Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/29.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
linux内核ip_options_build()函数_Linux_Tcp_Linux Kernel_Linux Device Driver_Tcp Ip - Fatal编程技术网

linux内核ip_options_build()函数

linux内核ip_options_build()函数,linux,tcp,linux-kernel,linux-device-driver,tcp-ip,Linux,Tcp,Linux Kernel,Linux Device Driver,Tcp Ip,下面是linux内核3.4第51行和第52行中的ip_options_build() 51 if (opt->srr) 52 memcpy(iph+opt->srr+iph[opt->srr+1]-4, &daddr, 4); 我理解这两行的意思是,如果存在源路由选项,将目标地址复制到选项的末尾,这表明iph[opt->srr+1]是源路由选项的长度,但我不明白为什么 31/* 32 * Write options to I

下面是linux内核3.4第51行和第52行中的ip_options_build()

51        if (opt->srr)
52                memcpy(iph+opt->srr+iph[opt->srr+1]-4, &daddr, 4);
我理解这两行的意思是,如果存在源路由选项,将目标地址复制到选项的末尾,这表明iph[opt->srr+1]是源路由选项的长度,但我不明白为什么

31/*
32 * Write options to IP header, record destination address to
33 * source route option, address of outgoing interface
34 * (we should already know it, so that this  function is allowed be
35 * called only after routing decision) and timestamp,
36 * if we originate this datagram.
37 *
38 * daddr is real destination address, next hop is recorded in IP header.
39 * saddr is address of outgoing interface.
40 */
41
42void ip_options_build(struct sk_buff *skb, struct ip_options *opt,
43                      __be32 daddr, struct rtable *rt, int is_frag)
44{
45        unsigned char *iph = skb_network_header(skb);
46
47        memcpy(&(IPCB(skb)->opt), opt, sizeof(struct ip_options));
48        memcpy(iph+sizeof(struct iphdr), opt->__data, opt->optlen);
49        opt = &(IPCB(skb)->opt);
50
51        if (opt->srr)
52                memcpy(iph+opt->srr+iph[opt->srr+1]-4, &daddr, 4);
53
54        if (!is_frag) {
55                if (opt->rr_needaddr)
56                        ip_rt_get_source(iph+opt->rr+iph[opt->rr+2]-5, skb, rt);
57                if (opt->ts_needaddr)
58                        ip_rt_get_source(iph+opt->ts+iph[opt->ts+2]-9, skb, rt);
59                if (opt->ts_needtime) {
60                        struct timespec tv;
61                        __be32 midtime;
62                        getnstimeofday(&tv);
63                        midtime = htonl((tv.tv_sec % 86400) * MSEC_PER_SEC    
+           tv.tv_nsec / NSEC_PER_MSEC);
64                        memcpy(iph+opt->ts+iph[opt->ts+2]-5, &midtime, 4);
65                }
66                return;
67        }
68        if (opt->rr) {
69                memset(iph+opt->rr, IPOPT_NOP, iph[opt->rr+1]);
70                opt->rr = 0;
71                opt->rr_needaddr = 0;
72        }
73        if (opt->ts) {
74                memset(iph+opt->ts, IPOPT_NOP, iph[opt->ts+1]);
75                opt->ts = 0;
76                opt->ts_needaddr = opt->ts_needtime = 0;
77        }
78}

如果我没记错的话,iph+opt->srr基本上是srr选项的第一个字节的地址。选项本身的格式如下所示:

类型(1字节)|长度(1字节)|偏移量(1字节)|。。。然后一些地址每个4字节


长度“字段”指定整个选项的长度(以字节为单位),这就是为什么iph[opt->srr+1]是选项的长度。

如果我没记错的话,iph+opt->srr基本上是srr选项的第一个字节的地址。选项本身的格式如下所示:

类型(1字节)|长度(1字节)|偏移量(1字节)|。。。然后一些地址每个4字节

长度“字段”指定整个选项的长度(以字节为单位),因此iph[opt->srr+1]是选项的长度