Root/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@@ -154,6 +158,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@@ -88,6 +88,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 #if ENABLE_FEATURE_UDHCP_RFC3397
48     [OPTION_DNS_STRING ] = 1, /* unused */
49@@ -123,6 +124,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@@ -232,6 +250,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=") */
144

Archive Download this file



interactive