- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我对何时使用 ntohs 和 ntohl 感到很困惑。我知道何时将 ntohs 用于 uint16_t 和 ntohl uint32_t。但是那些具有 unsigned int 或指定了特定位数的那些(例如 u_int16_t doff:4;)呢?
这是我用来演示问题的工作代码:
// Utility/Debugging method for dumping raw packet data
void dump(const unsigned char *data, int length) {
unsigned int i;
static unsigned long pcount = 0;
// Decode Packet Header
struct ether_header *eth_header = (struct ether_header *) data;
printf("\n\n === PACKET %ld HEADER ===\n", pcount);
printf("\nSource MAC: ");
for (i = 0; i < 6; ++i) {
printf("%02x", eth_header->ether_shost[i]);
if (i < 5) {
printf(":");
}
}
printf("\nDestination MAC: ");
unsigned short ethernet_type = ntohs(eth_header->ether_type);
printf("\nType: %hu\n", ethernet_type); //Why not nthos?
if (ethernet_type == ETHERTYPE_IP) { //IP Header
printf("\n == IP HEADER ==\n");
struct ip *ip_hdr = (struct ip*) (data + sizeof(struct ether_header));
unsigned int size_ip = ip_hdr->ip_hl * 4; //why no nthos or nthol
printf("\nip_hdr->ip_hl: %u", ip_hdr->ip_hl); //why no nthos or nthol
printf("\nIP Version: %u", ip_hdr->ip_v); //why no nthos or nthol
printf("\nHeader Length: %u", ip_hdr->ip_hl); //why no nthos or nthol
printf("\nTotal Length: %hu", ntohs(ip_hdr->ip_len)); //?is this right?
// TCP Header
printf("\n== TCP HEADER ==\n");
struct tcphdr *tcp_hdr = (struct tcphdr*) (data + sizeof(struct ether_header) + size_ip);
unsigned int size_tcp = tcp_hdr->doff * 4; //why no nthos or nthol
printf("\n Source Port: %" PRIu16, ntohs(tcp_hdr->th_sport));
printf("\n Destination Port: %" PRIu16, ntohs(tcp_hdr->th_dport));
printf("\n fin: %" PRIu16, tcp_hdr->fin ); //As this is 1 bit, both nthos or nthol will work
printf("\n urg: %" PRIu16, tcp_hdr->urg ); //As this is 1 bit, both nthos or nthol will work
printf("\n ack_seq: %" PRIu32, ntohl(tcp_hdr->ack_seq));
u_int16_t sourcePort = ntohs(tcp_hdr->th_sport);
u_int16_t destinationPort = ntohs(tcp_hdr->th_sport);
if (sourcePort == 80 || destinationPort == 80){
printf("\n\nPORT 80!!!\n");
//Transport payload!
printf("\n\ === TCP PAYLOAD DATA == \n");
// Decode Packet Data (Skipping over the header)
unsigned int headers_size = ETH_HLEN + size_ip + size_tcp;
unsigned int data_bytes = length - headers_size;
const unsigned char *payload = data + headers_size;
const static int output_sz = 500; // Output this many bytes at a time
while (data_bytes > 0) {
int output_bytes = data_bytes < output_sz ? data_bytes : output_sz;
// Print data in raw hexadecimal form
printf("| ");
// Print data in ascii form
for (i = 0; i < output_bytes; ++i) {
char byte = payload[i];
if ( (byte > 31 && byte < 127) || byte == '\n') {
// Byte is in printable ascii range
printf("%c", byte); //why no nthos or nthol
} else {
printf(".");
}
}
payload += output_bytes;
data_bytes -= output_bytes;
}
}
}
pcount++;
}
如您所见,有时我使用 ntohs/ntohl,有时两者都不用。我不明白什么时候使用哪个。
最佳答案
But what about those with unsigned int
原则上,如前所述,C 不保证 unsigned int
的大小。 ;有平台可以int
和 unsigned int
是 16 位的,例如 PDP-11,以及带有一些编译器的摩托罗拉 68k 处理器(其他编译器使它们成为 32 位),并且对于某些 16 位微处理器来说,情况可能仍然如此。
因此,如果您通过网络发送数据,最好使用 <stdint.h>
中定义的类型如果可以的话。
实际上,您使用的机器几乎肯定有一个 32 位 unsigned int
, although some Cray machines have 64-bit int
and even short
!但最好还是使用 <stdint.h>
中定义的类型.
or those where a specific amount of bits is specified (e.g. u_int16_t doff:4;).
如果一个值比一个字节短,如 4 位字段的情况,则字节顺序无关紧要。
但是,请注意位字段在 1、2 或 4 字节序列中的顺序也不是由 C 指定的, 所以你不应该在通过网络发送的数据中使用位域。 (是的,一些 UN*Xes 碰巧在 IPv4 和 TCP header 的结构中使用它们,但这只有在供应商用于他们支持的体系结构的编译器都以相同的顺序放置位域的情况下才有效,并且如果第三方GCC 等编译器做同样的事情。)
所以处理 IPv4 header 的正确方法是做一些事情,比如
struct ip {
uint8_t ip_vhl; /* header length, version */
#define IP_V(ip) (((ip)->ip_vhl & 0xf0) >> 4)
#define IP_HL(ip) ((ip)->ip_vhl & 0x0f)
uint8_t ip_tos; /* type of service */
uint16_t ip_len; /* total length */
uint16_t ip_id; /* identification */
uint16_t ip_off; /* fragment offset field */
#define IP_DF 0x4000 /* dont fragment flag */
#define IP_MF 0x2000 /* more fragments flag */
#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
uint8_t ip_ttl; /* time to live */
uint8_t ip_p; /* protocol */
uint16_t ip_sum; /* checksum */
struct in_addr ip_src,ip_dst; /* source and dest address */
};
使用那个结构来声明你的ip_hdr
指向 IP header 的指针,以及:
IP_V(ip_hdr)
;IP_HL(ip_hdr)
.如果您的供应商的 ip.h
header 使用位域,不要使用供应商的 ip.h
header ;使用你自己的标题。事实上,即使您的供应商的 ip.h
header 不使用位域,不要使用供应商的ip.h
header ;使用你自己的标题。毕竟,IP header 的定义并不依赖于操作系统......
(这就是 tcpdump 现在为几个版本所做的;以上内容摘自它的 ip.h
。)
关于c - 什么时候在 C 语言中使用 ntohs 和 ntohl?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27299634/
int main() { uint8_t var = 9; var = ntohs(var); printf("var=%u",var) } 这段代码在 Little End
这个程序应该从离线转储文件中捕获一个数据包并对其进行解码。在这里我遇到了 ntohs() 函数的问题(它接近尾声,标题描述在开头)。为什么它不起作用?操作系统 win7 x86,VS 2010 exp
我有一个.cpp 文件:htonstest.cpp。我使用 g++ 编译它: $ g++ -o test htonstest.cpp 它有效,程序 ./test 也有效。 但是,当我使用 automa
我有一个程序一直依赖于 native::io::net::{htons, ntohs} 但现在在 Could not find 'io' in 'packet: :native'。变化似乎发生在上周的
我正在从 DNS 服务器获取一些数据,我正在尝试将某个部分转换为无符号整数(代表刷新间隔、到期时间等)。通过转换,我的意思是从大端到小端。问题是 ntohs 只放置了 2 个字节的数据而不是 4 个字
当我从 stringstream 读取数据时,我有一个关于如何使用 ntohs() 的问题。 对于下面的代码: read(ns, buf_receive, BUFFER_SIZE); stringst
我正在编写一个 ELF 分析器,但我在正确转换字节顺序时遇到了一些问题。我具有确定分析器的字节序和目标文件的字节序的函数。 基本上,有四种可能的情况: 在大端目标文件上运行的大端编译分析器 无需转换
我从一个答案中阅读了文档: ntohs 函数采用 TCP/IP 网络字节顺序(AF_INET 或 AF_INET6 地址族)的 16 位数字,并以主机字节顺序返回一个 16 位数字。 请举例说明,什么
要从另一台大端机器转换字节数组,我们可以使用: long long convert(unsigned char data[]) { long long res; res = 0; for(
我们正在将 C 语言的遗留代码重写为 C++。在我们系统的核心,我们有一个连接到 master 的 TCP 客户端。主人将不断地流式传输消息。每个套接字读取都会产生 N 条格式为 {type, siz
C# 中是否有网络到主机的转换函数?谷歌搜索并没有找到太多。 :P 最佳答案 IPAddress.HostToNetworkOrder和 IPAddress.NetworkToHostOrder ?
为什么Coverity会产生警告 > "cc" clobber ignored 对于下面提到的代码中的函数调用 htons() 和 ntohs()? lSocketAddr.sin_port = ht
我需要在可能位于不同平台的服务器和客户端之间发送一个枚举缓冲区。 但是枚举的大小取决于平台,我应该调用哪个函数? (htons() 或 htonl()),例如以下枚举: typedef enum f_
我不确定为什么 htons 和 ntohs 都存在于标准库中。他们做的事情完全一样——除非我有点困惑! htonl 和 ntohl 也是如此。 最佳答案 它们提供自文档化代码,告诉读者数据是按主机顺序
我正在使用现有代码,它通过 TCP 连接传递数据 - union ibv_gid 而不转换字节顺序。里面有注释:“gid会逐字节传输,所以不需要做”hton“。代码是正确的,可以工作,但我不明白为什么
我正在为一个不是 hton 数据的协议(protocol)编写一个 Wireshark 解析器插件,我需要在不进行任何字节序转换的情况下提取 64 位数据值。 Wireshark 库中是否有不执行 n
我正在尝试将整数值写入/从 C 套接字读取。有时 ntohs() 会返回非常大的值,例如 55000 、 32000 等...尽管客户端始终发送值 1500 ) { **printf
我对何时使用 ntohs 和 ntohl 感到很困惑。我知道何时将 ntohs 用于 uint16_t 和 ntohl uint32_t。但是那些具有 unsigned int 或指定了特定位数的那些
我是 C 网络编程的新手,我首先尝试将从键盘读取的数组发送到服务器。问题是,每当我从键盘读取数组的长度时,它都会增加 2/3,并且不再做任何正确的事情。例如: 我给出的长度或数组:2客户端将从键盘读取
这是一个 SSCCE ,显示了我的代码的简化版本,它仍然做了一些有用的事情: //Compile with -O3 -Wsign-conversion #include #include void
我是一名优秀的程序员,十分优秀!