244-udhcpc_add_6rd_option.patch 5.1 KB

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