busybox: refresh patches
[openwrt.git] / package / busybox / patches / 244-udhcpc_add_6rd_option.patch
1 --- a/networking/udhcp/common.c
2 +++ b/networking/udhcp/common.c
3 @@ -60,6 +60,8 @@ const struct dhcp_optflag dhcp_optflags[
4         { OPTION_U8                               , 0x85 }, /* DHCP_VLAN_PRIORITY */
5  #endif
6         { OPTION_STATIC_ROUTES                    , 0xf9 }, /* DHCP_MS_STATIC_ROUTES */
7 +       { OPTION_6RD                              , 0xd4 }, /* DHCP_6RD (RFC)     */
8 +       { OPTION_6RD                              , 0x96 }, /* DHCP_6RD (Comcast) */
9         { OPTION_STRING                           , 0xfc }, /* DHCP_WPAD          */
10  
11         /* Options below have no match in dhcp_option_strings[],
12 @@ -127,6 +129,8 @@ const char dhcp_option_strings[] ALIGN1 
13         "vlanpriority" "\0"/* DHCP_VLAN_PRIORITY  */
14  #endif
15         "msstaticroutes""\0"/* DHCP_MS_STATIC_ROUTES */
16 +       "ip6rd" "\0"       /* DHCP_6RD (RFC)      */
17 +       "ip6rd" "\0"       /* DHCP_6RD (Comcast)  */
18         "wpad" "\0"        /* DHCP_WPAD           */
19         ;
20  
21 @@ -155,6 +159,7 @@ const uint8_t dhcp_option_lengths[] ALIG
22         [OPTION_S32] =     4,
23         /* Just like OPTION_STRING, we use minimum length here */
24         [OPTION_STATIC_ROUTES] = 5,
25 +       [OPTION_6RD]           = 22,
26  };
27  
28  
29 --- a/networking/udhcp/common.h
30 +++ b/networking/udhcp/common.h
31 @@ -91,6 +91,7 @@ enum {
32         OPTION_S32,
33         OPTION_BIN,
34         OPTION_STATIC_ROUTES,
35 +       OPTION_6RD,
36  #if ENABLE_FEATURE_UDHCP_RFC3397
37         OPTION_DNS_STRING,  /* RFC1035 compressed domain name list */
38         OPTION_SIP_SERVERS,
39 --- a/networking/udhcp/dhcpc.c
40 +++ b/networking/udhcp/dhcpc.c
41 @@ -100,6 +100,7 @@ static const uint8_t len_of_option_as_st
42         [OPTION_IP              ] = sizeof("255.255.255.255 "),
43         [OPTION_IP_PAIR         ] = sizeof("255.255.255.255 ") * 2,
44         [OPTION_STATIC_ROUTES   ] = sizeof("255.255.255.255/32 255.255.255.255 "),
45 +       [OPTION_6RD             ] = sizeof("32 128 FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF 255.255.255.255 "),
46         [OPTION_STRING          ] = 1,
47         [OPTION_STRING_HOST     ] = 1,
48  #if ENABLE_FEATURE_UDHCP_RFC3397
49 @@ -124,6 +125,23 @@ static int sprint_nip(char *dest, const 
50         return sprintf(dest, "%s%u.%u.%u.%u", pre, ip[0], ip[1], ip[2], ip[3]);
51  }
52  
53 +static int sprint_nip6(char *dest, const char *pre, const uint8_t *ip)
54 +{
55 +       int len = 0;
56 +       int off;
57 +       uint16_t word;
58 +
59 +       len += sprintf(dest, "%s", pre);
60 +
61 +       for (off = 0; off < 16; off += 2)
62 +       {
63 +               move_from_unaligned16(word, &ip[off]);
64 +               len += sprintf(dest+len, "%s%04X", off ? ":" : "", htons(word));
65 +       }
66 +
67 +       return len;
68 +}
69 +
70  /* really simple implementation, just count the bits */
71  static int mton(uint32_t mask)
72  {
73 @@ -293,6 +311,70 @@ static NOINLINE char *xmalloc_optname_op
74  
75                         return ret;
76                 }
77 +               case OPTION_6RD: {
78 +                       /* Option binary format:
79 +                        *  0                   1                   2                   3
80 +                        *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
81 +                        *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
82 +                        *  |  OPTION_6RD   | option-length |  IPv4MaskLen  |  6rdPrefixLen |
83 +                        *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
84 +                        *  |                                                               |
85 +                        *  |                           6rdPrefix                           |
86 +                        *  |                          (16 octets)                          |
87 +                        *  |                                                               |
88 +                        *  |                                                               |
89 +                        *  |                                                               |
90 +                        *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
91 +                        *  |                     6rdBRIPv4Address(es)                      |
92 +                        *  .                                                               .
93 +                        *  .                                                               .
94 +                        *  .                                                               .
95 +                        *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
96 +                        *
97 +                        * We convert it to a string "IPv4MaskLen 6rdPrefixLen 6rdPrefix 6rdBRIPv4Address"
98 +                        */
99 +
100 +                       /* Sanity check: ensure that our length is at least 22 bytes, that
101 +                        * IPv4MaskLen is <= 32, 6rdPrefixLen <= 128 and that the sum of
102 +                        * (32 - IPv4MaskLen) + 6rdPrefixLen is less than or equal to 128.
103 +                        * If any of these requirements is not fulfilled, return with empty
104 +                        * value.
105 +                        */
106 +                       if ((len >= 22) && (*option <= 32) && (*(option+1) <= 128) &&
107 +                           (((32 - *option) + *(option+1)) <= 128))
108 +                       {
109 +                               /* IPv4MaskLen */
110 +                               dest += sprintf(dest, "%u ", *option++);
111 +                               len--;
112 +
113 +                               /* 6rdPrefixLen */
114 +                               dest += sprintf(dest, "%u ", *option++);
115 +                               len--;
116 +
117 +                               /* 6rdPrefix */
118 +                               dest += sprint_nip6(dest, "", option);
119 +                               option += 16;
120 +                               len -= 16;
121 +
122 +                               /* 6rdBRIPv4Addresses */
123 +                               while (len >= 4)
124 +                               {
125 +                                       dest += sprint_nip(dest, " ", option);
126 +                                       option += 4;
127 +                                       len -= 4;
128 +
129 +                                       /* the code to determine the option size fails to work with
130 +                                        * lengths that are not a multiple of the minimum length,
131 +                                        * adding all advertised 6rdBRIPv4Addresses here would
132 +                                        * overflow the destination buffer, therefore skip the rest
133 +                                        * for now
134 +                                        */
135 +                                       break;
136 +                               }
137 +                       }
138 +
139 +                       return ret;
140 +               }
141  #if ENABLE_FEATURE_UDHCP_RFC3397
142                 case OPTION_DNS_STRING:
143                         /* unpack option into dest; use ret for prefix (i.e., "optname=") */