kernelpassion 0 Newbie Poster

Below is the ip_options_build() in linux kernel 3.4, line 51 and 52:

51        if (opt->srr)
52                memcpy(iph+opt->srr+iph[opt->srr+1]-4, &daddr, 4);

I understand that the two lines say, if source routing option is present, copy the destination address to the end of the option, that suggests that iph[opt->srr+1] is the length of the source routing option, but I don't get it why? Thanks!

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}