srcport:01BB, dstport:CA0D udp_len:00A8,udp_chsum:8296 srcport:BB01, dstport:0DCA udp_len:A800,udp_chsum:9682
时间: 2024-01-07 20:03:10 浏览: 125
根据给出的信息,可以得到以下结论:
- 第一个报文的源端口号是0x01BB(443),目的端口号是0xCA0D(51725),长度为0x00A8(168),检验和为0x8296。
- 第二个报文的源端口号是0xBB01(47841),目的端口号是0x0DCA(3530),长度为0xA800(43264),检验和为0x9682。
需要注意的是,端口号在网络中采用大端字节序,因此需要将字节序进行转换才能得到正确的数值。因此,第一个报文的源端口号实际为443,目的端口号为51725,第二个报文的源端口号为47841,目的端口号为3530。
相关问题
怎么改if (frame[12] == 0x08 && frame[13] == 0x00) { byte *ip_header = frame + 14; if (ip_header[9] == 0x11){ is_udp = true; } }结果srcport:01BB, dstport:CA0D udp_len:00A8,udp_chsum:8296 变srcport:BB01, dstport:0DCA udp_len:A800,udp_chsum:9682
这里面涉及到了字节序的问题。在网络传输中,数据是以字节流的形式传输的,但是不同的计算机或操作系统在存储这些数据时采用的字节序可能不同,导致同样的数据在传输过程中出现了字节序的变化。
在这个问题中,你需要将srcport和dstport的字节序从大端序(即高位字节在前,低位字节在后)转换为小端序(即低位字节在前,高位字节在后),同时将udp_len和udp_chsum的字节序也进行转换。
可以使用下面的代码来完成字节序转换:
```c++
uint16_t swap16(uint16_t val){
return (val << 8) | (val >> 8);
}
uint32_t swap32(uint32_t val){
return ((val << 24) & 0xff000000) |
((val << 8) & 0x00ff0000) |
((val >> 8) & 0x0000ff00) |
((val >> 24) & 0x000000ff);
}
if (frame[12] == 0x08 && frame[13] == 0x00) {
byte *ip_header = frame + 14;
if (ip_header[9] == 0x11){
is_udp = true;
uint16_t srcport = *(uint16_t *)(ip_header + 20);
uint16_t dstport = *(uint16_t *)(ip_header + 22);
uint16_t udp_len = *(uint16_t *)(ip_header + 38);
uint16_t udp_chsum = *(uint16_t *)(ip_header + 40);
srcport = swap16(srcport);
dstport = swap16(dstport);
udp_len = swap16(udp_len);
udp_chsum = swap16(udp_chsum);
printf("srcport:%04X, dstport:%04X udp_len:%04X, udp_chsum:%04X\n",
srcport, dstport, udp_len, udp_chsum);
}
}
```
注意,这里使用了指针类型转换来获取端口号和校验和,这种做法需要注意指针对齐的问题,否则可能会导致程序出错。同时,在进行字节序转换时,需要保证数据的类型正确,否则也会导致程序出错。
#include"../network_protocol.h" /*从帧中获取UDP报源端口*/ uint16 get_srcport(byte *frame) { uint16 srcport = 0; /***************** Begin 1 *****************/ srcport = (frame[34] << 8) | frame[35]; /***************** End 1 *******************/ return srcport; }/*从帧中获取UDP报目的端口*/ uint16 get_dstport(byte *frame) { uint16 dstport = 0; /***************** Begin 2 *****************/ dstport = (frame[36] << 8) | frame[37]; /***************** End 2 *******************/return dstport; } /*从帧中获取UDP报长度*/ uint16 get_udp_len(byte *frame) { uint16 udp_len = 0; /***************** Begin 3 *****************/ udp_len = (frame[38] << 8) | frame[39]; /***************** End 3 *******************/ return udp_len; }/*从帧中获取UDP报检验码*/ uint16 get_udp_cksum(byte *frame) { uint16 udp_cksum = 0; /***************** Begin 4 *****************/ udp_cksum = (frame[40] << 8) | frame[41]; /***************** End 4 *******************/ return udp_cksum; }/*判断帧中携带的是否是UDP报文*/ bool is_udp_frame(byte *frame) { bool is_udp=false; /***************** Begin 5 *****************/ /***************** End 5 *******************/ return is_udp; }
好的,这段代码中已经包含了获取UDP报文各个字段的函数。现在需要补全 `is_udp_frame` 函数的代码,以判断帧中携带的是否是UDP报文。补充缺少的代码如下:
```
/*判断帧中携带的是否是UDP报文*/
bool is_udp_frame(byte *frame) {
bool is_udp=false;
uint8 protocol = get_protocol(frame);
/***************** Begin 5 *****************/
if (protocol == 0x11) {
uint16 udp_len = get_udp_len(frame);
if (udp_len >= 8) {
is_udp = true;
}
}
/***************** End 5 *******************/
return is_udp;
}
```
这样,我们就可以在使用这些函数之前先调用 `is_udp_frame` 函数来判断是否是UDP报文了。
阅读全文