在我的系統上 /usr/include/netinet/iphdr 這是結構 iphdr 的樣子
struct iphdr
{
#if __BYTE_ORDER == __LITTLE_ENDIAN
unsigned int ihl:4;
unsigned int version:4;
#elif __BYTE_ORDER == __BIG_ENDIAN
unsigned int version:4;
unsigned int ihl:4;
#else
# error "Please fix <bits/endian.h>"
#endif
uint8_t tos;
uint16_t tot_len;
uint16_t id;
uint16_t frag_off;
uint8_t ttl;
uint8_t protocol;
uint16_t check;
uint32_t saddr;
uint32_t daddr;
/*The options start here. */
};
假設我已經制作了所有帶有值的 ip 頭欄位。現在我想計算 ip 頭長度,它是我系統上的 iphdr->ihl 欄位。我假設這是 ip 頭的長度,所以我制作的 ip 頭的長度不可能是那個長度sizeof(struct iphdr)。
還有這個struct tcphdr樣子
struct tcphdr
{
__extension__ union
{
struct
{
uint16_t th_sport; /* source port */
uint16_t th_dport; /* destination port */
tcp_seq th_seq; /* sequence number */
tcp_seq th_ack; /* acknowledgement number */
# if __BYTE_ORDER == __LITTLE_ENDIAN
uint8_t th_x2:4; /* (unused) */
uint8_t th_off:4; /* data offset */
# endif
# if __BYTE_ORDER == __BIG_ENDIAN
uint8_t th_off:4; /* data offset */
uint8_t th_x2:4; /* (unused) */
# endif
uint8_t th_flags;
# define TH_FIN 0x01
# define TH_SYN 0x02
# define TH_RST 0x04
# define TH_PUSH 0x08
# define TH_ACK 0x10
# define TH_URG 0x20
uint16_t th_win; /* window */
uint16_t th_sum; /* checksum */
uint16_t th_urp; /* urgent pointer */
};
struct
{
uint16_t source;
uint16_t dest;
uint32_t seq;
uint32_t ack_seq;
# if __BYTE_ORDER == __LITTLE_ENDIAN
uint16_t res1:4;
uint16_t doff:4;
uint16_t fin:1;
uint16_t syn:1;
uint16_t rst:1;
uint16_t psh:1;
uint16_t ack:1;
uint16_t urg:1;
uint16_t res2:2;
# elif __BYTE_ORDER == __BIG_ENDIAN
uint16_t doff:4;
uint16_t res1:4;
uint16_t res2:2;
uint16_t urg:1;
uint16_t ack:1;
uint16_t psh:1;
uint16_t rst:1;
uint16_t syn:1;
uint16_t fin:1;
# else
# error "Adjust your <bits/endian.h> defines"
# endif
uint16_t window;
uint16_t check;
uint16_t urg_ptr;
};
};
};
所以再次假設我已經用值填充了 tcphdr 的所有欄位,現在我想要doff(資料偏移)。如何計算
struct iphdr *iph=buffer;
// populate the fields of iph
//but what is iph->ihl? to calculate how?
int iphdrlen = iph->ihl*4;
struct tcphdr *tcph=(struct tcphdr *)(buffer iphdrlen);
//populate all the fields of tcph
//but also how to calculate tcph->doff
應該像 iphdr->ihl
//after populating all the fields of iph then just do following to get iph->ihl
iph->ihl=sizeof(iph);
它應該像 tcph->doff
//after populating all the fields of tcph just do following
tcph->doff = (unsigned int)(sizeof(iph)) sizeof(tcph)));
這會起作用,所以會嗎?
uj5u.com熱心網友回復:
IP 報頭有兩個“部分”——一個強制固定大小的部分,由 表示,struct iphdr后者由可選的選項表示(參見注釋/*The options start here. */)。標頭長度是帶有選項的整個標頭長度。因此,除非您實際添加了一些選項,否則它只是標題的長度,您可以在標準中計算或讀取:
國際人道法:4 位
Internet Header Length 是 Internet 報頭的長度,以 32 位字表示,因此指向資料的開頭。請注意, 正確標頭的最小值為 5。
現在,一個位元組是 4 位,而 32 位是 4 個字。因此它是sizeof(struct iphdr)/4或者你可以將它設定為5.
TCP 資料偏移量基本相同,只是針對 TCP。由于 TCP 標頭也可以包含選項,因此適用相同的邏輯。根據標準(滾動到下一頁):
資料偏移:4位
TCP 標頭中 32 位字的數量。這表明資料從哪里開始。TCP 標頭(甚至包括選項)是 32 位長的整數。
所以,基本上它是用同樣的方式計算的。它不是一個指標,它是一個指示標題長度的數字。根據維基百科,如果您的標題沒有選項,則該欄位的值也是5.
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/390033.html
