繁体   English   中英

Linux原始套接字-IP头中的字节序

[英]Linux raw socket - endianness in ip header

我想确认的是,ip头中大于一个字节的任何值(short,int。或它们的替代int16_t ..)都应使用ntohs / ntohl等格式转换为big endian,以通过网络发送。

使用普通套接字或使用其他技术时,内核是否在后台进行了管理?

由于某些功能(例如,使用ioctl获取接口的ip地址)在转换为sockaddr_in *时似乎已经以大端序的方式放置了数据,这真是一团糟。 它输出我的地址,例如36.2.168.192(带有printf的%d),但是ifreq输出它的地址,例如192.168.2.36

int addr = ((struct sockaddr_in *)(&ifr.ifr_addr))->sin_addr.s_addr;
printf("%d %d %d %d ", (addr >> 24) & 255 , (addr >> 16) & 255,(addr >> 8) & 255, (addr) & 255);

以相反的顺序给我我的IP地址

而使用

for (int _x = 0; x < 14; ++_x) {
        printf("%d ", ifr.ifr_ifru.ifru_addr.sa_data[_x] );
}

会以正确的顺序(192.168.2.36)给我一些零的IP地址,然后是零。 哇...我迷路了。

如果你问我,那是一个丛林。

什么可以转换成大端,什么不可以?

最好不要将其视为大端或小端,而是主机顺序(可以是任意顺序)和网络顺序(大端)。 您是正确的,在IP标准中,每个字段都是按网络顺序排列的。 您应该使用ntohsntohl函数将网络转换为主机顺序,并使用htonshtonl函数将主机转换为网络顺序。 这样,您的代码也可以直接在big-endian机器上编译。

IP地址通常以网络顺序在内部存储,在这种情况下,可以使用inet_ptoninet_ntop将其转换为表示格式。 因此,除非您手动应用网络掩码等,否则通常不需要使用这些地址的存储格式。如果执行此操作,则八位字节(您和我的字节)以自然顺序存储,即111.222。 33.44以111、222、33和44的顺序存储。如果考虑一下,那是一个大端顺序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM