PageRenderTime 26ms CodeModel.GetById 9ms RepoModel.GetById 1ms app.codeStats 0ms

/contrib/tcpdump/print-ether.c

https://bitbucket.org/freebsd/freebsd-head/
C | 434 lines | 284 code | 54 blank | 96 comment | 52 complexity | 0de72a31fb576deeb6b5a08ac4b97876 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, BSD-3-Clause, LGPL-2.0, LGPL-2.1, BSD-2-Clause, 0BSD, JSON, AGPL-1.0, GPL-2.0
  1. /*
  2. * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
  3. * The Regents of the University of California. All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that: (1) source code distributions
  7. * retain the above copyright notice and this paragraph in its entirety, (2)
  8. * distributions including binary code include the above copyright notice and
  9. * this paragraph in its entirety in the documentation or other materials
  10. * provided with the distribution, and (3) all advertising materials mentioning
  11. * features or use of this software display the following acknowledgement:
  12. * ``This product includes software developed by the University of California,
  13. * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  14. * the University nor the names of its contributors may be used to endorse
  15. * or promote products derived from this software without specific prior
  16. * written permission.
  17. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  18. * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  19. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  20. *
  21. * $FreeBSD$
  22. */
  23. #ifndef lint
  24. static const char rcsid[] _U_ =
  25. "@(#) $Header: /tcpdump/master/tcpdump/print-ether.c,v 1.106 2008-02-06 10:47:53 guy Exp $ (LBL)";
  26. #endif
  27. #define NETDISSECT_REWORKED
  28. #ifdef HAVE_CONFIG_H
  29. #include "config.h"
  30. #endif
  31. #include <tcpdump-stdinc.h>
  32. #include <stdio.h>
  33. #include <pcap.h>
  34. #include "interface.h"
  35. #include "extract.h"
  36. #include "addrtoname.h"
  37. #include "ethertype.h"
  38. #include "ether.h"
  39. const struct tok ethertype_values[] = {
  40. { ETHERTYPE_IP, "IPv4" },
  41. { ETHERTYPE_MPLS, "MPLS unicast" },
  42. { ETHERTYPE_MPLS_MULTI, "MPLS multicast" },
  43. { ETHERTYPE_IPV6, "IPv6" },
  44. { ETHERTYPE_8021Q, "802.1Q" },
  45. { ETHERTYPE_8021Q9100, "802.1Q-9100" },
  46. { ETHERTYPE_8021QinQ, "802.1Q-QinQ" },
  47. { ETHERTYPE_8021Q9200, "802.1Q-9200" },
  48. { ETHERTYPE_VMAN, "VMAN" },
  49. { ETHERTYPE_PUP, "PUP" },
  50. { ETHERTYPE_ARP, "ARP"},
  51. { ETHERTYPE_REVARP, "Reverse ARP"},
  52. { ETHERTYPE_NS, "NS" },
  53. { ETHERTYPE_SPRITE, "Sprite" },
  54. { ETHERTYPE_TRAIL, "Trail" },
  55. { ETHERTYPE_MOPDL, "MOP DL" },
  56. { ETHERTYPE_MOPRC, "MOP RC" },
  57. { ETHERTYPE_DN, "DN" },
  58. { ETHERTYPE_LAT, "LAT" },
  59. { ETHERTYPE_SCA, "SCA" },
  60. { ETHERTYPE_TEB, "TEB" },
  61. { ETHERTYPE_LANBRIDGE, "Lanbridge" },
  62. { ETHERTYPE_DECDNS, "DEC DNS" },
  63. { ETHERTYPE_DECDTS, "DEC DTS" },
  64. { ETHERTYPE_VEXP, "VEXP" },
  65. { ETHERTYPE_VPROD, "VPROD" },
  66. { ETHERTYPE_ATALK, "Appletalk" },
  67. { ETHERTYPE_AARP, "Appletalk ARP" },
  68. { ETHERTYPE_IPX, "IPX" },
  69. { ETHERTYPE_PPP, "PPP" },
  70. { ETHERTYPE_MPCP, "MPCP" },
  71. { ETHERTYPE_SLOW, "Slow Protocols" },
  72. { ETHERTYPE_PPPOED, "PPPoE D" },
  73. { ETHERTYPE_PPPOES, "PPPoE S" },
  74. { ETHERTYPE_EAPOL, "EAPOL" },
  75. { ETHERTYPE_RRCP, "RRCP" },
  76. { ETHERTYPE_JUMBO, "Jumbo" },
  77. { ETHERTYPE_LOOPBACK, "Loopback" },
  78. { ETHERTYPE_ISO, "OSI" },
  79. { ETHERTYPE_GRE_ISO, "GRE-OSI" },
  80. { ETHERTYPE_CFM_OLD, "CFM (old)" },
  81. { ETHERTYPE_CFM, "CFM" },
  82. { ETHERTYPE_LLDP, "LLDP" },
  83. { ETHERTYPE_TIPC, "TIPC"},
  84. { 0, NULL}
  85. };
  86. static inline void
  87. ether_hdr_print(netdissect_options *ndo,
  88. const u_char *bp, u_int length)
  89. {
  90. register const struct ether_header *ep;
  91. u_int16_t ether_type;
  92. ep = (const struct ether_header *)bp;
  93. (void)ND_PRINT((ndo, "%s > %s",
  94. etheraddr_string(ESRC(ep)),
  95. etheraddr_string(EDST(ep))));
  96. ether_type = EXTRACT_16BITS(&ep->ether_type);
  97. if (!ndo->ndo_qflag) {
  98. if (ether_type <= ETHERMTU)
  99. (void)ND_PRINT((ndo, ", 802.3"));
  100. else
  101. (void)ND_PRINT((ndo, ", ethertype %s (0x%04x)",
  102. tok2str(ethertype_values,"Unknown", ether_type),
  103. ether_type));
  104. } else {
  105. if (ether_type <= ETHERMTU)
  106. (void)ND_PRINT((ndo, ", 802.3"));
  107. else
  108. (void)ND_PRINT((ndo, ", %s", tok2str(ethertype_values,"Unknown Ethertype (0x%04x)", ether_type)));
  109. }
  110. (void)ND_PRINT((ndo, ", length %u: ", length));
  111. }
  112. /*
  113. * Print an Ethernet frame.
  114. * This might be encapsulated within another frame; we might be passed
  115. * a pointer to a function that can print header information for that
  116. * frame's protocol, and an argument to pass to that function.
  117. */
  118. void
  119. ether_print(netdissect_options *ndo,
  120. const u_char *p, u_int length, u_int caplen,
  121. void (*print_encap_header)(netdissect_options *ndo, const u_char *), const u_char *encap_header_arg)
  122. {
  123. struct ether_header *ep;
  124. u_int orig_length;
  125. u_short ether_type;
  126. u_short extracted_ether_type;
  127. if (caplen < ETHER_HDRLEN || length < ETHER_HDRLEN) {
  128. ND_PRINT((ndo, "[|ether]"));
  129. return;
  130. }
  131. if (ndo->ndo_eflag) {
  132. if (print_encap_header != NULL)
  133. (*print_encap_header)(ndo, encap_header_arg);
  134. ether_hdr_print(ndo, p, length);
  135. }
  136. orig_length = length;
  137. length -= ETHER_HDRLEN;
  138. caplen -= ETHER_HDRLEN;
  139. ep = (struct ether_header *)p;
  140. p += ETHER_HDRLEN;
  141. ether_type = EXTRACT_16BITS(&ep->ether_type);
  142. recurse:
  143. /*
  144. * Is it (gag) an 802.3 encapsulation?
  145. */
  146. if (ether_type <= ETHERMTU) {
  147. /* Try to print the LLC-layer header & higher layers */
  148. if (llc_print(p, length, caplen, ESRC(ep), EDST(ep),
  149. &extracted_ether_type) == 0) {
  150. /* ether_type not known, print raw packet */
  151. if (!ndo->ndo_eflag) {
  152. if (print_encap_header != NULL)
  153. (*print_encap_header)(ndo, encap_header_arg);
  154. ether_hdr_print(ndo, (u_char *)ep, orig_length);
  155. }
  156. if (!ndo->ndo_suppress_default_print)
  157. ndo->ndo_default_print(ndo, p, caplen);
  158. }
  159. } else if (ether_type == ETHERTYPE_8021Q ||
  160. ether_type == ETHERTYPE_8021Q9100 ||
  161. ether_type == ETHERTYPE_8021Q9200 ||
  162. ether_type == ETHERTYPE_8021QinQ) {
  163. /*
  164. * Print VLAN information, and then go back and process
  165. * the enclosed type field.
  166. */
  167. if (caplen < 4 || length < 4) {
  168. ND_PRINT((ndo, "[|vlan]"));
  169. return;
  170. }
  171. if (ndo->ndo_eflag) {
  172. u_int16_t tag = EXTRACT_16BITS(p);
  173. ND_PRINT((ndo, "vlan %u, p %u%s, ",
  174. tag & 0xfff,
  175. tag >> 13,
  176. (tag & 0x1000) ? ", CFI" : ""));
  177. }
  178. ether_type = EXTRACT_16BITS(p + 2);
  179. if (ndo->ndo_eflag && ether_type > ETHERMTU)
  180. ND_PRINT((ndo, "ethertype %s, ", tok2str(ethertype_values,"0x%04x", ether_type)));
  181. p += 4;
  182. length -= 4;
  183. caplen -= 4;
  184. goto recurse;
  185. } else if (ether_type == ETHERTYPE_JUMBO) {
  186. /*
  187. * Alteon jumbo frames.
  188. * See
  189. *
  190. * http://tools.ietf.org/html/draft-ietf-isis-ext-eth-01
  191. *
  192. * which indicates that, following the type field,
  193. * there's an LLC header and payload.
  194. */
  195. /* Try to print the LLC-layer header & higher layers */
  196. if (llc_print(p, length, caplen, ESRC(ep), EDST(ep),
  197. &extracted_ether_type) == 0) {
  198. /* ether_type not known, print raw packet */
  199. if (!ndo->ndo_eflag) {
  200. if (print_encap_header != NULL)
  201. (*print_encap_header)(ndo, encap_header_arg);
  202. ether_hdr_print(ndo, (u_char *)ep, orig_length);
  203. }
  204. if (!ndo->ndo_suppress_default_print)
  205. ndo->ndo_default_print(ndo, p, caplen);
  206. }
  207. } else {
  208. if (ethertype_print(ndo, ether_type, p, length, caplen) == 0) {
  209. /* ether_type not known, print raw packet */
  210. if (!ndo->ndo_eflag) {
  211. if (print_encap_header != NULL)
  212. (*print_encap_header)(ndo, encap_header_arg);
  213. ether_hdr_print(ndo, (u_char *)ep, orig_length);
  214. }
  215. if (!ndo->ndo_suppress_default_print)
  216. ndo->ndo_default_print(ndo, p, caplen);
  217. }
  218. }
  219. }
  220. /*
  221. * This is the top level routine of the printer. 'p' points
  222. * to the ether header of the packet, 'h->ts' is the timestamp,
  223. * 'h->len' is the length of the packet off the wire, and 'h->caplen'
  224. * is the number of bytes actually captured.
  225. */
  226. u_int
  227. ether_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h,
  228. const u_char *p)
  229. {
  230. ether_print(ndo, p, h->len, h->caplen, NULL, NULL);
  231. return (ETHER_HDRLEN);
  232. }
  233. /*
  234. * This is the top level routine of the printer. 'p' points
  235. * to the ether header of the packet, 'h->ts' is the timestamp,
  236. * 'h->len' is the length of the packet off the wire, and 'h->caplen'
  237. * is the number of bytes actually captured.
  238. *
  239. * This is for DLT_NETANALYZER, which has a 4-byte pseudo-header
  240. * before the Ethernet header.
  241. */
  242. u_int
  243. netanalyzer_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h,
  244. const u_char *p)
  245. {
  246. /*
  247. * Fail if we don't have enough data for the Hilscher pseudo-header.
  248. */
  249. if (h->len < 4 || h->caplen < 4) {
  250. printf("[|netanalyzer]");
  251. return (h->caplen);
  252. }
  253. /* Skip the pseudo-header. */
  254. ether_print(ndo, p + 4, h->len - 4, h->caplen - 4, NULL, NULL);
  255. return (4 + ETHER_HDRLEN);
  256. }
  257. /*
  258. * This is the top level routine of the printer. 'p' points
  259. * to the ether header of the packet, 'h->ts' is the timestamp,
  260. * 'h->len' is the length of the packet off the wire, and 'h->caplen'
  261. * is the number of bytes actually captured.
  262. *
  263. * This is for DLT_NETANALYZER_TRANSPARENT, which has a 4-byte
  264. * pseudo-header, a 7-byte Ethernet preamble, and a 1-byte Ethernet SOF
  265. * before the Ethernet header.
  266. */
  267. u_int
  268. netanalyzer_transparent_if_print(netdissect_options *ndo,
  269. const struct pcap_pkthdr *h,
  270. const u_char *p)
  271. {
  272. /*
  273. * Fail if we don't have enough data for the Hilscher pseudo-header,
  274. * preamble, and SOF.
  275. */
  276. if (h->len < 12 || h->caplen < 12) {
  277. printf("[|netanalyzer-transparent]");
  278. return (h->caplen);
  279. }
  280. /* Skip the pseudo-header, preamble, and SOF. */
  281. ether_print(ndo, p + 12, h->len - 12, h->caplen - 12, NULL, NULL);
  282. return (12 + ETHER_HDRLEN);
  283. }
  284. /*
  285. * Prints the packet payload, given an Ethernet type code for the payload's
  286. * protocol.
  287. *
  288. * Returns non-zero if it can do so, zero if the ethertype is unknown.
  289. */
  290. int
  291. ethertype_print(netdissect_options *ndo,
  292. u_short ether_type, const u_char *p,
  293. u_int length, u_int caplen)
  294. {
  295. switch (ether_type) {
  296. case ETHERTYPE_IP:
  297. ip_print(ndo, p, length);
  298. return (1);
  299. #ifdef INET6
  300. case ETHERTYPE_IPV6:
  301. ip6_print(ndo, p, length);
  302. return (1);
  303. #endif /*INET6*/
  304. case ETHERTYPE_ARP:
  305. case ETHERTYPE_REVARP:
  306. arp_print(ndo, p, length, caplen);
  307. return (1);
  308. case ETHERTYPE_DN:
  309. decnet_print(/*ndo,*/p, length, caplen);
  310. return (1);
  311. case ETHERTYPE_ATALK:
  312. if (ndo->ndo_vflag)
  313. fputs("et1 ", stdout);
  314. atalk_print(/*ndo,*/p, length);
  315. return (1);
  316. case ETHERTYPE_AARP:
  317. aarp_print(/*ndo,*/p, length);
  318. return (1);
  319. case ETHERTYPE_IPX:
  320. ND_PRINT((ndo, "(NOV-ETHII) "));
  321. ipx_print(/*ndo,*/p, length);
  322. return (1);
  323. case ETHERTYPE_ISO:
  324. isoclns_print(/*ndo,*/p+1, length-1, length-1);
  325. return(1);
  326. case ETHERTYPE_PPPOED:
  327. case ETHERTYPE_PPPOES:
  328. case ETHERTYPE_PPPOED2:
  329. case ETHERTYPE_PPPOES2:
  330. pppoe_print(/*ndo,*/p, length);
  331. return (1);
  332. case ETHERTYPE_EAPOL:
  333. eap_print(ndo, p, length);
  334. return (1);
  335. case ETHERTYPE_RRCP:
  336. rrcp_print(ndo, p - 14 , length + 14);
  337. return (1);
  338. case ETHERTYPE_PPP:
  339. if (length) {
  340. printf(": ");
  341. ppp_print(/*ndo,*/p, length);
  342. }
  343. return (1);
  344. case ETHERTYPE_MPCP:
  345. mpcp_print(/*ndo,*/p, length);
  346. return (1);
  347. case ETHERTYPE_SLOW:
  348. slow_print(/*ndo,*/p, length);
  349. return (1);
  350. case ETHERTYPE_CFM:
  351. case ETHERTYPE_CFM_OLD:
  352. cfm_print(/*ndo,*/p, length);
  353. return (1);
  354. case ETHERTYPE_LLDP:
  355. lldp_print(/*ndo,*/p, length);
  356. return (1);
  357. case ETHERTYPE_LOOPBACK:
  358. return (1);
  359. case ETHERTYPE_MPLS:
  360. case ETHERTYPE_MPLS_MULTI:
  361. mpls_print(/*ndo,*/p, length);
  362. return (1);
  363. case ETHERTYPE_TIPC:
  364. tipc_print(ndo, p, length, caplen);
  365. return (1);
  366. case ETHERTYPE_LAT:
  367. case ETHERTYPE_SCA:
  368. case ETHERTYPE_MOPRC:
  369. case ETHERTYPE_MOPDL:
  370. /* default_print for now */
  371. default:
  372. return (0);
  373. }
  374. }
  375. /*
  376. * Local Variables:
  377. * c-style: whitesmith
  378. * c-basic-offset: 8
  379. * End:
  380. */