【问题标题】:Casting with raw packet data and inet_ntoa()使用原始数据包数据和 inet_ntoa() 进行投射
【发布时间】:2012-02-20 04:48:12
【问题描述】:

尝试为数据包嗅探器编写处理程序。我在选角和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);这一行

【问题讨论】:

  • 您的示例调用尝试打印test;你的意思是打印test2 吗?
  • 为什么要使用malloc 来获取单个uint32_t 而不是仅仅使用局部变量?

标签: c pointers casting pcap


【解决方案1】:

警告可能表明您在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");
}

【讨论】:

  • 这为我指明了正确的方向,极大地帮助了我。谢谢。
猜你喜欢
  • 1970-01-01
  • 2016-08-27
  • 2017-12-02
  • 1970-01-01
  • 1970-01-01
  • 2022-08-24
  • 2017-12-15
  • 2021-06-05
  • 1970-01-01
相关资源
最近更新 更多