print-ip6opts.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /*
  2. * Copyright (C) 1998 WIDE Project.
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 3. Neither the name of the project nor the names of its contributors
  14. * may be used to endorse or promote products derived from this software
  15. * without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  18. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20. * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
  21. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  23. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27. * SUCH DAMAGE.
  28. */
  29. /* \summary: IPv6 header option printer */
  30. #ifdef HAVE_CONFIG_H
  31. #include "config.h"
  32. #endif
  33. #include <netdissect-stdinc.h>
  34. #include "netdissect.h"
  35. #include "addrtoname.h"
  36. #include "extract.h"
  37. #include "ip6.h"
  38. static void
  39. ip6_sopt_print(netdissect_options *ndo, const u_char *bp, int len)
  40. {
  41. int i;
  42. int optlen;
  43. for (i = 0; i < len; i += optlen) {
  44. if (bp[i] == IP6OPT_PAD1)
  45. optlen = 1;
  46. else {
  47. if (i + 1 < len)
  48. optlen = bp[i + 1] + 2;
  49. else
  50. goto trunc;
  51. }
  52. if (i + optlen > len)
  53. goto trunc;
  54. switch (bp[i]) {
  55. case IP6OPT_PAD1:
  56. ND_PRINT((ndo, ", pad1"));
  57. break;
  58. case IP6OPT_PADN:
  59. if (len - i < IP6OPT_MINLEN) {
  60. ND_PRINT((ndo, ", padn: trunc"));
  61. goto trunc;
  62. }
  63. ND_PRINT((ndo, ", padn"));
  64. break;
  65. default:
  66. if (len - i < IP6OPT_MINLEN) {
  67. ND_PRINT((ndo, ", sopt_type %d: trunc)", bp[i]));
  68. goto trunc;
  69. }
  70. ND_PRINT((ndo, ", sopt_type 0x%02x: len=%d", bp[i], bp[i + 1]));
  71. break;
  72. }
  73. }
  74. return;
  75. trunc:
  76. ND_PRINT((ndo, "[trunc] "));
  77. }
  78. static void
  79. ip6_opt_print(netdissect_options *ndo, const u_char *bp, int len)
  80. {
  81. int i;
  82. int optlen = 0;
  83. if (len == 0)
  84. return;
  85. for (i = 0; i < len; i += optlen) {
  86. if (bp[i] == IP6OPT_PAD1)
  87. optlen = 1;
  88. else {
  89. if (i + 1 < len)
  90. optlen = bp[i + 1] + 2;
  91. else
  92. goto trunc;
  93. }
  94. if (i + optlen > len)
  95. goto trunc;
  96. switch (bp[i]) {
  97. case IP6OPT_PAD1:
  98. ND_PRINT((ndo, "(pad1)"));
  99. break;
  100. case IP6OPT_PADN:
  101. if (len - i < IP6OPT_MINLEN) {
  102. ND_PRINT((ndo, "(padn: trunc)"));
  103. goto trunc;
  104. }
  105. ND_PRINT((ndo, "(padn)"));
  106. break;
  107. case IP6OPT_ROUTER_ALERT:
  108. if (len - i < IP6OPT_RTALERT_LEN) {
  109. ND_PRINT((ndo, "(rtalert: trunc)"));
  110. goto trunc;
  111. }
  112. if (bp[i + 1] != IP6OPT_RTALERT_LEN - 2) {
  113. ND_PRINT((ndo, "(rtalert: invalid len %d)", bp[i + 1]));
  114. goto trunc;
  115. }
  116. ND_PRINT((ndo, "(rtalert: 0x%04x) ", EXTRACT_16BITS(&bp[i + 2])));
  117. break;
  118. case IP6OPT_JUMBO:
  119. if (len - i < IP6OPT_JUMBO_LEN) {
  120. ND_PRINT((ndo, "(jumbo: trunc)"));
  121. goto trunc;
  122. }
  123. if (bp[i + 1] != IP6OPT_JUMBO_LEN - 2) {
  124. ND_PRINT((ndo, "(jumbo: invalid len %d)", bp[i + 1]));
  125. goto trunc;
  126. }
  127. ND_PRINT((ndo, "(jumbo: %u) ", EXTRACT_32BITS(&bp[i + 2])));
  128. break;
  129. case IP6OPT_HOME_ADDRESS:
  130. if (len - i < IP6OPT_HOMEADDR_MINLEN) {
  131. ND_PRINT((ndo, "(homeaddr: trunc)"));
  132. goto trunc;
  133. }
  134. if (bp[i + 1] < IP6OPT_HOMEADDR_MINLEN - 2) {
  135. ND_PRINT((ndo, "(homeaddr: invalid len %d)", bp[i + 1]));
  136. goto trunc;
  137. }
  138. ND_PRINT((ndo, "(homeaddr: %s", ip6addr_string(ndo, &bp[i + 2])));
  139. if (bp[i + 1] > IP6OPT_HOMEADDR_MINLEN - 2) {
  140. ip6_sopt_print(ndo, &bp[i + IP6OPT_HOMEADDR_MINLEN],
  141. (optlen - IP6OPT_HOMEADDR_MINLEN));
  142. }
  143. ND_PRINT((ndo, ")"));
  144. break;
  145. default:
  146. if (len - i < IP6OPT_MINLEN) {
  147. ND_PRINT((ndo, "(type %d: trunc)", bp[i]));
  148. goto trunc;
  149. }
  150. ND_PRINT((ndo, "(opt_type 0x%02x: len=%d)", bp[i], bp[i + 1]));
  151. break;
  152. }
  153. }
  154. ND_PRINT((ndo, " "));
  155. return;
  156. trunc:
  157. ND_PRINT((ndo, "[trunc] "));
  158. }
  159. int
  160. hbhopt_print(netdissect_options *ndo, register const u_char *bp)
  161. {
  162. const struct ip6_hbh *dp = (const struct ip6_hbh *)bp;
  163. int hbhlen = 0;
  164. ND_TCHECK(dp->ip6h_len);
  165. hbhlen = (int)((dp->ip6h_len + 1) << 3);
  166. ND_TCHECK2(*dp, hbhlen);
  167. ND_PRINT((ndo, "HBH "));
  168. if (ndo->ndo_vflag)
  169. ip6_opt_print(ndo, (const u_char *)dp + sizeof(*dp), hbhlen - sizeof(*dp));
  170. return(hbhlen);
  171. trunc:
  172. ND_PRINT((ndo, "[|HBH]"));
  173. return(-1);
  174. }
  175. int
  176. dstopt_print(netdissect_options *ndo, register const u_char *bp)
  177. {
  178. const struct ip6_dest *dp = (const struct ip6_dest *)bp;
  179. int dstoptlen = 0;
  180. ND_TCHECK(dp->ip6d_len);
  181. dstoptlen = (int)((dp->ip6d_len + 1) << 3);
  182. ND_TCHECK2(*dp, dstoptlen);
  183. ND_PRINT((ndo, "DSTOPT "));
  184. if (ndo->ndo_vflag) {
  185. ip6_opt_print(ndo, (const u_char *)dp + sizeof(*dp),
  186. dstoptlen - sizeof(*dp));
  187. }
  188. return(dstoptlen);
  189. trunc:
  190. ND_PRINT((ndo, "[|DSTOPT]"));
  191. return(-1);
  192. }