2016-11-05 5 views
1

私の教授は、手動でUDPリクエストを作成して送信するように教えてくれました。 私は..だから問題はsendto機能は、データ構造sockaddrを必要とし、私が持っているものすべてがターゲットのIPv4を示す文字列です..ですUDPヘッダとコンテンツポインタを構築するために、これまでにこの文字列を変換する方法任意のアイデアを手動で作成されたUDPデータグラムをCで送信しますか?

を行ってきましたその構造に、または別の送信メッセージがある場合は、

#include <errno.h> 
#include <unistd.h> 
#include <netdb.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <stdio.h> 
#include <stdarg.h> 
#include <stdlib.h> 
#include <string.h> 

static void die (const char * format, ...) 
{ 
    va_list vargs; 
    va_start (vargs, format); 
    vfprintf (stderr, format, vargs); 
    fprintf (stderr, ".\n"); 
    exit (1); 
} 
void copy_lower_16_int(void * dest,int value) 
{ 
    size_t sz =sizeof(value); 
    if(sz == 2) 
     memcpy(dest,&value,2); 
    else if (sz >2) 
    { 
     memcpy(dest,(&value)+sz-2,2); 
    } 
} 
int sendTo(void * message,size_t size ,char * destinationIP,unsigned short destinationPort) 
{ 


    // Get the target transport protocol number 
    const char* protocol_name="udp"; 
    struct protoent* protocol=getprotobyname(protocol_name); 
    if (!protocol) { 
     die("Protocol %s not found",protocol_name); 
    } 
    int protocol_number=protocol->p_proto; 

    printf(" Protocol %s has number of %d \n",protocol_name,protocol_number); 

    // Create raw socket for usage with IPv4 & the specified transport protocol (UDP) 
    int fd=socket(AF_INET,SOCK_RAW,protocol_number); 
    if (fd==-1) { 
     die("Failed to create a raw socket, error : %s",strerror(errno)); 
    } 

    // Construct the UDP datagram 

    //Calculate total size (message size + 8 byte for the headers) 
    size_t total_size = size + 8; 
    // Calculate the checksum 
    int checksum = 0x53AF; 

    void * content = (void*) malloc(total_size); 
    const int sourcePort = 1524; 


    copy_lower_16_int(content,sourcePort); 
    copy_lower_16_int(content+2,destinationPort); 
    copy_lower_16_int(content+4,total_size); 

    copy_lower_16_int(content+6,checksum); 


    memcpy(content+8,message,size); 

} 
void main(){ 
    printf("Size of int is %d",sizeof(2)); 
    sendTo("Cx",2,"127.0.0.1",5405); 
} 
+0

としてgetaddrinfoを使用して私の問題を解決し、私はわからないんだけど、私はあなたがDGRAM_RAWソケット、ないDGRAM_UDPを開くために必要があると思います。 (またはそのようなもの) –

+0

私は完全に生のソケットを持っています。 –

+1

通常、sockaddr_in構造体を作成し、そのアドレスをsendto()呼び出しで使用し、そのアドレスを(struct sockaddr *)...にキャストします。 sendto(sockfd、buf、len、flags、 (struct sockaddr *)&dest_addr、sizeof(dest_addr)); – TonyB

答えて

1

私は、次の

struct addrinfo *addr_result; 
struct addrinfo hints; 


memset(&hints, 0, sizeof(struct addrinfo)); 
hints.ai_family = AF_INET; /* Allow IPv4 or IPv6 */ 
hints.ai_socktype = SOCK_RAW; /* Datagram socket */ 
hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */ 
hints.ai_protocol = protocol_number;   /* Any protocol */ 
hints.ai_canonname = NULL; 
hints.ai_addr = NULL; 
hints.ai_next = NULL; 
getaddrinfo(destinationIP,NULL,&hints,&addr_result); 

//Send the damn message 
ssize_t sentsz = sendto(fd,content,total_size,0,addr_result->ai_addr,addr_result->ai_addrlen); 
if (sentsz == -1) 
{ 
     printf("It failed to send !!"); 
} 
else { 
     printf("It did send %d bytes",sentsz); 
} 
// free allocated memory 

free(content); 
freeaddrinfo(addr_result); 
関連する問題