PageRenderTime 42ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 1ms

/contrib/tcpdump/print-babel.c

https://gitlab.com/HowTheStoryEnds/freebsd11-psm-port
C | 414 lines | 344 code | 42 blank | 28 comment | 79 complexity | 224ffca27169cef66c91b3d3888262e7 MD5 | raw file
  1. /*
  2. * Copyright (c) 2007-2011 Grégoire Henry, Juliusz Chroboczek
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. * 1. Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * 2. Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * 3. Neither the name of the project nor the names of its contributors
  13. * may be used to endorse or promote products derived from this software
  14. * without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  17. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  19. * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
  20. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  22. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  23. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  24. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  25. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  26. * SUCH DAMAGE.
  27. */
  28. #ifdef HAVE_CONFIG_H
  29. #include "config.h"
  30. #endif
  31. #include <tcpdump-stdinc.h>
  32. #include <stdio.h>
  33. #include <string.h>
  34. #include "addrtoname.h"
  35. #include "interface.h"
  36. #include "extract.h"
  37. static void babel_print_v2(const u_char *cp, u_int length);
  38. void
  39. babel_print(const u_char *cp, u_int length) {
  40. printf("babel");
  41. TCHECK2(*cp, 4);
  42. if(cp[0] != 42) {
  43. printf(" malformed header");
  44. return;
  45. } else {
  46. printf(" %d", cp[1]);
  47. }
  48. switch(cp[1]) {
  49. case 2:
  50. babel_print_v2(cp,length);
  51. break;
  52. default:
  53. printf(" unknown version");
  54. break;
  55. }
  56. return;
  57. trunc:
  58. printf(" [|babel]");
  59. return;
  60. }
  61. #define MESSAGE_PAD1 0
  62. #define MESSAGE_PADN 1
  63. #define MESSAGE_ACK_REQ 2
  64. #define MESSAGE_ACK 3
  65. #define MESSAGE_HELLO 4
  66. #define MESSAGE_IHU 5
  67. #define MESSAGE_ROUTER_ID 6
  68. #define MESSAGE_NH 7
  69. #define MESSAGE_UPDATE 8
  70. #define MESSAGE_REQUEST 9
  71. #define MESSAGE_MH_REQUEST 10
  72. static const char *
  73. format_id(const u_char *id)
  74. {
  75. static char buf[25];
  76. snprintf(buf, 25, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
  77. id[0], id[1], id[2], id[3], id[4], id[5], id[6], id[7]);
  78. buf[24] = '\0';
  79. return buf;
  80. }
  81. static const unsigned char v4prefix[16] =
  82. {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0 };
  83. static const char *
  84. format_prefix(const u_char *prefix, unsigned char plen)
  85. {
  86. static char buf[50];
  87. if(plen >= 96 && memcmp(prefix, v4prefix, 12) == 0)
  88. snprintf(buf, 50, "%s/%u", ipaddr_string(prefix + 12), plen - 96);
  89. else
  90. snprintf(buf, 50, "%s/%u", ip6addr_string(prefix), plen);
  91. buf[49] = '\0';
  92. return buf;
  93. }
  94. static const char *
  95. format_address(const u_char *prefix)
  96. {
  97. if(memcmp(prefix, v4prefix, 12) == 0)
  98. return ipaddr_string(prefix + 12);
  99. else
  100. return ip6addr_string(prefix);
  101. }
  102. static int
  103. network_prefix(int ae, int plen, unsigned int omitted,
  104. const unsigned char *p, const unsigned char *dp,
  105. unsigned int len, unsigned char *p_r)
  106. {
  107. unsigned pb;
  108. unsigned char prefix[16];
  109. if(plen >= 0)
  110. pb = (plen + 7) / 8;
  111. else if(ae == 1)
  112. pb = 4;
  113. else
  114. pb = 16;
  115. if(pb > 16)
  116. return -1;
  117. memset(prefix, 0, 16);
  118. switch(ae) {
  119. case 0: break;
  120. case 1:
  121. if(omitted > 4 || pb > 4 || (pb > omitted && len < pb - omitted))
  122. return -1;
  123. memcpy(prefix, v4prefix, 12);
  124. if(omitted) {
  125. if (dp == NULL) return -1;
  126. memcpy(prefix, dp, 12 + omitted);
  127. }
  128. if(pb > omitted) memcpy(prefix + 12 + omitted, p, pb - omitted);
  129. break;
  130. case 2:
  131. if(omitted > 16 || (pb > omitted && len < pb - omitted))
  132. return -1;
  133. if(omitted) {
  134. if (dp == NULL) return -1;
  135. memcpy(prefix, dp, omitted);
  136. }
  137. if(pb > omitted) memcpy(prefix + omitted, p, pb - omitted);
  138. break;
  139. case 3:
  140. if(pb > 8 && len < pb - 8) return -1;
  141. prefix[0] = 0xfe;
  142. prefix[1] = 0x80;
  143. if(pb > 8) memcpy(prefix + 8, p, pb - 8);
  144. break;
  145. default:
  146. return -1;
  147. }
  148. memcpy(p_r, prefix, 16);
  149. return 1;
  150. }
  151. static int
  152. network_address(int ae, const unsigned char *a, unsigned int len,
  153. unsigned char *a_r)
  154. {
  155. return network_prefix(ae, -1, 0, a, NULL, len, a_r);
  156. }
  157. #define ICHECK(i, l) \
  158. if ((i) + (l) > bodylen || (i) + (l) > length) goto corrupt;
  159. static void
  160. babel_print_v2(const u_char *cp, u_int length) {
  161. u_int i;
  162. u_short bodylen;
  163. u_char v4_prefix[16] =
  164. {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0 };
  165. u_char v6_prefix[16] = {0};
  166. TCHECK2(*cp, 4);
  167. if (length < 4)
  168. goto corrupt;
  169. bodylen = EXTRACT_16BITS(cp + 2);
  170. printf(" (%u)", bodylen);
  171. /* Process the TLVs in the body */
  172. i = 0;
  173. while(i < bodylen) {
  174. const u_char *message;
  175. u_char type, len;
  176. message = cp + 4 + i;
  177. TCHECK2(*message, 2);
  178. ICHECK(i, 2);
  179. type = message[0];
  180. len = message[1];
  181. TCHECK2(*message, 2 + len);
  182. ICHECK(i, 2 + len);
  183. switch(type) {
  184. case MESSAGE_PAD1: {
  185. if(!vflag)
  186. printf(" pad1");
  187. else
  188. printf("\n\tPad 1");
  189. }
  190. break;
  191. case MESSAGE_PADN: {
  192. if(!vflag)
  193. printf(" padN");
  194. else
  195. printf("\n\tPad %d", len + 2);
  196. }
  197. break;
  198. case MESSAGE_ACK_REQ: {
  199. u_short nonce, interval;
  200. if(!vflag)
  201. printf(" ack-req");
  202. else {
  203. printf("\n\tAcknowledgment Request ");
  204. if(len < 6) goto corrupt;
  205. nonce = EXTRACT_16BITS(message + 4);
  206. interval = EXTRACT_16BITS(message + 6);
  207. printf("%04x %d", nonce, interval);
  208. }
  209. }
  210. break;
  211. case MESSAGE_ACK: {
  212. u_short nonce;
  213. if(!vflag)
  214. printf(" ack");
  215. else {
  216. printf("\n\tAcknowledgment ");
  217. if(len < 2) goto corrupt;
  218. nonce = EXTRACT_16BITS(message + 2);
  219. printf("%04x", nonce);
  220. }
  221. }
  222. break;
  223. case MESSAGE_HELLO: {
  224. u_short seqno, interval;
  225. if(!vflag)
  226. printf(" hello");
  227. else {
  228. printf("\n\tHello ");
  229. if(len < 6) goto corrupt;
  230. seqno = EXTRACT_16BITS(message + 4);
  231. interval = EXTRACT_16BITS(message + 6);
  232. printf("seqno %u interval %u", seqno, interval);
  233. }
  234. }
  235. break;
  236. case MESSAGE_IHU: {
  237. unsigned short txcost, interval;
  238. if(!vflag)
  239. printf(" ihu");
  240. else {
  241. u_char address[16];
  242. int rc;
  243. printf("\n\tIHU ");
  244. if(len < 6) goto corrupt;
  245. txcost = EXTRACT_16BITS(message + 4);
  246. interval = EXTRACT_16BITS(message + 6);
  247. rc = network_address(message[2], message + 8, len - 6, address);
  248. if(rc < 0) { printf("[|babel]"); break; }
  249. printf("%s txcost %u interval %d",
  250. format_address(address), txcost, interval);
  251. }
  252. }
  253. break;
  254. case MESSAGE_ROUTER_ID: {
  255. if(!vflag)
  256. printf(" router-id");
  257. else {
  258. printf("\n\tRouter Id");
  259. if(len < 10) goto corrupt;
  260. printf(" %s", format_id(message + 4));
  261. }
  262. }
  263. break;
  264. case MESSAGE_NH: {
  265. if(!vflag)
  266. printf(" nh");
  267. else {
  268. int rc;
  269. u_char nh[16];
  270. printf("\n\tNext Hop");
  271. if(len < 2) goto corrupt;
  272. rc = network_address(message[2], message + 4, len - 2, nh);
  273. if(rc < 0) goto corrupt;
  274. printf(" %s", format_address(nh));
  275. }
  276. }
  277. break;
  278. case MESSAGE_UPDATE: {
  279. if(!vflag) {
  280. printf(" update");
  281. if(len < 1)
  282. printf("/truncated");
  283. else
  284. printf("%s%s%s",
  285. (message[3] & 0x80) ? "/prefix": "",
  286. (message[3] & 0x40) ? "/id" : "",
  287. (message[3] & 0x3f) ? "/unknown" : "");
  288. } else {
  289. u_short interval, seqno, metric;
  290. u_char plen;
  291. int rc;
  292. u_char prefix[16];
  293. printf("\n\tUpdate");
  294. if(len < 10) goto corrupt;
  295. plen = message[4] + (message[2] == 1 ? 96 : 0);
  296. rc = network_prefix(message[2], message[4], message[5],
  297. message + 12,
  298. message[2] == 1 ? v4_prefix : v6_prefix,
  299. len - 10, prefix);
  300. if(rc < 0) goto corrupt;
  301. interval = EXTRACT_16BITS(message + 6);
  302. seqno = EXTRACT_16BITS(message + 8);
  303. metric = EXTRACT_16BITS(message + 10);
  304. printf("%s%s%s %s metric %u seqno %u interval %u",
  305. (message[3] & 0x80) ? "/prefix": "",
  306. (message[3] & 0x40) ? "/id" : "",
  307. (message[3] & 0x3f) ? "/unknown" : "",
  308. format_prefix(prefix, plen),
  309. metric, seqno, interval);
  310. if(message[3] & 0x80) {
  311. if(message[2] == 1)
  312. memcpy(v4_prefix, prefix, 16);
  313. else
  314. memcpy(v6_prefix, prefix, 16);
  315. }
  316. }
  317. }
  318. break;
  319. case MESSAGE_REQUEST: {
  320. if(!vflag)
  321. printf(" request");
  322. else {
  323. int rc;
  324. u_char prefix[16], plen;
  325. printf("\n\tRequest ");
  326. if(len < 2) goto corrupt;
  327. plen = message[3] + (message[2] == 1 ? 96 : 0);
  328. rc = network_prefix(message[2], message[3], 0,
  329. message + 4, NULL, len - 2, prefix);
  330. if(rc < 0) goto corrupt;
  331. plen = message[3] + (message[2] == 1 ? 96 : 0);
  332. printf("for %s",
  333. message[2] == 0 ? "any" : format_prefix(prefix, plen));
  334. }
  335. }
  336. break;
  337. case MESSAGE_MH_REQUEST : {
  338. if(!vflag)
  339. printf(" mh-request");
  340. else {
  341. int rc;
  342. u_short seqno;
  343. u_char prefix[16], plen;
  344. printf("\n\tMH-Request ");
  345. if(len < 14) goto corrupt;
  346. seqno = EXTRACT_16BITS(message + 4);
  347. rc = network_prefix(message[2], message[3], 0,
  348. message + 16, NULL, len - 14, prefix);
  349. if(rc < 0) goto corrupt;
  350. plen = message[3] + (message[2] == 1 ? 96 : 0);
  351. printf("(%u hops) for %s seqno %u id %s",
  352. message[6], format_prefix(prefix, plen),
  353. seqno, format_id(message + 8));
  354. }
  355. }
  356. break;
  357. default:
  358. if(!vflag)
  359. printf(" unknown");
  360. else
  361. printf("\n\tUnknown message type %d", type);
  362. }
  363. i += len + 2;
  364. }
  365. return;
  366. trunc:
  367. printf(" [|babel]");
  368. return;
  369. corrupt:
  370. printf(" (corrupt)");
  371. return;
  372. }