print-chdlc.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /*
  2. * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997
  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. /* \summary: Cisco HDLC printer */
  22. #ifdef HAVE_CONFIG_H
  23. #include "config.h"
  24. #endif
  25. #include <netdissect-stdinc.h>
  26. #include "netdissect.h"
  27. #include "addrtoname.h"
  28. #include "ethertype.h"
  29. #include "extract.h"
  30. #include "chdlc.h"
  31. static void chdlc_slarp_print(netdissect_options *, const u_char *, u_int);
  32. static const struct tok chdlc_cast_values[] = {
  33. { CHDLC_UNICAST, "unicast" },
  34. { CHDLC_BCAST, "bcast" },
  35. { 0, NULL}
  36. };
  37. /* Standard CHDLC printer */
  38. u_int
  39. chdlc_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, register const u_char *p)
  40. {
  41. return chdlc_print(ndo, p, h->len);
  42. }
  43. u_int
  44. chdlc_print(netdissect_options *ndo, register const u_char *p, u_int length)
  45. {
  46. u_int proto;
  47. const u_char *bp = p;
  48. if (length < CHDLC_HDRLEN)
  49. goto trunc;
  50. ND_TCHECK2(*p, CHDLC_HDRLEN);
  51. proto = EXTRACT_16BITS(&p[2]);
  52. if (ndo->ndo_eflag) {
  53. ND_PRINT((ndo, "%s, ethertype %s (0x%04x), length %u: ",
  54. tok2str(chdlc_cast_values, "0x%02x", p[0]),
  55. tok2str(ethertype_values, "Unknown", proto),
  56. proto,
  57. length));
  58. }
  59. length -= CHDLC_HDRLEN;
  60. p += CHDLC_HDRLEN;
  61. switch (proto) {
  62. case ETHERTYPE_IP:
  63. ip_print(ndo, p, length);
  64. break;
  65. case ETHERTYPE_IPV6:
  66. ip6_print(ndo, p, length);
  67. break;
  68. case CHDLC_TYPE_SLARP:
  69. chdlc_slarp_print(ndo, p, length);
  70. break;
  71. #if 0
  72. case CHDLC_TYPE_CDP:
  73. chdlc_cdp_print(p, length);
  74. break;
  75. #endif
  76. case ETHERTYPE_MPLS:
  77. case ETHERTYPE_MPLS_MULTI:
  78. mpls_print(ndo, p, length);
  79. break;
  80. case ETHERTYPE_ISO:
  81. /* is the fudge byte set ? lets verify by spotting ISO headers */
  82. if (length < 2)
  83. goto trunc;
  84. ND_TCHECK_16BITS(p);
  85. if (*(p+1) == 0x81 ||
  86. *(p+1) == 0x82 ||
  87. *(p+1) == 0x83)
  88. isoclns_print(ndo, p + 1, length - 1);
  89. else
  90. isoclns_print(ndo, p, length);
  91. break;
  92. default:
  93. if (!ndo->ndo_eflag)
  94. ND_PRINT((ndo, "unknown CHDLC protocol (0x%04x)", proto));
  95. break;
  96. }
  97. return (CHDLC_HDRLEN);
  98. trunc:
  99. ND_PRINT((ndo, "[|chdlc]"));
  100. return ndo->ndo_snapend - bp;
  101. }
  102. /*
  103. * The fixed-length portion of a SLARP packet.
  104. */
  105. struct cisco_slarp {
  106. uint8_t code[4];
  107. #define SLARP_REQUEST 0
  108. #define SLARP_REPLY 1
  109. #define SLARP_KEEPALIVE 2
  110. union {
  111. struct {
  112. uint8_t addr[4];
  113. uint8_t mask[4];
  114. } addr;
  115. struct {
  116. uint8_t myseq[4];
  117. uint8_t yourseq[4];
  118. uint8_t rel[2];
  119. } keep;
  120. } un;
  121. };
  122. #define SLARP_MIN_LEN 14
  123. #define SLARP_MAX_LEN 18
  124. static void
  125. chdlc_slarp_print(netdissect_options *ndo, const u_char *cp, u_int length)
  126. {
  127. const struct cisco_slarp *slarp;
  128. u_int sec,min,hrs,days;
  129. ND_PRINT((ndo, "SLARP (length: %u), ",length));
  130. if (length < SLARP_MIN_LEN)
  131. goto trunc;
  132. slarp = (const struct cisco_slarp *)cp;
  133. ND_TCHECK2(*slarp, SLARP_MIN_LEN);
  134. switch (EXTRACT_32BITS(&slarp->code)) {
  135. case SLARP_REQUEST:
  136. ND_PRINT((ndo, "request"));
  137. /*
  138. * At least according to William "Chops" Westfield's
  139. * message in
  140. *
  141. * http://www.nethelp.no/net/cisco-hdlc.txt
  142. *
  143. * the address and mask aren't used in requests -
  144. * they're just zero.
  145. */
  146. break;
  147. case SLARP_REPLY:
  148. ND_PRINT((ndo, "reply %s/%s",
  149. ipaddr_string(ndo, &slarp->un.addr.addr),
  150. ipaddr_string(ndo, &slarp->un.addr.mask)));
  151. break;
  152. case SLARP_KEEPALIVE:
  153. ND_PRINT((ndo, "keepalive: mineseen=0x%08x, yourseen=0x%08x, reliability=0x%04x",
  154. EXTRACT_32BITS(&slarp->un.keep.myseq),
  155. EXTRACT_32BITS(&slarp->un.keep.yourseq),
  156. EXTRACT_16BITS(&slarp->un.keep.rel)));
  157. if (length >= SLARP_MAX_LEN) { /* uptime-stamp is optional */
  158. cp += SLARP_MIN_LEN;
  159. ND_TCHECK2(*cp, 4);
  160. sec = EXTRACT_32BITS(cp) / 1000;
  161. min = sec / 60; sec -= min * 60;
  162. hrs = min / 60; min -= hrs * 60;
  163. days = hrs / 24; hrs -= days * 24;
  164. ND_PRINT((ndo, ", link uptime=%ud%uh%um%us",days,hrs,min,sec));
  165. }
  166. break;
  167. default:
  168. ND_PRINT((ndo, "0x%02x unknown", EXTRACT_32BITS(&slarp->code)));
  169. if (ndo->ndo_vflag <= 1)
  170. print_unknown_data(ndo,cp+4,"\n\t",length-4);
  171. break;
  172. }
  173. if (SLARP_MAX_LEN < length && ndo->ndo_vflag)
  174. ND_PRINT((ndo, ", (trailing junk: %d bytes)", length - SLARP_MAX_LEN));
  175. if (ndo->ndo_vflag > 1)
  176. print_unknown_data(ndo,cp+4,"\n\t",length-4);
  177. return;
  178. trunc:
  179. ND_PRINT((ndo, "[|slarp]"));
  180. }
  181. /*
  182. * Local Variables:
  183. * c-style: whitesmith
  184. * c-basic-offset: 8
  185. * End:
  186. */