12949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*
22949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996
32949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *	The Regents of the University of California.  All rights reserved.
42949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *
52949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Redistribution and use in source and binary forms, with or without
62949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * modification, are permitted provided that: (1) source code distributions
72949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * retain the above copyright notice and this paragraph in its entirety, (2)
82949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * distributions including binary code include the above copyright notice and
92949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * this paragraph in its entirety in the documentation or other materials
102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * provided with the distribution, and (3) all advertising materials mentioning
112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * features or use of this software display the following acknowledgement:
122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * ``This product includes software developed by the University of California,
132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * the University nor the names of its contributors may be used to endorse
152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * or promote products derived from this software without specific prior
162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * written permission.
172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
22892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes#define NETDISSECT_REWORKED
232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#ifdef HAVE_CONFIG_H
242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "config.h"
252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#endif
262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <tcpdump-stdinc.h>
282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <stdio.h>
302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include <string.h>
312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "interface.h"
33892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes#include "addrtoname.h"
342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "ethertype.h"
35892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes#include "llc.h"
362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "nlpid.h"
372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "extract.h"
382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#include "oui.h"
392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
40892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesstatic void frf15_print(netdissect_options *ndo, const u_char *, u_int);
412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*
432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * the frame relay header has a variable length
442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *
452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * the EA bit determines if there is another byte
462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * in the header
472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *
482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * minimum header length is 2 bytes
492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * maximum header length is 4 bytes
502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *
512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *      7    6    5    4    3    2    1    0
522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    +----+----+----+----+----+----+----+----+
532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    |        DLCI (6 bits)        | CR | EA |
542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    +----+----+----+----+----+----+----+----+
552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    |   DLCI (4 bits)   |FECN|BECN| DE | EA |
562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    +----+----+----+----+----+----+----+----+
572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    |           DLCI (7 bits)          | EA |
582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    +----+----+----+----+----+----+----+----+
592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    |        DLCI (6 bits)        |SDLC| EA |
602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    +----+----+----+----+----+----+----+----+
612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define FR_EA_BIT	0x01
642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define FR_CR_BIT       0x02000000
662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define FR_DE_BIT	0x00020000
672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define FR_BECN_BIT	0x00040000
682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define FR_FECN_BIT	0x00080000
692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define FR_SDLC_BIT	0x00000002
702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
7253f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok fr_header_flag_values[] = {
732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { FR_CR_BIT, "C!" },
742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { FR_DE_BIT, "DE" },
752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { FR_BECN_BIT, "BECN" },
762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { FR_FECN_BIT, "FECN" },
772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { FR_SDLC_BIT, "sdlcore" },
782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0, NULL }
792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* FRF.15 / FRF.16 */
822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define MFR_B_BIT 0x80
832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define MFR_E_BIT 0x40
842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define MFR_C_BIT 0x20
852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define MFR_BEC_MASK    (MFR_B_BIT | MFR_E_BIT | MFR_C_BIT)
862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define MFR_CTRL_FRAME  (MFR_B_BIT | MFR_E_BIT | MFR_C_BIT)
872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define MFR_FRAG_FRAME  (MFR_B_BIT | MFR_E_BIT )
882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
8953f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok frf_flag_values[] = {
902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MFR_B_BIT, "Begin" },
912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MFR_E_BIT, "End" },
922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MFR_C_BIT, "Control" },
932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0, NULL }
942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
96892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes/* Finds out Q.922 address length, DLCI and flags. Returns 1 on success,
97892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes * 0 on invalid address, -1 on truncated packet
982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * save the flags dep. on address length
992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
100892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesstatic int parse_q922_addr(netdissect_options *ndo,
101892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                           const u_char *p, u_int *dlci,
102892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                           u_int *addr_len, uint8_t *flags, u_int length)
1032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
104892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	if (!ND_TTEST(p[0]) || length < 1)
1052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return -1;
106892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	if ((p[0] & FR_EA_BIT))
107892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		return 0;
1082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
109892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	if (!ND_TTEST(p[1]) || length < 2)
110892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		return -1;
1112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	*addr_len = 2;
1122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	*dlci = ((p[0] & 0xFC) << 2) | ((p[1] & 0xF0) >> 4);
1132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        flags[0] = p[0] & 0x02; /* populate the first flag fields */
1152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        flags[1] = p[1] & 0x0c;
1162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        flags[2] = 0;           /* clear the rest of the flags */
1172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        flags[3] = 0;
1182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (p[1] & FR_EA_BIT)
120892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		return 1;	/* 2-byte Q.922 address */
1212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	p += 2;
123892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	length -= 2;
124892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	if (!ND_TTEST(p[0]) || length < 1)
125892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		return -1;
1262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	(*addr_len)++;		/* 3- or 4-byte Q.922 address */
1272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if ((p[0] & FR_EA_BIT) == 0) {
1282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		*dlci = (*dlci << 7) | (p[0] >> 1);
1292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		(*addr_len)++;	/* 4-byte Q.922 address */
1302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		p++;
131892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		length--;
1322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
1332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
134892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	if (!ND_TTEST(p[0]) || length < 1)
135892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		return -1;
1362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if ((p[0] & FR_EA_BIT) == 0)
137892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		return 0; /* more than 4 bytes of Q.922 address? */
1382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        flags[3] = p[0] & 0x02;
1402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
14153f17a9db278d33517d9888dd77848f554522a38JP Abgrall        *dlci = (*dlci << 6) | (p[0] >> 2);
1422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
143892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	return 1;
1442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
1452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
146892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hugheschar *
147892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesq922_string(netdissect_options *ndo, const u_char *p, u_int length)
148892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes{
14953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
15053f17a9db278d33517d9888dd77848f554522a38JP Abgrall    static u_int dlci, addr_len;
151892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    static uint8_t flags[4];
15253f17a9db278d33517d9888dd77848f554522a38JP Abgrall    static char buffer[sizeof("DLCI xxxxxxxxxx")];
15353f17a9db278d33517d9888dd77848f554522a38JP Abgrall    memset(buffer, 0, sizeof(buffer));
15453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
155892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    if (parse_q922_addr(ndo, p, &dlci, &addr_len, flags, length) == 1){
15653f17a9db278d33517d9888dd77848f554522a38JP Abgrall        snprintf(buffer, sizeof(buffer), "DLCI %u", dlci);
15753f17a9db278d33517d9888dd77848f554522a38JP Abgrall    }
15853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
15953f17a9db278d33517d9888dd77848f554522a38JP Abgrall    return buffer;
16053f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
16153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
16253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
1632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* Frame Relay packet structure, with flags and CRC removed
1642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                  +---------------------------+
1662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                  |       Q.922 Address*      |
1672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                  +--                       --+
1682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                  |                           |
1692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                  +---------------------------+
1702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                  | Control (UI = 0x03)       |
1712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                  +---------------------------+
1722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                  | Optional Pad      (0x00)  |
1732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                  +---------------------------+
1742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                  | NLPID                     |
1752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                  +---------------------------+
1762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                  |             .             |
1772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                  |             .             |
1782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                  |             .             |
1792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                  |           Data            |
1802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                  |             .             |
1812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                  |             .             |
1822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                  +---------------------------+
1832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project           * Q.922 addresses, as presently defined, are two octets and
1852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project             contain a 10-bit DLCI.  In some networks Q.922 addresses
1862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project             may optionally be increased to three or four octets.
1872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project*/
1882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
1892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic void
190892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesfr_hdr_print(netdissect_options *ndo,
191892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes             int length, u_int addr_len, u_int dlci, uint8_t *flags, uint16_t nlpid)
1922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
193892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    if (ndo->ndo_qflag) {
194892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        ND_PRINT((ndo, "Q.922, DLCI %u, length %u: ",
1952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                     dlci,
196892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                     length));
1972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    } else {
1982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        if (nlpid <= 0xff) /* if its smaller than 256 then its a NLPID */
199892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            ND_PRINT((ndo, "Q.922, hdr-len %u, DLCI %u, Flags [%s], NLPID %s (0x%02x), length %u: ",
2002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                         addr_len,
2012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                         dlci,
2022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                         bittok2str(fr_header_flag_values, "none", EXTRACT_32BITS(flags)),
2032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                         tok2str(nlpid_values,"unknown", nlpid),
2042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                         nlpid,
205892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                         length));
2062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        else /* must be an ethertype */
207892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            ND_PRINT((ndo, "Q.922, hdr-len %u, DLCI %u, Flags [%s], cisco-ethertype %s (0x%04x), length %u: ",
2082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                         addr_len,
2092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                         dlci,
2102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                         bittok2str(fr_header_flag_values, "none", EXTRACT_32BITS(flags)),
2112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                         tok2str(ethertype_values, "unknown", nlpid),
2122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                         nlpid,
213892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                         length));
2142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    }
2152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
2162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectu_int
218892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesfr_if_print(netdissect_options *ndo,
219892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            const struct pcap_pkthdr *h, register const u_char *p)
2202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
2212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	register u_int length = h->len;
2222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	register u_int caplen = h->caplen;
2232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
224892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        ND_TCHECK2(*p, 4); /* minimum frame header length */
2252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
226892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        if ((length = fr_print(ndo, p, length)) == 0)
2272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            return (0);
2282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        else
2292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            return length;
2302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project trunc:
231892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        ND_PRINT((ndo, "[|fr]"));
2322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        return caplen;
2332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
2342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
2352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectu_int
236892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesfr_print(netdissect_options *ndo,
237892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes         register const u_char *p, u_int length)
2382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
239892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	int ret;
240892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint16_t extracted_ethertype;
2412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	u_int dlci;
2422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	u_int addr_len;
243892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint16_t nlpid;
2442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	u_int hdr_len;
245892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	uint8_t flags[4];
2462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
247892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ret = parse_q922_addr(ndo, p, &dlci, &addr_len, flags, length);
248892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	if (ret == -1)
249892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		goto trunc;
250892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	if (ret == 0) {
251892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "Q.922, invalid address"));
2522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return 0;
2532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
2542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
255892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK(p[addr_len]);
256892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	if (length < addr_len + 1)
257892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		goto trunc;
2582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
259892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	if (p[addr_len] != LLC_UI && dlci != 0) {
260892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                /*
261892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                 * Let's figure out if we have Cisco-style encapsulation,
262892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                 * with an Ethernet type (Cisco HDLC type?) following the
263892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                 * address.
264892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                 */
265892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		if (!ND_TTEST2(p[addr_len], 2) || length < addr_len + 2) {
266892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        /* no Ethertype */
267892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        ND_PRINT((ndo, "UI %02x! ", p[addr_len]));
268892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                } else {
269892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        extracted_ethertype = EXTRACT_16BITS(p+addr_len);
270892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
271892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        if (ndo->ndo_eflag)
272892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                fr_hdr_print(ndo, length, addr_len, dlci,
273892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                    flags, extracted_ethertype);
274892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
275892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        if (ethertype_print(ndo, extracted_ethertype,
276892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                            p+addr_len+ETHERTYPE_LEN,
277892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                            length-addr_len-ETHERTYPE_LEN,
278892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                            length-addr_len-ETHERTYPE_LEN) == 0)
279892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                /* ether_type not known, probably it wasn't one */
280892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                ND_PRINT((ndo, "UI %02x! ", p[addr_len]));
281892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        else
282892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                                return addr_len + 2;
283892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                }
2842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        }
2852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
286892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_TCHECK(p[addr_len+1]);
287892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	if (length < addr_len + 2)
288892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		goto trunc;
289892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
290892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	if (p[addr_len + 1] == 0) {
291892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		/*
292892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		 * Assume a pad byte after the control (UI) byte.
293892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		 * A pad byte should only be used with 3-byte Q.922.
294892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		 */
2952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		if (addr_len != 3)
296892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "Pad! "));
297892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		hdr_len = addr_len + 1 /* UI */ + 1 /* pad */ + 1 /* NLPID */;
298892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	} else {
299892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		/*
300892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		 * Not a pad byte.
301892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		 * A pad byte should be used with 3-byte Q.922.
302892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		 */
303892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		if (addr_len == 3)
304892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_PRINT((ndo, "No pad! "));
305892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		hdr_len = addr_len + 1 /* UI */ + 1 /* NLPID */;
306892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	}
3072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
308892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        ND_TCHECK(p[hdr_len - 1]);
309892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	if (length < hdr_len)
310892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		goto trunc;
3112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	nlpid = p[hdr_len - 1];
3122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
313892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	if (ndo->ndo_eflag)
314892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		fr_hdr_print(ndo, length, addr_len, dlci, flags, nlpid);
3152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	p += hdr_len;
3162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	length -= hdr_len;
3172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	switch (nlpid) {
3192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case NLPID_IP:
320892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	        ip_print(ndo, p, length);
3212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
3222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case NLPID_IP6:
324892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ip6_print(ndo, p, length);
3252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
326892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
3272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case NLPID_CLNP:
3282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case NLPID_ESIS:
3292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case NLPID_ISIS:
330892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		isoclns_print(ndo, p - 1, length + 1, length + 1); /* OSI printers need the NLPID field */
3312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
3322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	case NLPID_SNAP:
334892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		if (snap_print(ndo, p, length, length, 0) == 0) {
3352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project			/* ether_type not known, print raw packet */
336892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        if (!ndo->ndo_eflag)
337892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                            fr_hdr_print(ndo, length + hdr_len, hdr_len,
3382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                                         dlci, flags, nlpid);
339892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			if (!ndo->ndo_suppress_default_print)
340892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes				ND_DEFAULTPRINT(p - hdr_len, length + hdr_len);
3412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
3422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
3432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        case NLPID_Q933:
345892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		q933_print(ndo, p, length);
3462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		break;
3472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        case NLPID_MFR:
349892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                frf15_print(ndo, p, length);
3502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                break;
3512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        case NLPID_PPP:
353892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                ppp_print(ndo, p, length);
3542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                break;
3552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	default:
357892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		if (!ndo->ndo_eflag)
358892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    fr_hdr_print(ndo, length + hdr_len, addr_len,
3592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project				     dlci, flags, nlpid);
360892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		if (!ndo->ndo_xflag)
361892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			ND_DEFAULTPRINT(p, length);
3622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
3632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	return hdr_len;
3652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project trunc:
367892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        ND_PRINT((ndo, "[|fr]"));
3682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        return 0;
3692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
3712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectu_int
373892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesmfr_if_print(netdissect_options *ndo,
374892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes             const struct pcap_pkthdr *h, register const u_char *p)
3752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
3762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	register u_int length = h->len;
3772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	register u_int caplen = h->caplen;
3782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
379892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        ND_TCHECK2(*p, 2); /* minimum frame header length */
3802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
381892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        if ((length = mfr_print(ndo, p, length)) == 0)
3822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            return (0);
3832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        else
3842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            return length;
3852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project trunc:
386892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        ND_PRINT((ndo, "[|mfr]"));
3872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        return caplen;
3882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
3892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
3912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define MFR_CTRL_MSG_ADD_LINK        1
3922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define MFR_CTRL_MSG_ADD_LINK_ACK    2
3932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define MFR_CTRL_MSG_ADD_LINK_REJ    3
3942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define MFR_CTRL_MSG_HELLO           4
3952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define MFR_CTRL_MSG_HELLO_ACK       5
3962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define MFR_CTRL_MSG_REMOVE_LINK     6
3972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define MFR_CTRL_MSG_REMOVE_LINK_ACK 7
3982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
39953f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok mfr_ctrl_msg_values[] = {
4002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MFR_CTRL_MSG_ADD_LINK, "Add Link" },
4012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MFR_CTRL_MSG_ADD_LINK_ACK, "Add Link ACK" },
4022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MFR_CTRL_MSG_ADD_LINK_REJ, "Add Link Reject" },
4032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MFR_CTRL_MSG_HELLO, "Hello" },
4042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MFR_CTRL_MSG_HELLO_ACK, "Hello ACK" },
4052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MFR_CTRL_MSG_REMOVE_LINK, "Remove Link" },
4062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MFR_CTRL_MSG_REMOVE_LINK_ACK, "Remove Link ACK" },
4072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0, NULL }
4082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
4092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
4102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define MFR_CTRL_IE_BUNDLE_ID  1
4112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define MFR_CTRL_IE_LINK_ID    2
4122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define MFR_CTRL_IE_MAGIC_NUM  3
4132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define MFR_CTRL_IE_TIMESTAMP  5
4142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define MFR_CTRL_IE_VENDOR_EXT 6
4152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define MFR_CTRL_IE_CAUSE      7
4162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
41753f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok mfr_ctrl_ie_values[] = {
4182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MFR_CTRL_IE_BUNDLE_ID, "Bundle ID"},
4192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MFR_CTRL_IE_LINK_ID, "Link ID"},
4202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MFR_CTRL_IE_MAGIC_NUM, "Magic Number"},
4212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MFR_CTRL_IE_TIMESTAMP, "Timestamp"},
4222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MFR_CTRL_IE_VENDOR_EXT, "Vendor Extension"},
4232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MFR_CTRL_IE_CAUSE, "Cause"},
4242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0, NULL }
4252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
4262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
4272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define MFR_ID_STRING_MAXLEN 50
4282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
4292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstruct ie_tlv_header_t {
430892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    uint8_t ie_type;
431892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    uint8_t ie_len;
4322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
4332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
4342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectu_int
435892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesmfr_print(netdissect_options *ndo,
436892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes          register const u_char *p, u_int length)
4372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
4382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    u_int tlen,idx,hdr_len = 0;
439892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    uint16_t sequence_num;
440892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    uint8_t ie_type,ie_len;
441892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    const uint8_t *tptr;
4422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
4432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
4442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*
4452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * FRF.16 Link Integrity Control Frame
446892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes *
4472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *      7    6    5    4    3    2    1    0
4482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    +----+----+----+----+----+----+----+----+
4492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    | B  | E  | C=1| 0    0    0    0  | EA |
4502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    +----+----+----+----+----+----+----+----+
4512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    | 0    0    0    0    0    0    0    0  |
4522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    +----+----+----+----+----+----+----+----+
4532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    |              message type             |
4542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    +----+----+----+----+----+----+----+----+
4552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
4562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
457892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    ND_TCHECK2(*p, 4); /* minimum frame header length */
4582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
4592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    if ((p[0] & MFR_BEC_MASK) == MFR_CTRL_FRAME && p[1] == 0) {
460892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        ND_PRINT((ndo, "FRF.16 Control, Flags [%s], %s, length %u",
4612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project               bittok2str(frf_flag_values,"none",(p[0] & MFR_BEC_MASK)),
4622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project               tok2str(mfr_ctrl_msg_values,"Unknown Message (0x%02x)",p[2]),
463892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes               length));
4642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        tptr = p + 3;
4652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        tlen = length -3;
4662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        hdr_len = 3;
4672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
468892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        if (!ndo->ndo_vflag)
4692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            return hdr_len;
4702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
4712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        while (tlen>sizeof(struct ie_tlv_header_t)) {
472892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            ND_TCHECK2(*tptr, sizeof(struct ie_tlv_header_t));
4732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            ie_type=tptr[0];
4742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            ie_len=tptr[1];
4752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
476892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            ND_PRINT((ndo, "\n\tIE %s (%u), length %u: ",
4772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                   tok2str(mfr_ctrl_ie_values,"Unknown",ie_type),
4782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                   ie_type,
479892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                   ie_len));
4802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
4812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            /* infinite loop check */
4822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            if (ie_type == 0 || ie_len <= sizeof(struct ie_tlv_header_t))
4832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                return hdr_len;
4842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
485892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            ND_TCHECK2(*tptr, ie_len);
4862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            tptr+=sizeof(struct ie_tlv_header_t);
4872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            /* tlv len includes header */
4882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            ie_len-=sizeof(struct ie_tlv_header_t);
4892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            tlen-=sizeof(struct ie_tlv_header_t);
4902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
4912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            switch (ie_type) {
4922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
4932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            case MFR_CTRL_IE_MAGIC_NUM:
494892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                ND_PRINT((ndo, "0x%08x", EXTRACT_32BITS(tptr)));
4952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                break;
4962949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
4972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            case MFR_CTRL_IE_BUNDLE_ID: /* same message format */
4982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            case MFR_CTRL_IE_LINK_ID:
4992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                for (idx = 0; idx < ie_len && idx < MFR_ID_STRING_MAXLEN; idx++) {
5002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    if (*(tptr+idx) != 0) /* don't print null termination */
501892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        safeputchar(ndo, *(tptr + idx));
5022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    else
5032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                        break;
5042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                }
5052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                break;
5062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            case MFR_CTRL_IE_TIMESTAMP:
5082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                if (ie_len == sizeof(struct timeval)) {
509892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    ts_print(ndo, (const struct timeval *)tptr);
5102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    break;
5112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                }
5122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                /* fall through and hexdump if no unix timestamp */
5132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                /*
5152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                 * FIXME those are the defined IEs that lack a decoder
5162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                 * you are welcome to contribute code ;-)
5172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                 */
5182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            case MFR_CTRL_IE_VENDOR_EXT:
5202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            case MFR_CTRL_IE_CAUSE:
5212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            default:
523892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                if (ndo->ndo_vflag <= 1)
524892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    print_unknown_data(ndo, tptr, "\n\t  ", ie_len);
5252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                break;
5262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            }
5272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            /* do we want to see a hexdump of the IE ? */
529892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            if (ndo->ndo_vflag > 1 )
530892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                print_unknown_data(ndo, tptr, "\n\t  ", ie_len);
531892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
5322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            tlen-=ie_len;
5332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            tptr+=ie_len;
5342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        }
5352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        return hdr_len;
5362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    }
5372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*
5382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * FRF.16 Fragmentation Frame
539892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes *
5402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *      7    6    5    4    3    2    1    0
5412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    +----+----+----+----+----+----+----+----+
5422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    | B  | E  | C=0|seq. (high 4 bits) | EA  |
5432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    +----+----+----+----+----+----+----+----+
5442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    |        sequence  (low 8 bits)         |
5452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    +----+----+----+----+----+----+----+----+
5462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    |        DLCI (6 bits)        | CR | EA  |
5472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    +----+----+----+----+----+----+----+----+
5482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    |   DLCI (4 bits)   |FECN|BECN| DE | EA |
5492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    +----+----+----+----+----+----+----+----+
5502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
5512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    sequence_num = (p[0]&0x1e)<<7 | p[1];
5532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    /* whole packet or first fragment ? */
5542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    if ((p[0] & MFR_BEC_MASK) == MFR_FRAG_FRAME ||
5552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        (p[0] & MFR_BEC_MASK) == MFR_B_BIT) {
556892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        ND_PRINT((ndo, "FRF.16 Frag, seq %u, Flags [%s], ",
5572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project               sequence_num,
558892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes               bittok2str(frf_flag_values,"none",(p[0] & MFR_BEC_MASK))));
5592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        hdr_len = 2;
560892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        fr_print(ndo, p+hdr_len,length-hdr_len);
5612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        return hdr_len;
5622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    }
5632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    /* must be a middle or the last fragment */
565892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    ND_PRINT((ndo, "FRF.16 Frag, seq %u, Flags [%s]",
5662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project           sequence_num,
567892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes           bittok2str(frf_flag_values,"none",(p[0] & MFR_BEC_MASK))));
568892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    print_unknown_data(ndo, p, "\n\t", length);
5692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    return hdr_len;
5712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project trunc:
573892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    ND_PRINT((ndo, "[|mfr]"));
5742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    return length;
5752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
5762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* an NLPID of 0xb1 indicates a 2-byte
5782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * FRF.15 header
579892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes *
5802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *      7    6    5    4    3    2    1    0
5812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    +----+----+----+----+----+----+----+----+
5822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    ~              Q.922 header             ~
5832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    +----+----+----+----+----+----+----+----+
5842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    |             NLPID (8 bits)            | NLPID=0xb1
5852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    +----+----+----+----+----+----+----+----+
5862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    | B  | E  | C  |seq. (high 4 bits) | R  |
5872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    +----+----+----+----+----+----+----+----+
5882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    |        sequence  (low 8 bits)         |
5892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project *    +----+----+----+----+----+----+----+----+
5902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
5912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define FR_FRF15_FRAGTYPE 0x01
5932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
5942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic void
595892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesfrf15_print(netdissect_options *ndo,
596892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            const u_char *p, u_int length)
597892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes{
598892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    uint16_t sequence_num, flags;
5992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
6002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    flags = p[0]&MFR_BEC_MASK;
6012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    sequence_num = (p[0]&0x1e)<<7 | p[1];
6022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
603892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    ND_PRINT((ndo, "FRF.15, seq 0x%03x, Flags [%s],%s Fragmentation, length %u",
6042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project           sequence_num,
6052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project           bittok2str(frf_flag_values,"none",flags),
6062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project           p[0]&FR_FRF15_FRAGTYPE ? "Interface" : "End-to-End",
607892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes           length));
6082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
6092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* TODO:
6102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * depending on all permutations of the B, E and C bit
6112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * dig as deep as we can - e.g. on the first (B) fragment
6122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * there is enough payload to print the IP header
6132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * on non (B) fragments it depends if the fragmentation
6142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * model is end-to-end or interface based wether we want to print
6152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * another Q.922 header
6162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
6172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
6182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
6192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
6202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*
6212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * Q.933 decoding portion for framerelay specific.
6222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
6232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
6242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* Q.933 packet format
625892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                      Format of Other Protocols
6262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                          using Q.933 NLPID
627892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                  +-------------------------------+
628892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                  |        Q.922 Address          |
629892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                  +---------------+---------------+
630892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                  |Control  0x03  | NLPID   0x08  |
6312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                  +---------------+---------------+
6322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                  |          L2 Protocol ID       |
6332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                  | octet 1       |  octet 2      |
6342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                  +-------------------------------+
6352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                  |          L3 Protocol ID       |
6362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                  | octet 2       |  octet 2      |
6372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                  +-------------------------------+
6382949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                  |         Protocol Data         |
6392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                  +-------------------------------+
6402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                  | FCS                           |
6412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                  +-------------------------------+
6422949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
6432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
6442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* L2 (Octet 1)- Call Reference Usually is 0x0 */
6452949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
6462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/*
6472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project * L2 (Octet 2)- Message Types definition 1 byte long.
6482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project */
6492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* Call Establish */
6502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define MSG_TYPE_ESC_TO_NATIONAL  0x00
6512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define MSG_TYPE_ALERT            0x01
6522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define MSG_TYPE_CALL_PROCEEDING  0x02
6532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define MSG_TYPE_CONNECT          0x07
6542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define MSG_TYPE_CONNECT_ACK      0x0F
6552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define MSG_TYPE_PROGRESS         0x03
6562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define MSG_TYPE_SETUP            0x05
6572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* Call Clear */
6582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define MSG_TYPE_DISCONNECT       0x45
6592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define MSG_TYPE_RELEASE          0x4D
6602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define MSG_TYPE_RELEASE_COMPLETE 0x5A
6612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define MSG_TYPE_RESTART          0x46
6622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define MSG_TYPE_RESTART_ACK      0x4E
6632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* Status */
6642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define MSG_TYPE_STATUS           0x7D
6652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define MSG_TYPE_STATUS_ENQ       0x75
6662949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
66753f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok fr_q933_msg_values[] = {
6682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MSG_TYPE_ESC_TO_NATIONAL, "ESC to National" },
6692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MSG_TYPE_ALERT, "Alert" },
6702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MSG_TYPE_CALL_PROCEEDING, "Call proceeding" },
6712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MSG_TYPE_CONNECT, "Connect" },
6722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MSG_TYPE_CONNECT_ACK, "Connect ACK" },
6732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MSG_TYPE_PROGRESS, "Progress" },
6742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MSG_TYPE_SETUP, "Setup" },
6752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MSG_TYPE_DISCONNECT, "Disconnect" },
6762949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MSG_TYPE_RELEASE, "Release" },
6772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MSG_TYPE_RELEASE_COMPLETE, "Release Complete" },
6782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MSG_TYPE_RESTART, "Restart" },
6792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MSG_TYPE_RESTART_ACK, "Restart ACK" },
6802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MSG_TYPE_STATUS, "Status Reply" },
6812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { MSG_TYPE_STATUS_ENQ, "Status Enquiry" },
6822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0, NULL }
6832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
6842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
6852949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define MSG_ANSI_LOCKING_SHIFT	0x95
6862949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
6872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define FR_LMI_ANSI_REPORT_TYPE_IE	0x01
6882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define FR_LMI_ANSI_LINK_VERIFY_IE_91	0x19 /* details? */
6892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define FR_LMI_ANSI_LINK_VERIFY_IE	0x03
6902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define FR_LMI_ANSI_PVC_STATUS_IE	0x07
6912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
6922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define FR_LMI_CCITT_REPORT_TYPE_IE	0x51
6932949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define FR_LMI_CCITT_LINK_VERIFY_IE	0x53
6942949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define FR_LMI_CCITT_PVC_STATUS_IE	0x57
6952949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
69653f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok fr_q933_ie_values_codeset5[] = {
6972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { FR_LMI_ANSI_REPORT_TYPE_IE, "ANSI Report Type" },
6982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { FR_LMI_ANSI_LINK_VERIFY_IE_91, "ANSI Link Verify" },
6992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { FR_LMI_ANSI_LINK_VERIFY_IE, "ANSI Link Verify" },
7002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { FR_LMI_ANSI_PVC_STATUS_IE, "ANSI PVC Status" },
7012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { FR_LMI_CCITT_REPORT_TYPE_IE, "CCITT Report Type" },
7022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { FR_LMI_CCITT_LINK_VERIFY_IE, "CCITT Link Verify" },
7032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { FR_LMI_CCITT_PVC_STATUS_IE, "CCITT PVC Status" },
7042949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0, NULL }
7052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
7062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
7072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define FR_LMI_REPORT_TYPE_IE_FULL_STATUS 0
7082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define FR_LMI_REPORT_TYPE_IE_LINK_VERIFY 1
7092949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project#define FR_LMI_REPORT_TYPE_IE_ASYNC_PVC   2
7102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
71153f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok fr_lmi_report_type_ie_values[] = {
7122949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { FR_LMI_REPORT_TYPE_IE_FULL_STATUS, "Full Status" },
7132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { FR_LMI_REPORT_TYPE_IE_LINK_VERIFY, "Link verify" },
7142949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { FR_LMI_REPORT_TYPE_IE_ASYNC_PVC, "Async PVC Status" },
7152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    { 0, NULL }
7162949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
7172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
7182949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* array of 16 codepages - currently we only support codepage 1,5 */
71953f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok *fr_q933_ie_codesets[] = {
7202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    NULL,
7212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    fr_q933_ie_values_codeset5,
7222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    NULL,
7232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    NULL,
7242949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    NULL,
7252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    fr_q933_ie_values_codeset5,
7262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    NULL,
7272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    NULL,
7282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    NULL,
7292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    NULL,
7302949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    NULL,
7312949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    NULL,
7322949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    NULL,
7332949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    NULL,
7342949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    NULL,
7352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    NULL
7362949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
7372949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
738892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesstatic int fr_q933_print_ie_codeset5(netdissect_options *ndo,
739892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    const struct ie_tlv_header_t  *ie_p, const u_char *p);
7402949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
741892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughestypedef int (*codeset_pr_func_t)(netdissect_options *,
742892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes    const struct ie_tlv_header_t  *ie_p, const u_char *p);
7432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
7442949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project/* array of 16 codepages - currently we only support codepage 1,5 */
745892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesstatic const codeset_pr_func_t fr_q933_print_ie_codeset[] = {
7462949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    NULL,
7472949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    fr_q933_print_ie_codeset5,
7482949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    NULL,
7492949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    NULL,
7502949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    NULL,
7512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    fr_q933_print_ie_codeset5,
7522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    NULL,
7532949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    NULL,
7542949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    NULL,
7552949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    NULL,
7562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    NULL,
7572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    NULL,
7582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    NULL,
7592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    NULL,
7602949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    NULL,
7612949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project    NULL
7622949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project};
7632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
7642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectvoid
765892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesq933_print(netdissect_options *ndo,
766892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes           const u_char *p, u_int length)
7672949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
7682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	const u_char *ptemp = p;
7692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	struct ie_tlv_header_t  *ie_p;
7702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        int olen;
7712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	int is_ansi = 0;
7722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        u_int codeset;
7732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        u_int ie_is_known = 0;
7742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
7752949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (length < 9) {	/* shortest: Q.933a LINK VERIFY */
776892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "[|q.933]"));
7772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return;
7782949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
7792949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
7802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        codeset = p[2]&0x0f;   /* extract the codeset */
7812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
78253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (p[2] == MSG_ANSI_LOCKING_SHIFT) {
78353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	        is_ansi = 1;
78453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
785892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
786892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        ND_PRINT((ndo, "%s", ndo->ndo_eflag ? "" : "Q.933, "));
7872949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
7882949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	/* printing out header part */
789892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	ND_PRINT((ndo, "%s, codeset %u", is_ansi ? "ANSI" : "CCITT", codeset));
7902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
79153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if (p[0]) {
792892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes	        ND_PRINT((ndo, ", Call Ref: 0x%02x", p[0]));
79353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
794892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        if (ndo->ndo_vflag) {
795892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                ND_PRINT((ndo, ", %s (0x%02x), length %u",
79653f17a9db278d33517d9888dd77848f554522a38JP Abgrall		       tok2str(fr_q933_msg_values,
79753f17a9db278d33517d9888dd77848f554522a38JP Abgrall			       "unknown message", p[1]),
79853f17a9db278d33517d9888dd77848f554522a38JP Abgrall		       p[1],
799892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		       length));
80053f17a9db278d33517d9888dd77848f554522a38JP Abgrall        } else {
801892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                ND_PRINT((ndo, ", %s",
80253f17a9db278d33517d9888dd77848f554522a38JP Abgrall		       tok2str(fr_q933_msg_values,
803892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes			       "unknown message 0x%02x", p[1])));
80453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
8052949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
8062949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        olen = length; /* preserve the original length for non verbose mode */
8072949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
8082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	if (length < (u_int)(2 - is_ansi)) {
809892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		ND_PRINT((ndo, "[|q.933]"));
8102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		return;
8112949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
81253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	length -= 2 + is_ansi;
8132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	ptemp += 2 + is_ansi;
814892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
8152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	/* Loop through the rest of IE */
81653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	while (length > sizeof(struct ie_tlv_header_t)) {
8172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		ie_p = (struct ie_tlv_header_t  *)ptemp;
81853f17a9db278d33517d9888dd77848f554522a38JP Abgrall		if (length < sizeof(struct ie_tlv_header_t) ||
81953f17a9db278d33517d9888dd77848f554522a38JP Abgrall		    length < sizeof(struct ie_tlv_header_t) + ie_p->ie_len) {
820892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    if (ndo->ndo_vflag) { /* not bark if there is just a trailer */
821892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        ND_PRINT((ndo, "\n[|q.933]"));
82253f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    } else {
823892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                        ND_PRINT((ndo, ", length %u", olen));
82453f17a9db278d33517d9888dd77848f554522a38JP Abgrall		    }
8252949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    return;
8262949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		}
8272949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
8282949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                /* lets do the full IE parsing only in verbose mode
8292949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                 * however some IEs (DLCI Status, Link Verify)
83053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                 * are also interestting in non-verbose mode */
831892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                if (ndo->ndo_vflag) {
832892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    ND_PRINT((ndo, "\n\t%s IE (0x%02x), length %u: ",
83353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                           tok2str(fr_q933_ie_codesets[codeset],
83453f17a9db278d33517d9888dd77848f554522a38JP Abgrall				   "unknown", ie_p->ie_type),
8352949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                           ie_p->ie_type,
836892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                           ie_p->ie_len));
83753f17a9db278d33517d9888dd77848f554522a38JP Abgrall		}
83853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
8392949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                /* sanity check */
84053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                if (ie_p->ie_type == 0 || ie_p->ie_len == 0) {
8412949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    return;
84253f17a9db278d33517d9888dd77848f554522a38JP Abgrall		}
8432949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
84453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                if (fr_q933_print_ie_codeset[codeset] != NULL) {
845892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    ie_is_known = fr_q933_print_ie_codeset[codeset](ndo, ie_p, ptemp);
846892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes		}
84753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
848892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                if (ndo->ndo_vflag >= 1 && !ie_is_known) {
849892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    print_unknown_data(ndo, ptemp+2, "\n\t", ie_p->ie_len);
85053f17a9db278d33517d9888dd77848f554522a38JP Abgrall		}
8512949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
8522949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                /* do we want to see a hexdump of the IE ? */
853892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                if (ndo->ndo_vflag> 1 && ie_is_known) {
854892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    print_unknown_data(ndo, ptemp+2, "\n\t  ", ie_p->ie_len);
85553f17a9db278d33517d9888dd77848f554522a38JP Abgrall		}
8562949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
8572949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		length = length - ie_p->ie_len - 2;
8582949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project		ptemp = ptemp + ie_p->ie_len + 2;
8592949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
860892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes        if (!ndo->ndo_vflag) {
861892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            ND_PRINT((ndo, ", length %u", olen));
86253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	}
8632949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
8642949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
8652949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Projectstatic int
866892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughesfr_q933_print_ie_codeset5(netdissect_options *ndo,
867892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                          const struct ie_tlv_header_t  *ie_p, const u_char *p)
8682949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project{
8692949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        u_int dlci;
8702949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
8712949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        switch (ie_p->ie_type) {
8722949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
8732949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        case FR_LMI_ANSI_REPORT_TYPE_IE: /* fall through */
8742949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        case FR_LMI_CCITT_REPORT_TYPE_IE:
875892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            if (ndo->ndo_vflag) {
876892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                ND_PRINT((ndo, "%s (%u)",
8772949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                       tok2str(fr_lmi_report_type_ie_values,"unknown",p[2]),
878892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                       p[2]));
87953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    }
8802949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            return 1;
8812949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
8822949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        case FR_LMI_ANSI_LINK_VERIFY_IE: /* fall through */
8832949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        case FR_LMI_CCITT_LINK_VERIFY_IE:
8842949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        case FR_LMI_ANSI_LINK_VERIFY_IE_91:
885892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            if (!ndo->ndo_vflag) {
886892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                ND_PRINT((ndo, ", "));
88753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    }
888892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            ND_PRINT((ndo, "TX Seq: %3d, RX Seq: %3d", p[2], p[3]));
8892949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            return 1;
8902949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
8912949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        case FR_LMI_ANSI_PVC_STATUS_IE: /* fall through */
8922949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        case FR_LMI_CCITT_PVC_STATUS_IE:
893892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            if (!ndo->ndo_vflag) {
894892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                ND_PRINT((ndo, ", "));
89553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    }
896892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            /* now parse the DLCI information element. */
8972949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            if ((ie_p->ie_len < 3) ||
8982949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                (p[2] & 0x80) ||
8992949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                ((ie_p->ie_len == 3) && !(p[3] & 0x80)) ||
9002949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                ((ie_p->ie_len == 4) && ((p[3] & 0x80) || !(p[4] & 0x80))) ||
9012949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                ((ie_p->ie_len == 5) && ((p[3] & 0x80) || (p[4] & 0x80) ||
9022949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                                   !(p[5] & 0x80))) ||
9032949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                (ie_p->ie_len > 5) ||
90453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                !(p[ie_p->ie_len + 1] & 0x80)) {
905892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                ND_PRINT((ndo, "Invalid DLCI IE"));
90653f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    }
907892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes
9082949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            dlci = ((p[2] & 0x3F) << 4) | ((p[3] & 0x78) >> 3);
90953f17a9db278d33517d9888dd77848f554522a38JP Abgrall            if (ie_p->ie_len == 4) {
9102949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                dlci = (dlci << 6) | ((p[4] & 0x7E) >> 1);
91153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    }
91253f17a9db278d33517d9888dd77848f554522a38JP Abgrall            else if (ie_p->ie_len == 5) {
9132949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                dlci = (dlci << 13) | (p[4] & 0x7F) | ((p[5] & 0x7E) >> 1);
91453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	    }
9152949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
916892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes            ND_PRINT((ndo, "DLCI %u: status %s%s", dlci,
9172949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project                    p[ie_p->ie_len + 1] & 0x8 ? "New, " : "",
918892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes                    p[ie_p->ie_len + 1] & 0x2 ? "Active" : "Inactive"));
9192949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project            return 1;
9202949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project	}
9212949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project
9222949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project        return 0;
9232949f58a438f6fd85f66a8b7ed4708042cde4b37The Android Open Source Project}
924892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes/*
925892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes * Local Variables:
926892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes * c-style: whitesmith
927892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes * c-basic-offset: 8
928892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes * End:
929892a68bdf2f50b40781212e4d7ee7369c8165953Elliott Hughes */
930