Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么我收到的IP地址是反向的?给定-12.0.0.100,在C中作为100.0.0.12接收_C_Ip_Ip Address_Endianness_Radius - Fatal编程技术网

为什么我收到的IP地址是反向的?给定-12.0.0.100,在C中作为100.0.0.12接收

为什么我收到的IP地址是反向的?给定-12.0.0.100,在C中作为100.0.0.12接收,c,ip,ip-address,endianness,radius,C,Ip,Ip Address,Endianness,Radius,我正在测试RADIUS-DISCONNECT选项 服务器发送断开连接请求以断开Cmd:cat packet.txt | radclient-c 10-i 40-x 12.0.0.1:3799断开连接机密 我的RAIDUS服务器配置为12.0.0.100。RADIUS客户端IP配置为12.0.0.1 从服务器发送使用数据包捕获命令捕获的数据包。数据包捕获将源IP表示为:source:12.0.0.100 12.0.0.100 但在接收时,当打印我的服务器IP时,它是100.0.0.12,因此,我无

我正在测试RADIUS-DISCONNECT选项

服务器发送断开连接请求以断开Cmd:cat packet.txt | radclient-c 10-i 40-x 12.0.0.1:3799断开连接机密

我的RAIDUS服务器配置为12.0.0.100。RADIUS客户端IP配置为12.0.0.1

从服务器发送使用数据包捕获命令捕获的数据包。数据包捕获将源IP表示为:source:12.0.0.100 12.0.0.100

但在接收时,当打印我的服务器IP时,它是100.0.0.12,因此,我无法跟踪或验证服务器详细信息。我不知道这是否是由于小端,大端的问题

GDB在服务器IP上打印:{0xc,0x0,0x0,0x64,0x0},但它实际上必须是{0x64,0x0,0x0,0xc,0x0}

如果是由于小端或大端问题,有人能告诉我如何解决这个问题吗


请有人帮忙。

在绝大多数协议中,IP地址的有线格式是big-endian,而您似乎希望IP地址是little-endian格式

提供宏htonl host-to-network long和ntohl-network-to-host long,以将endianness从big-endian转换为主机使用的任何大、小或混合

uint8_t  *packet;
uint32_t ip_net;
uint32_t ip_host;

memcpy(&ip_net, packet, sizeof(ip_net));  /* Assuming packet is a buffer of at least 4 bytes */
ip_host = ntohl(ip_net);
您可能会在其他指向数据包缓冲区的指针代码中看到实例被转换为uint32_t,并被传递到字节顺序转换函数中。这可能适用于某些x86体系结构,但可能会导致对其他Sparc体系结构的未对齐内存访问

通常最好的做法是将memcpy从正在处理的缓冲区映射到中间变量,因为memcpy将处理对齐问题,并且保证堆栈变量正确对齐


这些问题有一个快速的总结,可用的方法是

网络字节顺序是big-endian,x86是little-endian。根据要交换的字节数,您需要使用宏ntohl和htonl或ntohs和htons。至少从Solaris 10开始,Solaris就符合POSIX对in_addr__t as uint32_t的定义,并且在实践中,如果需要从缓冲区复制,它将成为32位字的时间更长,malloc返回的一个将起作用,因为该类型符合最严格的要求,或者您可以使用alignas声明缓冲区。如果IP地址位于缓冲区的开头,则可以。如果使用libpcap或原始套接字读取数据包,则很可能在缓冲区中有以太网报头,这意味着即使缓冲区的起始位置为,ip地址字段也可能未对齐。如果将缓冲区的地址提供给复制操作,则它将复制到缓冲区的起始位置。实际上,如果您知道要存储IPv4地址,您会将缓冲区设置为In_addr_t,,或者如果您正在接收某种任意类型的连接,例如通过多个网络协议侦听连接,您需要为sockaddr_存储分配空间,并使用套接字库来填充它。AFAIK没有办法让libpcap或原始套接字API从传入数据包中的特定偏移量开始复制到缓冲区,因此,libpcap>应用程序缓冲区需要至少为sizeofl2 header+sizeofin_addr|t|sizeofsockaddr|u存储区。原始协议头和套接字地址将有不同的缓冲区,网络上的数据缓冲区可能是与数据包或头相对应的结构。如果需要在缓冲区中表示多个类型,那么它将是一个联合。此时,您仍然需要复制和重新格式化数据。该标准不能保证结构的字段之间没有填充,因此如果您想要完全可移植的代码,您确实需要memcpy。不过,对于实际存在的CPU来说,自然对齐就足够了。