2012-02-20 56 views
3

试图为数据包嗅探器编写处理程序。我在铸造和inet_ntoa()方面存在问题。代码如下:使用原始数据包数据和inet_ntoa()

uint32_t *iphdr_srcaddr = malloc(sizeof(uint32_t)); 
if (*packet_ethertype == ETHERTYPE_IP) { /* IPv4 */ 
    // copy packet data to vars 
    memcpy(iphdr_srcaddr, packet+26, 4); 

    // change to host-byte-order 
    *iphdr_srcaddr = ntohl(*iphdr_srcaddr); 

    struct in_addr *test; 
    test = (struct in_addr*) iphdr_srcaddr; 

    printf("uint32_t: %u\n", *iphdr_srcaddr); // Gives the correct long integer for the address 
    printf("struct in_addr: %u\n", test->s_addr); // Gives the correct long integer through the cast 

    char *test2; 
    test2 = inet_ntoa(*test); 
} 

现在,如果我尝试printf("%s\n", test)我得到SEGV。我确信我在混合指针,值和做某种愚蠢的投射。下面运行过程中收到的错误:

Program received signal SIGSEGV, Segmentation fault. 
0x00007ffff787ec61 in __strlen_sse2() from /lib/libc.so.6 

编译警告,以及,我敢肯定,这是我指点正确的方向,但我不知道这意味着什么,我怎么能解决这个问题:

mypcap.c: In function ‘handle_sniffed’: 
mypcap.c:61:15: warning: assignment makes pointer from integer without a cast [enabled by default] 

这指的是线路test2 = inet_ntoa(*test);

+0

你的样品呼叫尝试打印'test';你是不是打印'test2'? – reuben 2012-02-20 04:52:39

+1

为什么使用'malloc'获取单个'uint32_t'而不是仅仅使用局部变量? – 2012-02-20 05:10:14

回答

7

警告可能表明你没有在范围上正确的原型inet_ntoa()(因为您还没有正确的标头)。这意味着编译器假定它的返回类型为int

当您应该通过test2时,您还通过testprintf()

另外:

  • 没有必要使用malloc()分配一个uint32_t;
  • 您不需要拨打ntohl(),因为inet_ntoa()期望以网络字节顺序输入;和
  • inet_ntoa()已过期 - inet_ntop()应在新代码中使用。

尝试:

#include <arpa/inet.h> 

if (*packet_ethertype == ETHERTYPE_IP) { /* IPv4 */ 
    struct in_addr sin_addr; 
    char straddr[INET_ADDRSTRLEN]; 

    memcpy(&sin_addr.s_addr, packet+26, 4); 

    if (inet_ntop(AF_INET, &sin_addr, straddr, sizeof straddr)) 
     printf("%s\n", straddr); 
    else 
     perror("inet_ntop"); 
} 
+0

这指出我正确的方向,帮助巨大。谢谢。 – axon 2012-02-21 17:20:36