tcpdump  4.99.1
About: tcpdump is a tool for network monitoring and data acquisition.
  Fossies Dox: tcpdump-4.99.1.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

print-fr.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996
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 
22 /* \summary: Frame Relay printer */
23 
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27 
28 #include "netdissect-stdinc.h"
29 
30 #include <stdio.h>
31 #include <string.h>
32 
33 #include "netdissect.h"
34 #include "addrtoname.h"
35 #include "ethertype.h"
36 #include "llc.h"
37 #include "nlpid.h"
38 #include "extract.h"
39 
40 static void frf15_print(netdissect_options *ndo, const u_char *, u_int);
41 
42 /*
43  * the frame relay header has a variable length
44  *
45  * the EA bit determines if there is another byte
46  * in the header
47  *
48  * minimum header length is 2 bytes
49  * maximum header length is 4 bytes
50  *
51  * 7 6 5 4 3 2 1 0
52  * +----+----+----+----+----+----+----+----+
53  * | DLCI (6 bits) | CR | EA |
54  * +----+----+----+----+----+----+----+----+
55  * | DLCI (4 bits) |FECN|BECN| DE | EA |
56  * +----+----+----+----+----+----+----+----+
57  * | DLCI (7 bits) | EA |
58  * +----+----+----+----+----+----+----+----+
59  * | DLCI (6 bits) |SDLC| EA |
60  * +----+----+----+----+----+----+----+----+
61  */
62 
63 #define FR_EA_BIT 0x01
64 
65 #define FR_CR_BIT 0x02000000
66 #define FR_DE_BIT 0x00020000
67 #define FR_BECN_BIT 0x00040000
68 #define FR_FECN_BIT 0x00080000
69 #define FR_SDLC_BIT 0x00000002
70 
71 
72 static const struct tok fr_header_flag_values[] = {
73  { FR_CR_BIT, "C!" },
74  { FR_DE_BIT, "DE" },
75  { FR_BECN_BIT, "BECN" },
76  { FR_FECN_BIT, "FECN" },
77  { FR_SDLC_BIT, "sdlcore" },
78  { 0, NULL }
79 };
80 
81 /* FRF.15 / FRF.16 */
82 #define MFR_B_BIT 0x80
83 #define MFR_E_BIT 0x40
84 #define MFR_C_BIT 0x20
85 #define MFR_BEC_MASK (MFR_B_BIT | MFR_E_BIT | MFR_C_BIT)
86 #define MFR_CTRL_FRAME (MFR_B_BIT | MFR_E_BIT | MFR_C_BIT)
87 #define MFR_FRAG_FRAME (MFR_B_BIT | MFR_E_BIT )
88 
89 static const struct tok frf_flag_values[] = {
90  { MFR_B_BIT, "Begin" },
91  { MFR_E_BIT, "End" },
92  { MFR_C_BIT, "Control" },
93  { 0, NULL }
94 };
95 
96 /* Finds out Q.922 address length, DLCI and flags. Returns 1 on success,
97  * 0 on invalid address, -1 on truncated packet
98  * save the flags dep. on address length
99  */
101  const u_char *p, u_int *dlci,
102  u_int *addr_len, uint32_t *flags, u_int length)
103 {
104  if (!ND_TTEST_1(p) || length < 1)
105  return -1;
106  if ((GET_U_1(p) & FR_EA_BIT))
107  return 0;
108 
109  if (!ND_TTEST_1(p + 1) || length < 2)
110  return -1;
111  *addr_len = 2;
112  *dlci = ((GET_U_1(p) & 0xFC) << 2) | ((GET_U_1(p + 1) & 0xF0) >> 4);
113 
114  *flags = ((GET_U_1(p) & 0x02) << 24) | /* CR flag */
115  ((GET_U_1(p + 1) & 0x0e) << 16); /* FECN,BECN,DE flags */
116 
117  if (GET_U_1(p + 1) & FR_EA_BIT)
118  return 1; /* 2-byte Q.922 address */
119 
120  p += 2;
121  length -= 2;
122  if (!ND_TTEST_1(p) || length < 1)
123  return -1;
124  (*addr_len)++; /* 3- or 4-byte Q.922 address */
125  if ((GET_U_1(p) & FR_EA_BIT) == 0) {
126  *dlci = (*dlci << 7) | (GET_U_1(p) >> 1);
127  (*addr_len)++; /* 4-byte Q.922 address */
128  p++;
129  length--;
130  }
131 
132  if (!ND_TTEST_1(p) || length < 1)
133  return -1;
134  if ((GET_U_1(p) & FR_EA_BIT) == 0)
135  return 0; /* more than 4 bytes of Q.922 address? */
136 
137  *flags = *flags | (GET_U_1(p) & 0x02); /* SDLC flag */
138 
139  *dlci = (*dlci << 6) | (GET_U_1(p) >> 2);
140 
141  return 1;
142 }
143 
144 const char *
145 q922_string(netdissect_options *ndo, const u_char *p, u_int length)
146 {
147 
148  static u_int dlci, addr_len;
149  static uint32_t flags;
150  static char buffer[sizeof("parse_q922_header() returned XXXXXXXXXXX")];
151  int ret;
152  memset(buffer, 0, sizeof(buffer));
153 
154  ret = parse_q922_header(ndo, p, &dlci, &addr_len, &flags, length);
155  if (ret == 1) {
156  snprintf(buffer, sizeof(buffer), "DLCI %u", dlci);
157  return buffer;
158  } else if (ret == 0) {
159  return "<Invalid DLCI>";
160  } else if (ret == -1) {
161  return "<Truncated>";
162  } else {
163  snprintf(buffer, sizeof(buffer), "parse_q922_header() returned %d", ret);
164  return buffer;
165  }
166 }
167 
168 
169 /* Frame Relay packet structure, with flags and CRC removed
170 
171  +---------------------------+
172  | Q.922 Address* |
173  +-- --+
174  | |
175  +---------------------------+
176  | Control (UI = 0x03) |
177  +---------------------------+
178  | Optional Pad (0x00) |
179  +---------------------------+
180  | NLPID |
181  +---------------------------+
182  | . |
183  | . |
184  | . |
185  | Data |
186  | . |
187  | . |
188  +---------------------------+
189 
190  * Q.922 addresses, as presently defined, are two octets and
191  contain a 10-bit DLCI. In some networks Q.922 addresses
192  may optionally be increased to three or four octets.
193 */
194 
195 static void
196 fr_hdr_print(netdissect_options *ndo, int length, u_int addr_len,
197  u_int dlci, uint32_t flags, uint16_t nlpid)
198 {
199  if (ndo->ndo_qflag) {
200  ND_PRINT("Q.922, DLCI %u, length %u: ",
201  dlci,
202  length);
203  } else {
204  if (nlpid <= 0xff) /* if its smaller than 256 then its a NLPID */
205  ND_PRINT("Q.922, hdr-len %u, DLCI %u, Flags [%s], NLPID %s (0x%02x), length %u: ",
206  addr_len,
207  dlci,
208  bittok2str(fr_header_flag_values, "none", flags),
209  tok2str(nlpid_values,"unknown", nlpid),
210  nlpid,
211  length);
212  else /* must be an ethertype */
213  ND_PRINT("Q.922, hdr-len %u, DLCI %u, Flags [%s], cisco-ethertype %s (0x%04x), length %u: ",
214  addr_len,
215  dlci,
216  bittok2str(fr_header_flag_values, "none", flags),
217  tok2str(ethertype_values, "unknown", nlpid),
218  nlpid,
219  length);
220  }
221 }
222 
223 /* Frame Relay */
224 void
226  const struct pcap_pkthdr *h, const u_char *p)
227 {
228  u_int length = h->len;
229  u_int caplen = h->caplen;
230 
231  ndo->ndo_protocol = "fr";
232  if (caplen < 4) { /* minimum frame header length */
233  nd_print_trunc(ndo);
234  ndo->ndo_ll_hdr_len += caplen;
235  return;
236  }
237 
238  ndo->ndo_ll_hdr_len += fr_print(ndo, p, length);
239 }
240 
241 u_int
243  const u_char *p, u_int length)
244 {
245  int ret;
246  uint16_t extracted_ethertype;
247  u_int dlci;
248  u_int addr_len;
249  uint16_t nlpid;
250  u_int hdr_len;
251  uint32_t flags;
252 
253  ndo->ndo_protocol = "fr";
254  ret = parse_q922_header(ndo, p, &dlci, &addr_len, &flags, length);
255  if (ret == -1)
256  goto trunc;
257  if (ret == 0) {
258  ND_PRINT("Q.922, invalid address");
259  return 0;
260  }
261 
262  ND_TCHECK_1(p + addr_len);
263  if (length < addr_len + 1)
264  goto trunc;
265 
266  if (GET_U_1(p + addr_len) != LLC_UI && dlci != 0) {
267  /*
268  * Let's figure out if we have Cisco-style encapsulation,
269  * with an Ethernet type (Cisco HDLC type?) following the
270  * address.
271  */
272  if (!ND_TTEST_2(p + addr_len) || length < addr_len + 2) {
273  /* no Ethertype */
274  ND_PRINT("UI %02x! ", GET_U_1(p + addr_len));
275  } else {
276  extracted_ethertype = GET_BE_U_2(p + addr_len);
277 
278  if (ndo->ndo_eflag)
279  fr_hdr_print(ndo, length, addr_len, dlci,
280  flags, extracted_ethertype);
281 
282  if (ethertype_print(ndo, extracted_ethertype,
283  p+addr_len+ETHERTYPE_LEN,
284  length-addr_len-ETHERTYPE_LEN,
286  NULL, NULL) == 0)
287  /* ether_type not known, probably it wasn't one */
288  ND_PRINT("UI %02x! ", GET_U_1(p + addr_len));
289  else
290  return addr_len + 2;
291  }
292  }
293 
294  ND_TCHECK_1(p + addr_len + 1);
295  if (length < addr_len + 2)
296  goto trunc;
297 
298  if (GET_U_1(p + addr_len + 1) == 0) {
299  /*
300  * Assume a pad byte after the control (UI) byte.
301  * A pad byte should only be used with 3-byte Q.922.
302  */
303  if (addr_len != 3)
304  ND_PRINT("Pad! ");
305  hdr_len = addr_len + 1 /* UI */ + 1 /* pad */ + 1 /* NLPID */;
306  } else {
307  /*
308  * Not a pad byte.
309  * A pad byte should be used with 3-byte Q.922.
310  */
311  if (addr_len == 3)
312  ND_PRINT("No pad! ");
313  hdr_len = addr_len + 1 /* UI */ + 1 /* NLPID */;
314  }
315 
316  ND_TCHECK_1(p + hdr_len - 1);
317  if (length < hdr_len)
318  goto trunc;
319  nlpid = GET_U_1(p + hdr_len - 1);
320 
321  if (ndo->ndo_eflag)
322  fr_hdr_print(ndo, length, addr_len, dlci, flags, nlpid);
323  p += hdr_len;
324  length -= hdr_len;
325 
326  switch (nlpid) {
327  case NLPID_IP:
328  ip_print(ndo, p, length);
329  break;
330 
331  case NLPID_IP6:
332  ip6_print(ndo, p, length);
333  break;
334 
335  case NLPID_CLNP:
336  case NLPID_ESIS:
337  case NLPID_ISIS:
338  isoclns_print(ndo, p - 1, length + 1); /* OSI printers need the NLPID field */
339  break;
340 
341  case NLPID_SNAP:
342  if (snap_print(ndo, p, length, ND_BYTES_AVAILABLE_AFTER(p), NULL, NULL, 0) == 0) {
343  /* ether_type not known, print raw packet */
344  if (!ndo->ndo_eflag)
345  fr_hdr_print(ndo, length + hdr_len, hdr_len,
346  dlci, flags, nlpid);
347  if (!ndo->ndo_suppress_default_print)
348  ND_DEFAULTPRINT(p - hdr_len, length + hdr_len);
349  }
350  break;
351 
352  case NLPID_Q933:
353  q933_print(ndo, p, length);
354  break;
355 
356  case NLPID_MFR:
357  frf15_print(ndo, p, length);
358  break;
359 
360  case NLPID_PPP:
361  ppp_print(ndo, p, length);
362  break;
363 
364  default:
365  if (!ndo->ndo_eflag)
366  fr_hdr_print(ndo, length + hdr_len, addr_len,
367  dlci, flags, nlpid);
368  if (!ndo->ndo_xflag)
369  ND_DEFAULTPRINT(p, length);
370  }
371 
372  return hdr_len;
373 
374 trunc:
375  nd_print_trunc(ndo);
376  return 0;
377 
378 }
379 
380 /* Multi Link Frame Relay (FRF.16) */
381 void
383  const struct pcap_pkthdr *h, const u_char *p)
384 {
385  u_int length = h->len;
386  u_int caplen = h->caplen;
387 
388  ndo->ndo_protocol = "mfr";
389  if (caplen < 2) { /* minimum frame header length */
390  nd_print_trunc(ndo);
391  ndo->ndo_ll_hdr_len += caplen;
392  return;
393  }
394 
395  ndo->ndo_ll_hdr_len += mfr_print(ndo, p, length);
396 }
397 
398 
399 #define MFR_CTRL_MSG_ADD_LINK 1
400 #define MFR_CTRL_MSG_ADD_LINK_ACK 2
401 #define MFR_CTRL_MSG_ADD_LINK_REJ 3
402 #define MFR_CTRL_MSG_HELLO 4
403 #define MFR_CTRL_MSG_HELLO_ACK 5
404 #define MFR_CTRL_MSG_REMOVE_LINK 6
405 #define MFR_CTRL_MSG_REMOVE_LINK_ACK 7
406 
407 static const struct tok mfr_ctrl_msg_values[] = {
408  { MFR_CTRL_MSG_ADD_LINK, "Add Link" },
409  { MFR_CTRL_MSG_ADD_LINK_ACK, "Add Link ACK" },
410  { MFR_CTRL_MSG_ADD_LINK_REJ, "Add Link Reject" },
411  { MFR_CTRL_MSG_HELLO, "Hello" },
412  { MFR_CTRL_MSG_HELLO_ACK, "Hello ACK" },
413  { MFR_CTRL_MSG_REMOVE_LINK, "Remove Link" },
414  { MFR_CTRL_MSG_REMOVE_LINK_ACK, "Remove Link ACK" },
415  { 0, NULL }
416 };
417 
418 #define MFR_CTRL_IE_BUNDLE_ID 1
419 #define MFR_CTRL_IE_LINK_ID 2
420 #define MFR_CTRL_IE_MAGIC_NUM 3
421 #define MFR_CTRL_IE_TIMESTAMP 5
422 #define MFR_CTRL_IE_VENDOR_EXT 6
423 #define MFR_CTRL_IE_CAUSE 7
424 
425 static const struct tok mfr_ctrl_ie_values[] = {
426  { MFR_CTRL_IE_BUNDLE_ID, "Bundle ID"},
427  { MFR_CTRL_IE_LINK_ID, "Link ID"},
428  { MFR_CTRL_IE_MAGIC_NUM, "Magic Number"},
429  { MFR_CTRL_IE_TIMESTAMP, "Timestamp"},
430  { MFR_CTRL_IE_VENDOR_EXT, "Vendor Extension"},
431  { MFR_CTRL_IE_CAUSE, "Cause"},
432  { 0, NULL }
433 };
434 
435 #define MFR_ID_STRING_MAXLEN 50
436 
438  uint8_t ie_type;
439  uint8_t ie_len;
440 };
441 
442 u_int
444  const u_char *p, u_int length)
445 {
446  u_int tlen,idx,hdr_len = 0;
447  uint16_t sequence_num;
448  uint8_t ie_type,ie_len;
449  const uint8_t *tptr;
450 
451 
452 /*
453  * FRF.16 Link Integrity Control Frame
454  *
455  * 7 6 5 4 3 2 1 0
456  * +----+----+----+----+----+----+----+----+
457  * | B | E | C=1| 0 0 0 0 | EA |
458  * +----+----+----+----+----+----+----+----+
459  * | 0 0 0 0 0 0 0 0 |
460  * +----+----+----+----+----+----+----+----+
461  * | message type |
462  * +----+----+----+----+----+----+----+----+
463  */
464 
465  ndo->ndo_protocol = "mfr";
466 
467  if (length < 4) { /* minimum frame header length */
468  ND_PRINT("[length %u < 4]", length);
469  nd_print_invalid(ndo);
470  return length;
471  }
472  ND_TCHECK_4(p);
473 
474  if ((GET_U_1(p) & MFR_BEC_MASK) == MFR_CTRL_FRAME && GET_U_1(p + 1) == 0) {
475  ND_PRINT("FRF.16 Control, Flags [%s], %s, length %u",
477  tok2str(mfr_ctrl_msg_values,"Unknown Message (0x%02x)",GET_U_1(p + 2)),
478  length);
479  tptr = p + 3;
480  tlen = length -3;
481  hdr_len = 3;
482 
483  if (!ndo->ndo_vflag)
484  return hdr_len;
485 
486  while (tlen>sizeof(struct ie_tlv_header_t)) {
487  ND_TCHECK_LEN(tptr, sizeof(struct ie_tlv_header_t));
488  ie_type=GET_U_1(tptr);
489  ie_len=GET_U_1(tptr + 1);
490 
491  ND_PRINT("\n\tIE %s (%u), length %u: ",
492  tok2str(mfr_ctrl_ie_values,"Unknown",ie_type),
493  ie_type,
494  ie_len);
495 
496  /* infinite loop check */
497  if (ie_type == 0 || ie_len <= sizeof(struct ie_tlv_header_t))
498  return hdr_len;
499 
500  ND_TCHECK_LEN(tptr, ie_len);
501  tptr+=sizeof(struct ie_tlv_header_t);
502  /* tlv len includes header */
503  ie_len-=sizeof(struct ie_tlv_header_t);
504  tlen-=sizeof(struct ie_tlv_header_t);
505 
506  switch (ie_type) {
507 
509  /* FRF.16.1 Section 3.4.3 Magic Number Information Element */
510  if (ie_len != 4) {
511  ND_PRINT("[IE data length %d != 4]", ie_len);
512  nd_print_invalid(ndo);
513  break;
514  }
515  ND_PRINT("0x%08x", GET_BE_U_4(tptr));
516  break;
517 
518  case MFR_CTRL_IE_BUNDLE_ID: /* same message format */
519  case MFR_CTRL_IE_LINK_ID:
520  for (idx = 0; idx < ie_len && idx < MFR_ID_STRING_MAXLEN; idx++) {
521  if (GET_U_1(tptr + idx) != 0) /* don't print null termination */
522  fn_print_char(ndo, GET_U_1(tptr + idx));
523  else
524  break;
525  }
526  break;
527 
529  if (ie_len == sizeof(struct timeval)) {
530  ts_print(ndo, (const struct timeval *)tptr);
531  break;
532  }
533  /* fall through and hexdump if no unix timestamp */
535 
536  /*
537  * FIXME those are the defined IEs that lack a decoder
538  * you are welcome to contribute code ;-)
539  */
540 
542  case MFR_CTRL_IE_CAUSE:
543 
544  default:
545  if (ndo->ndo_vflag <= 1)
546  print_unknown_data(ndo, tptr, "\n\t ", ie_len);
547  break;
548  }
549 
550  /* do we want to see a hexdump of the IE ? */
551  if (ndo->ndo_vflag > 1 )
552  print_unknown_data(ndo, tptr, "\n\t ", ie_len);
553 
554  tlen-=ie_len;
555  tptr+=ie_len;
556  }
557  return hdr_len;
558  }
559 /*
560  * FRF.16 Fragmentation Frame
561  *
562  * 7 6 5 4 3 2 1 0
563  * +----+----+----+----+----+----+----+----+
564  * | B | E | C=0|seq. (high 4 bits) | EA |
565  * +----+----+----+----+----+----+----+----+
566  * | sequence (low 8 bits) |
567  * +----+----+----+----+----+----+----+----+
568  * | DLCI (6 bits) | CR | EA |
569  * +----+----+----+----+----+----+----+----+
570  * | DLCI (4 bits) |FECN|BECN| DE | EA |
571  * +----+----+----+----+----+----+----+----+
572  */
573 
574  sequence_num = (GET_U_1(p)&0x1e)<<7 | GET_U_1(p + 1);
575  /* whole packet or first fragment ? */
576  if ((GET_U_1(p) & MFR_BEC_MASK) == MFR_FRAG_FRAME ||
577  (GET_U_1(p) & MFR_BEC_MASK) == MFR_B_BIT) {
578  ND_PRINT("FRF.16 Frag, seq %u, Flags [%s], ",
579  sequence_num,
581  hdr_len = 2;
582  fr_print(ndo, p+hdr_len,length-hdr_len);
583  return hdr_len;
584  }
585 
586  /* must be a middle or the last fragment */
587  ND_PRINT("FRF.16 Frag, seq %u, Flags [%s]",
588  sequence_num,
590  print_unknown_data(ndo, p, "\n\t", length);
591 
592  return hdr_len;
593 
594 trunc:
595  nd_print_trunc(ndo);
596  return length;
597 }
598 
599 /* an NLPID of 0xb1 indicates a 2-byte
600  * FRF.15 header
601  *
602  * 7 6 5 4 3 2 1 0
603  * +----+----+----+----+----+----+----+----+
604  * ~ Q.922 header ~
605  * +----+----+----+----+----+----+----+----+
606  * | NLPID (8 bits) | NLPID=0xb1
607  * +----+----+----+----+----+----+----+----+
608  * | B | E | C |seq. (high 4 bits) | R |
609  * +----+----+----+----+----+----+----+----+
610  * | sequence (low 8 bits) |
611  * +----+----+----+----+----+----+----+----+
612  */
613 
614 #define FR_FRF15_FRAGTYPE 0x01
615 
616 static void
618  const u_char *p, u_int length)
619 {
620  uint16_t sequence_num, flags;
621 
622  if (length < 2)
623  goto trunc;
624 
625  flags = GET_U_1(p)&MFR_BEC_MASK;
626  sequence_num = (GET_U_1(p)&0x1e)<<7 | GET_U_1(p + 1);
627 
628  ND_PRINT("FRF.15, seq 0x%03x, Flags [%s],%s Fragmentation, length %u",
629  sequence_num,
630  bittok2str(frf_flag_values,"none",flags),
631  GET_U_1(p)&FR_FRF15_FRAGTYPE ? "Interface" : "End-to-End",
632  length);
633 
634 /* TODO:
635  * depending on all permutations of the B, E and C bit
636  * dig as deep as we can - e.g. on the first (B) fragment
637  * there is enough payload to print the IP header
638  * on non (B) fragments it depends if the fragmentation
639  * model is end-to-end or interface based whether we want to print
640  * another Q.922 header
641  */
642  return;
643 
644 trunc:
645  nd_print_trunc(ndo);
646 }
647 
648 /*
649  * Q.933 decoding portion for framerelay specific.
650  */
651 
652 /* Q.933 packet format
653  Format of Other Protocols
654  using Q.933 NLPID
655  +-------------------------------+
656  | Q.922 Address |
657  +---------------+---------------+
658  |Control 0x03 | NLPID 0x08 |
659  +---------------+---------------+
660  | L2 Protocol ID |
661  | octet 1 | octet 2 |
662  +-------------------------------+
663  | L3 Protocol ID |
664  | octet 2 | octet 2 |
665  +-------------------------------+
666  | Protocol Data |
667  +-------------------------------+
668  | FCS |
669  +-------------------------------+
670  */
671 
672 /* L2 (Octet 1)- Call Reference Usually is 0x0 */
673 
674 /*
675  * L2 (Octet 2)- Message Types definition 1 byte long.
676  */
677 /* Call Establish */
678 #define MSG_TYPE_ESC_TO_NATIONAL 0x00
679 #define MSG_TYPE_ALERT 0x01
680 #define MSG_TYPE_CALL_PROCEEDING 0x02
681 #define MSG_TYPE_CONNECT 0x07
682 #define MSG_TYPE_CONNECT_ACK 0x0F
683 #define MSG_TYPE_PROGRESS 0x03
684 #define MSG_TYPE_SETUP 0x05
685 /* Call Clear */
686 #define MSG_TYPE_DISCONNECT 0x45
687 #define MSG_TYPE_RELEASE 0x4D
688 #define MSG_TYPE_RELEASE_COMPLETE 0x5A
689 #define MSG_TYPE_RESTART 0x46
690 #define MSG_TYPE_RESTART_ACK 0x4E
691 /* Status */
692 #define MSG_TYPE_STATUS 0x7D
693 #define MSG_TYPE_STATUS_ENQ 0x75
694 
695 static const struct tok fr_q933_msg_values[] = {
696  { MSG_TYPE_ESC_TO_NATIONAL, "ESC to National" },
697  { MSG_TYPE_ALERT, "Alert" },
698  { MSG_TYPE_CALL_PROCEEDING, "Call proceeding" },
699  { MSG_TYPE_CONNECT, "Connect" },
700  { MSG_TYPE_CONNECT_ACK, "Connect ACK" },
701  { MSG_TYPE_PROGRESS, "Progress" },
702  { MSG_TYPE_SETUP, "Setup" },
703  { MSG_TYPE_DISCONNECT, "Disconnect" },
704  { MSG_TYPE_RELEASE, "Release" },
705  { MSG_TYPE_RELEASE_COMPLETE, "Release Complete" },
706  { MSG_TYPE_RESTART, "Restart" },
707  { MSG_TYPE_RESTART_ACK, "Restart ACK" },
708  { MSG_TYPE_STATUS, "Status Reply" },
709  { MSG_TYPE_STATUS_ENQ, "Status Enquiry" },
710  { 0, NULL }
711 };
712 
713 #define IE_IS_SINGLE_OCTET(iecode) ((iecode) & 0x80)
714 #define IE_IS_SHIFT(iecode) (((iecode) & 0xF0) == 0x90)
715 #define IE_SHIFT_IS_NON_LOCKING(iecode) ((iecode) & 0x08)
716 #define IE_SHIFT_IS_LOCKING(iecode) (!(IE_SHIFT_IS_NON_LOCKING(iecode)))
717 #define IE_SHIFT_CODESET(iecode) ((iecode) & 0x07)
718 
719 #define FR_LMI_ANSI_REPORT_TYPE_IE 0x01
720 #define FR_LMI_ANSI_LINK_VERIFY_IE_91 0x19 /* details? */
721 #define FR_LMI_ANSI_LINK_VERIFY_IE 0x03
722 #define FR_LMI_ANSI_PVC_STATUS_IE 0x07
723 
724 #define FR_LMI_CCITT_REPORT_TYPE_IE 0x51
725 #define FR_LMI_CCITT_LINK_VERIFY_IE 0x53
726 #define FR_LMI_CCITT_PVC_STATUS_IE 0x57
727 
728 static const struct tok fr_q933_ie_values_codeset_0_5[] = {
729  { FR_LMI_ANSI_REPORT_TYPE_IE, "ANSI Report Type" },
730  { FR_LMI_ANSI_LINK_VERIFY_IE_91, "ANSI Link Verify" },
731  { FR_LMI_ANSI_LINK_VERIFY_IE, "ANSI Link Verify" },
732  { FR_LMI_ANSI_PVC_STATUS_IE, "ANSI PVC Status" },
733  { FR_LMI_CCITT_REPORT_TYPE_IE, "CCITT Report Type" },
734  { FR_LMI_CCITT_LINK_VERIFY_IE, "CCITT Link Verify" },
735  { FR_LMI_CCITT_PVC_STATUS_IE, "CCITT PVC Status" },
736  { 0, NULL }
737 };
738 
739 #define FR_LMI_REPORT_TYPE_IE_FULL_STATUS 0
740 #define FR_LMI_REPORT_TYPE_IE_LINK_VERIFY 1
741 #define FR_LMI_REPORT_TYPE_IE_ASYNC_PVC 2
742 
743 static const struct tok fr_lmi_report_type_ie_values[] = {
744  { FR_LMI_REPORT_TYPE_IE_FULL_STATUS, "Full Status" },
745  { FR_LMI_REPORT_TYPE_IE_LINK_VERIFY, "Link verify" },
746  { FR_LMI_REPORT_TYPE_IE_ASYNC_PVC, "Async PVC Status" },
747  { 0, NULL }
748 };
749 
750 /* array of 16 codesets - currently we only support codepage 0 and 5 */
751 static const struct tok *fr_q933_ie_codesets[] = {
753  NULL,
754  NULL,
755  NULL,
756  NULL,
758  NULL,
759  NULL,
760  NULL,
761  NULL,
762  NULL,
763  NULL,
764  NULL,
765  NULL,
766  NULL,
767  NULL
768 };
769 
770 static int fr_q933_print_ie_codeset_0_5(netdissect_options *ndo, u_int iecode,
771  u_int ielength, const u_char *p);
772 
773 typedef int (*codeset_pr_func_t)(netdissect_options *, u_int iecode,
774  u_int ielength, const u_char *p);
775 
776 /* array of 16 codesets - currently we only support codepage 0 and 5 */
779  NULL,
780  NULL,
781  NULL,
782  NULL,
784  NULL,
785  NULL,
786  NULL,
787  NULL,
788  NULL,
789  NULL,
790  NULL,
791  NULL,
792  NULL,
793  NULL
794 };
795 
796 /*
797  * ITU-T Q.933.
798  *
799  * p points to octet 2, the octet containing the length of the
800  * call reference value, so p[n] is octet n+2 ("octet X" is as
801  * used in Q.931/Q.933).
802  *
803  * XXX - actually used both for Q.931 and Q.933.
804  */
805 void
807  const u_char *p, u_int length)
808 {
809  u_int olen;
810  u_int call_ref_length, i;
811  uint8_t call_ref[15]; /* maximum length - length field is 4 bits */
812  u_int msgtype;
813  u_int iecode;
814  u_int ielength;
815  u_int codeset = 0;
816  u_int is_ansi = 0;
817  u_int ie_is_known;
818  u_int non_locking_shift;
819  u_int unshift_codeset;
820 
821  ndo->ndo_protocol = "q.933";
822  ND_PRINT("%s", ndo->ndo_eflag ? "" : "Q.933");
823 
824  if (length == 0 || !ND_TTEST_1(p)) {
825  if (!ndo->ndo_eflag)
826  ND_PRINT(", ");
827  ND_PRINT("length %u", length);
828  goto trunc;
829  }
830 
831  /*
832  * Get the length of the call reference value.
833  */
834  olen = length; /* preserve the original length for display */
835  call_ref_length = GET_U_1(p) & 0x0f;
836  p++;
837  length--;
838 
839  /*
840  * Get the call reference value.
841  */
842  for (i = 0; i < call_ref_length; i++) {
843  if (length == 0 || !ND_TTEST_1(p)) {
844  if (!ndo->ndo_eflag)
845  ND_PRINT(", ");
846  ND_PRINT("length %u", olen);
847  goto trunc;
848  }
849  call_ref[i] = GET_U_1(p);
850  p++;
851  length--;
852  }
853 
854  /*
855  * Get the message type.
856  */
857  if (length == 0 || !ND_TTEST_1(p)) {
858  if (!ndo->ndo_eflag)
859  ND_PRINT(", ");
860  ND_PRINT("length %u", olen);
861  goto trunc;
862  }
863  msgtype = GET_U_1(p);
864  p++;
865  length--;
866 
867  /*
868  * Peek ahead to see if we start with a shift.
869  */
870  non_locking_shift = 0;
871  unshift_codeset = codeset;
872  if (length != 0) {
873  if (!ND_TTEST_1(p)) {
874  if (!ndo->ndo_eflag)
875  ND_PRINT(", ");
876  ND_PRINT("length %u", olen);
877  goto trunc;
878  }
879  iecode = GET_U_1(p);
880  if (IE_IS_SHIFT(iecode)) {
881  /*
882  * It's a shift. Skip over it.
883  */
884  p++;
885  length--;
886 
887  /*
888  * Get the codeset.
889  */
890  codeset = IE_SHIFT_CODESET(iecode);
891 
892  /*
893  * If it's a locking shift to codeset 5,
894  * mark this as ANSI. (XXX - 5 is actually
895  * for national variants in general, not
896  * the US variant in particular, but maybe
897  * this is more American exceptionalism. :-))
898  */
899  if (IE_SHIFT_IS_LOCKING(iecode)) {
900  /*
901  * It's a locking shift.
902  */
903  if (codeset == 5) {
904  /*
905  * It's a locking shift to
906  * codeset 5, so this is
907  * T1.617 Annex D.
908  */
909  is_ansi = 1;
910  }
911  } else {
912  /*
913  * It's a non-locking shift.
914  * Remember the current codeset, so we
915  * can revert to it after the next IE.
916  */
917  non_locking_shift = 1;
918  unshift_codeset = 0;
919  }
920  }
921  }
922 
923  /* printing out header part */
924  if (!ndo->ndo_eflag)
925  ND_PRINT(", ");
926  ND_PRINT("%s, codeset %u", is_ansi ? "ANSI" : "CCITT", codeset);
927 
928  if (call_ref_length != 0) {
929  if (call_ref_length > 1 || GET_U_1(p) != 0) {
930  /*
931  * Not a dummy call reference.
932  */
933  ND_PRINT(", Call Ref: 0x");
934  for (i = 0; i < call_ref_length; i++)
935  ND_PRINT("%02x", call_ref[i]);
936  }
937  }
938  if (ndo->ndo_vflag) {
939  ND_PRINT(", %s (0x%02x), length %u",
941  "unknown message", msgtype),
942  msgtype,
943  olen);
944  } else {
945  ND_PRINT(", %s",
947  "unknown message 0x%02x", msgtype));
948  }
949 
950  /* Loop through the rest of the IEs */
951  while (length != 0) {
952  /*
953  * What's the state of any non-locking shifts?
954  */
955  if (non_locking_shift == 1) {
956  /*
957  * There's a non-locking shift in effect for
958  * this IE. Count it, so we reset the codeset
959  * before the next IE.
960  */
961  non_locking_shift = 2;
962  } else if (non_locking_shift == 2) {
963  /*
964  * Unshift.
965  */
966  codeset = unshift_codeset;
967  non_locking_shift = 0;
968  }
969 
970  /*
971  * Get the first octet of the IE.
972  */
973  if (!ND_TTEST_1(p)) {
974  if (!ndo->ndo_vflag) {
975  ND_PRINT(", length %u", olen);
976  }
977  goto trunc;
978  }
979  iecode = GET_U_1(p);
980  p++;
981  length--;
982 
983  /* Single-octet IE? */
984  if (IE_IS_SINGLE_OCTET(iecode)) {
985  /*
986  * Yes. Is it a shift?
987  */
988  if (IE_IS_SHIFT(iecode)) {
989  /*
990  * Yes. Is it locking?
991  */
992  if (IE_SHIFT_IS_LOCKING(iecode)) {
993  /*
994  * Yes.
995  */
996  non_locking_shift = 0;
997  } else {
998  /*
999  * No. Remember the current
1000  * codeset, so we can revert
1001  * to it after the next IE.
1002  */
1003  non_locking_shift = 1;
1004  unshift_codeset = codeset;
1005  }
1006 
1007  /*
1008  * Get the codeset.
1009  */
1010  codeset = IE_SHIFT_CODESET(iecode);
1011  }
1012  } else {
1013  /*
1014  * No. Get the IE length.
1015  */
1016  if (length == 0 || !ND_TTEST_1(p)) {
1017  if (!ndo->ndo_vflag) {
1018  ND_PRINT(", length %u", olen);
1019  }
1020  goto trunc;
1021  }
1022  ielength = GET_U_1(p);
1023  p++;
1024  length--;
1025 
1026  /* lets do the full IE parsing only in verbose mode
1027  * however some IEs (DLCI Status, Link Verify)
1028  * are also interesting in non-verbose mode */
1029  if (ndo->ndo_vflag) {
1030  ND_PRINT("\n\t%s IE (0x%02x), length %u: ",
1031  tok2str(fr_q933_ie_codesets[codeset],
1032  "unknown", iecode),
1033  iecode,
1034  ielength);
1035  }
1036 
1037  /* sanity checks */
1038  if (iecode == 0 || ielength == 0) {
1039  return;
1040  }
1041  if (length < ielength || !ND_TTEST_LEN(p, ielength)) {
1042  if (!ndo->ndo_vflag) {
1043  ND_PRINT(", length %u", olen);
1044  }
1045  goto trunc;
1046  }
1047 
1048  ie_is_known = 0;
1049  if (fr_q933_print_ie_codeset[codeset] != NULL) {
1050  ie_is_known = fr_q933_print_ie_codeset[codeset](ndo, iecode, ielength, p);
1051  }
1052 
1053  if (ie_is_known) {
1054  /*
1055  * Known IE; do we want to see a hexdump
1056  * of it?
1057  */
1058  if (ndo->ndo_vflag > 1) {
1059  /* Yes. */
1060  print_unknown_data(ndo, p, "\n\t ", ielength);
1061  }
1062  } else {
1063  /*
1064  * Unknown IE; if we're printing verbosely,
1065  * print its content in hex.
1066  */
1067  if (ndo->ndo_vflag >= 1) {
1068  print_unknown_data(ndo, p, "\n\t", ielength);
1069  }
1070  }
1071 
1072  length -= ielength;
1073  p += ielength;
1074  }
1075  }
1076  if (!ndo->ndo_vflag) {
1077  ND_PRINT(", length %u", olen);
1078  }
1079  return;
1080 
1081 trunc:
1082  nd_print_trunc(ndo);
1083 }
1084 
1085 static int
1087  u_int ielength, const u_char *p)
1088 {
1089  u_int dlci;
1090 
1091  switch (iecode) {
1092 
1093  case FR_LMI_ANSI_REPORT_TYPE_IE: /* fall through */
1095  if (ielength < 1) {
1096  if (!ndo->ndo_vflag) {
1097  ND_PRINT(", ");
1098  }
1099  ND_PRINT("Invalid REPORT TYPE IE");
1100  return 1;
1101  }
1102  if (ndo->ndo_vflag) {
1103  ND_PRINT("%s (%u)",
1105  GET_U_1(p));
1106  }
1107  return 1;
1108 
1109  case FR_LMI_ANSI_LINK_VERIFY_IE: /* fall through */
1112  if (!ndo->ndo_vflag) {
1113  ND_PRINT(", ");
1114  }
1115  if (ielength < 2) {
1116  ND_PRINT("Invalid LINK VERIFY IE");
1117  return 1;
1118  }
1119  ND_PRINT("TX Seq: %3d, RX Seq: %3d", GET_U_1(p), GET_U_1(p + 1));
1120  return 1;
1121 
1122  case FR_LMI_ANSI_PVC_STATUS_IE: /* fall through */
1124  if (!ndo->ndo_vflag) {
1125  ND_PRINT(", ");
1126  }
1127  /* now parse the DLCI information element. */
1128  if ((ielength < 3) ||
1129  (GET_U_1(p) & 0x80) ||
1130  ((ielength == 3) && !(GET_U_1(p + 1) & 0x80)) ||
1131  ((ielength == 4) &&
1132  ((GET_U_1(p + 1) & 0x80) || !(GET_U_1(p + 2) & 0x80))) ||
1133  ((ielength == 5) &&
1134  ((GET_U_1(p + 1) & 0x80) || (GET_U_1(p + 2) & 0x80) ||
1135  !(GET_U_1(p + 3) & 0x80))) ||
1136  (ielength > 5) ||
1137  !(GET_U_1(p + ielength - 1) & 0x80)) {
1138  ND_PRINT("Invalid DLCI in PVC STATUS IE");
1139  return 1;
1140  }
1141 
1142  dlci = ((GET_U_1(p) & 0x3F) << 4) | ((GET_U_1(p + 1) & 0x78) >> 3);
1143  if (ielength == 4) {
1144  dlci = (dlci << 6) | ((GET_U_1(p + 2) & 0x7E) >> 1);
1145  }
1146  else if (ielength == 5) {
1147  dlci = (dlci << 13) | (GET_U_1(p + 2) & 0x7F) | ((GET_U_1(p + 3) & 0x7E) >> 1);
1148  }
1149 
1150  ND_PRINT("DLCI %u: status %s%s", dlci,
1151  GET_U_1(p + ielength - 1) & 0x8 ? "New, " : "",
1152  GET_U_1(p + ielength - 1) & 0x2 ? "Active" : "Inactive");
1153  return 1;
1154  }
1155 
1156  return 0;
1157 }
const struct tok ethertype_values[]
Definition: print-ether.c:52
#define ETHERTYPE_LEN
Definition: ethertype.h:42
#define GET_BE_U_4(p)
Definition: extract.h:877
#define GET_BE_U_2(p)
Definition: extract.h:875
#define ND_TTEST_2(p)
Definition: extract.h:554
#define GET_U_1(p)
Definition: extract.h:872
#define ND_TCHECK_4(p)
Definition: extract.h:561
#define ND_TTEST_1(p)
Definition: extract.h:551
#define ND_TCHECK_1(p)
Definition: extract.h:552
#define LLC_UI
Definition: llc.h:36
#define ND_FALL_THROUGH
void ip6_print(netdissect_options *, const u_char *, u_int)
Definition: print-ip6.c:226
void fn_print_char(netdissect_options *, u_char)
Definition: util-print.c:70
int print_unknown_data(netdissect_options *, const u_char *, const char *, u_int)
Definition: util-print.c:441
#define ND_TCHECK_LEN(p, l)
Definition: netdissect.h:368
const char * tok2str(const struct tok *, const char *, u_int)
Definition: util-print.c:485
int ethertype_print(netdissect_options *, u_short, const u_char *, u_int, u_int, const struct lladdr_info *, const struct lladdr_info *)
Definition: print-ether.c:522
#define ND_TTEST_LEN(p, l)
Definition: netdissect.h:356
void isoclns_print(netdissect_options *, const u_char *, u_int)
char * bittok2str(const struct tok *, const char *, u_int)
Definition: util-print.c:558
void nd_print_invalid(netdissect_options *)
Definition: util-print.c:429
#define ND_DEFAULTPRINT(ap, length)
Definition: netdissect.h:386
void nd_print_trunc(netdissect_options *)
Definition: util-print.c:409
int snap_print(netdissect_options *, const u_char *, u_int, u_int, const struct lladdr_info *, const struct lladdr_info *, u_int)
Definition: print-llc.c:423
void ip_print(netdissect_options *, const u_char *, u_int)
Definition: print-ip.c:319
void ts_print(netdissect_options *, const struct timeval *)
Definition: util-print.c:277
#define ND_PRINT(...)
Definition: netdissect.h:385
u_int ppp_print(netdissect_options *, const u_char *, u_int)
Definition: print-ppp.c:1509
#define ND_BYTES_AVAILABLE_AFTER(p)
Definition: netdissect.h:383
const struct tok nlpid_values[]
Definition: nlpid.c:24
#define NLPID_IP6
Definition: nlpid.h:32
#define NLPID_ESIS
Definition: nlpid.h:23
#define NLPID_PPP
Definition: nlpid.h:30
#define NLPID_CLNP
Definition: nlpid.h:22
#define NLPID_MFR
Definition: nlpid.h:27
#define NLPID_IP
Definition: nlpid.h:29
#define NLPID_SNAP
Definition: nlpid.h:21
#define NLPID_Q933
Definition: nlpid.h:19
#define NLPID_ISIS
Definition: nlpid.h:24
int snprintf(char *, size_t, const char *,...)
#define FR_LMI_ANSI_LINK_VERIFY_IE
Definition: print-fr.c:721
#define MFR_CTRL_IE_VENDOR_EXT
Definition: print-fr.c:422
static const struct tok frf_flag_values[]
Definition: print-fr.c:89
#define FR_LMI_CCITT_LINK_VERIFY_IE
Definition: print-fr.c:725
#define MFR_CTRL_MSG_REMOVE_LINK
Definition: print-fr.c:404
#define MFR_C_BIT
Definition: print-fr.c:84
#define MSG_TYPE_CONNECT_ACK
Definition: print-fr.c:682
#define MSG_TYPE_ESC_TO_NATIONAL
Definition: print-fr.c:678
#define IE_IS_SHIFT(iecode)
Definition: print-fr.c:714
#define MSG_TYPE_ALERT
Definition: print-fr.c:679
#define MSG_TYPE_PROGRESS
Definition: print-fr.c:683
#define FR_EA_BIT
Definition: print-fr.c:63
#define MSG_TYPE_CALL_PROCEEDING
Definition: print-fr.c:680
#define MFR_BEC_MASK
Definition: print-fr.c:85
#define FR_CR_BIT
Definition: print-fr.c:65
#define MSG_TYPE_SETUP
Definition: print-fr.c:684
static int parse_q922_header(netdissect_options *ndo, const u_char *p, u_int *dlci, u_int *addr_len, uint32_t *flags, u_int length)
Definition: print-fr.c:100
#define MSG_TYPE_STATUS
Definition: print-fr.c:692
#define MSG_TYPE_STATUS_ENQ
Definition: print-fr.c:693
static const struct tok mfr_ctrl_msg_values[]
Definition: print-fr.c:407
#define FR_LMI_CCITT_REPORT_TYPE_IE
Definition: print-fr.c:724
#define FR_SDLC_BIT
Definition: print-fr.c:69
#define MFR_ID_STRING_MAXLEN
Definition: print-fr.c:435
#define MSG_TYPE_DISCONNECT
Definition: print-fr.c:686
static int fr_q933_print_ie_codeset_0_5(netdissect_options *ndo, u_int iecode, u_int ielength, const u_char *p)
Definition: print-fr.c:1086
#define IE_IS_SINGLE_OCTET(iecode)
Definition: print-fr.c:713
#define FR_LMI_REPORT_TYPE_IE_FULL_STATUS
Definition: print-fr.c:739
#define IE_SHIFT_CODESET(iecode)
Definition: print-fr.c:717
static const struct tok fr_header_flag_values[]
Definition: print-fr.c:72
#define MSG_TYPE_RELEASE_COMPLETE
Definition: print-fr.c:688
void mfr_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p)
Definition: print-fr.c:382
#define MFR_CTRL_MSG_HELLO_ACK
Definition: print-fr.c:403
#define MFR_CTRL_MSG_ADD_LINK
Definition: print-fr.c:399
static const struct tok * fr_q933_ie_codesets[]
Definition: print-fr.c:751
static const struct tok fr_lmi_report_type_ie_values[]
Definition: print-fr.c:743
static const codeset_pr_func_t fr_q933_print_ie_codeset[]
Definition: print-fr.c:777
#define MFR_CTRL_MSG_ADD_LINK_ACK
Definition: print-fr.c:400
#define FR_DE_BIT
Definition: print-fr.c:66
#define IE_SHIFT_IS_LOCKING(iecode)
Definition: print-fr.c:716
void q933_print(netdissect_options *ndo, const u_char *p, u_int length)
Definition: print-fr.c:806
#define MFR_FRAG_FRAME
Definition: print-fr.c:87
#define MSG_TYPE_CONNECT
Definition: print-fr.c:681
#define FR_LMI_ANSI_REPORT_TYPE_IE
Definition: print-fr.c:719
#define MFR_CTRL_IE_CAUSE
Definition: print-fr.c:423
static void frf15_print(netdissect_options *ndo, const u_char *, u_int)
Definition: print-fr.c:617
static const struct tok fr_q933_ie_values_codeset_0_5[]
Definition: print-fr.c:728
int(* codeset_pr_func_t)(netdissect_options *, u_int iecode, u_int ielength, const u_char *p)
Definition: print-fr.c:773
#define FR_LMI_REPORT_TYPE_IE_ASYNC_PVC
Definition: print-fr.c:741
#define MFR_CTRL_MSG_REMOVE_LINK_ACK
Definition: print-fr.c:405
#define FR_FRF15_FRAGTYPE
Definition: print-fr.c:614
#define MFR_CTRL_MSG_HELLO
Definition: print-fr.c:402
#define FR_LMI_REPORT_TYPE_IE_LINK_VERIFY
Definition: print-fr.c:740
#define FR_LMI_ANSI_LINK_VERIFY_IE_91
Definition: print-fr.c:720
#define MFR_CTRL_MSG_ADD_LINK_REJ
Definition: print-fr.c:401
#define MSG_TYPE_RESTART
Definition: print-fr.c:689
#define FR_LMI_CCITT_PVC_STATUS_IE
Definition: print-fr.c:726
#define MFR_CTRL_IE_MAGIC_NUM
Definition: print-fr.c:420
const char * q922_string(netdissect_options *ndo, const u_char *p, u_int length)
Definition: print-fr.c:145
#define MFR_CTRL_IE_LINK_ID
Definition: print-fr.c:419
#define FR_FECN_BIT
Definition: print-fr.c:68
static void fr_hdr_print(netdissect_options *ndo, int length, u_int addr_len, u_int dlci, uint32_t flags, uint16_t nlpid)
Definition: print-fr.c:196
#define MFR_B_BIT
Definition: print-fr.c:82
#define MFR_E_BIT
Definition: print-fr.c:83
#define FR_BECN_BIT
Definition: print-fr.c:67
static const struct tok fr_q933_msg_values[]
Definition: print-fr.c:695
static const struct tok mfr_ctrl_ie_values[]
Definition: print-fr.c:425
u_int mfr_print(netdissect_options *ndo, const u_char *p, u_int length)
Definition: print-fr.c:443
#define FR_LMI_ANSI_PVC_STATUS_IE
Definition: print-fr.c:722
#define MFR_CTRL_IE_TIMESTAMP
Definition: print-fr.c:421
void fr_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p)
Definition: print-fr.c:225
#define MFR_CTRL_FRAME
Definition: print-fr.c:86
#define MFR_CTRL_IE_BUNDLE_ID
Definition: print-fr.c:418
u_int fr_print(netdissect_options *ndo, const u_char *p, u_int length)
Definition: print-fr.c:242
#define MSG_TYPE_RELEASE
Definition: print-fr.c:687
#define MSG_TYPE_RESTART_ACK
Definition: print-fr.c:690
uint8_t ie_len
Definition: print-fr.c:439
uint8_t ie_type
Definition: print-fr.c:438
int ndo_suppress_default_print
Definition: netdissect.h:222
const char * ndo_protocol
Definition: netdissect.h:218