?? print-fr.c
字號:
/* * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */#ifndef lintstatic const char rcsid[] _U_ = "@(#)$Header: /tcpdump/master/tcpdump/print-fr.c,v 1.51 2006-06-23 22:20:32 hannes Exp $ (LBL)";#endif#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <tcpdump-stdinc.h>#include <stdio.h>#include <string.h>#include <pcap.h>#include "addrtoname.h"#include "interface.h"#include "ethertype.h"#include "nlpid.h"#include "extract.h"#include "oui.h"static void frf15_print(const u_char *, u_int);/* * the frame relay header has a variable length * * the EA bit determines if there is another byte * in the header * * minimum header length is 2 bytes * maximum header length is 4 bytes * * 7 6 5 4 3 2 1 0 * +----+----+----+----+----+----+----+----+ * | DLCI (6 bits) | CR | EA | * +----+----+----+----+----+----+----+----+ * | DLCI (4 bits) |FECN|BECN| DE | EA | * +----+----+----+----+----+----+----+----+ * | DLCI (7 bits) | EA | * +----+----+----+----+----+----+----+----+ * | DLCI (6 bits) |SDLC| EA | * +----+----+----+----+----+----+----+----+ */#define FR_EA_BIT 0x01#define FR_CR_BIT 0x02000000#define FR_DE_BIT 0x00020000#define FR_BECN_BIT 0x00040000#define FR_FECN_BIT 0x00080000#define FR_SDLC_BIT 0x00000002struct tok fr_header_flag_values[] = { { FR_CR_BIT, "C!" }, { FR_DE_BIT, "DE" }, { FR_BECN_BIT, "BECN" }, { FR_FECN_BIT, "FECN" }, { FR_SDLC_BIT, "sdlcore" }, { 0, NULL }};/* FRF.15 / FRF.16 */#define MFR_B_BIT 0x80#define MFR_E_BIT 0x40#define MFR_C_BIT 0x20#define MFR_BEC_MASK (MFR_B_BIT | MFR_E_BIT | MFR_C_BIT)#define MFR_CTRL_FRAME (MFR_B_BIT | MFR_E_BIT | MFR_C_BIT)#define MFR_FRAG_FRAME (MFR_B_BIT | MFR_E_BIT )struct tok frf_flag_values[] = { { MFR_B_BIT, "Begin" }, { MFR_E_BIT, "End" }, { MFR_C_BIT, "Control" }, { 0, NULL }};/* Finds out Q.922 address length, DLCI and flags. Returns 0 on success * save the flags dep. on address length */static int parse_q922_addr(const u_char *p, u_int *dlci, u_int *addr_len, u_int8_t *flags){ if ((p[0] & FR_EA_BIT)) return -1; *addr_len = 2; *dlci = ((p[0] & 0xFC) << 2) | ((p[1] & 0xF0) >> 4); flags[0] = p[0] & 0x02; /* populate the first flag fields */ flags[1] = p[1] & 0x0c; flags[2] = 0; /* clear the rest of the flags */ flags[3] = 0; if (p[1] & FR_EA_BIT) return 0; /* 2-byte Q.922 address */ p += 2; (*addr_len)++; /* 3- or 4-byte Q.922 address */ if ((p[0] & FR_EA_BIT) == 0) { *dlci = (*dlci << 7) | (p[0] >> 1); (*addr_len)++; /* 4-byte Q.922 address */ p++; } if ((p[0] & FR_EA_BIT) == 0) return -1; /* more than 4 bytes of Q.922 address? */ flags[3] = p[0] & 0x02; *dlci = (*dlci << 6) | (p[0] >> 2); return 0;}char *q922_string(const u_char *p) { static u_int dlci, addr_len; static u_int8_t flags[4]; static char buffer[sizeof("DLCI xxxxxxxxxx")]; memset(buffer, 0, sizeof(buffer)); if (parse_q922_addr(p, &dlci, &addr_len, flags) == 0){ snprintf(buffer, sizeof(buffer), "DLCI %u", dlci); } return buffer;}/* Frame Relay packet structure, with flags and CRC removed +---------------------------+ | Q.922 Address* | +-- --+ | | +---------------------------+ | Control (UI = 0x03) | +---------------------------+ | Optional Pad (0x00) | +---------------------------+ | NLPID | +---------------------------+ | . | | . | | . | | Data | | . | | . | +---------------------------+ * Q.922 addresses, as presently defined, are two octets and contain a 10-bit DLCI. In some networks Q.922 addresses may optionally be increased to three or four octets.*/static u_intfr_hdrlen(const u_char *p, u_int addr_len){ if (!p[addr_len + 1] /* pad exist */) return addr_len + 1 /* UI */ + 1 /* pad */ + 1 /* NLPID */; else return addr_len + 1 /* UI */ + 1 /* NLPID */;}static voidfr_hdr_print(int length, u_int addr_len, u_int dlci, u_int8_t *flags, u_int16_t nlpid){ if (qflag) { (void)printf("Q.922, DLCI %u, length %u: ", dlci, length); } else { if (nlpid <= 0xff) /* if its smaller than 256 then its a NLPID */ (void)printf("Q.922, hdr-len %u, DLCI %u, Flags [%s], NLPID %s (0x%02x), length %u: ", addr_len, dlci, bittok2str(fr_header_flag_values, "none", EXTRACT_32BITS(flags)), tok2str(nlpid_values,"unknown", nlpid), nlpid, length); else /* must be an ethertype */ (void)printf("Q.922, hdr-len %u, DLCI %u, Flags [%s], cisco-ethertype %s (0x%04x), length %u: ", addr_len, dlci, bittok2str(fr_header_flag_values, "none", EXTRACT_32BITS(flags)), tok2str(ethertype_values, "unknown", nlpid), nlpid, length); }}u_intfr_if_print(const struct pcap_pkthdr *h, register const u_char *p){ register u_int length = h->len; register u_int caplen = h->caplen; TCHECK2(*p, 4); /* minimum frame header length */ if ((length = fr_print(p, length)) == 0) return (0); else return length; trunc: printf("[|fr]"); return caplen;}u_intfr_print(register const u_char *p, u_int length){ u_int16_t extracted_ethertype; u_int dlci; u_int addr_len; u_int16_t nlpid; u_int hdr_len; u_int8_t flags[4]; if (parse_q922_addr(p, &dlci, &addr_len, flags)) { printf("Q.922, invalid address"); return 0; } TCHECK2(*p,addr_len+1+1); hdr_len = fr_hdrlen(p, addr_len); TCHECK2(*p,hdr_len); if (p[addr_len] != 0x03 && dlci != 0) { /* lets figure out if we have cisco style encapsulation: */ extracted_ethertype = EXTRACT_16BITS(p+addr_len); if (eflag) fr_hdr_print(length, addr_len, dlci, flags, extracted_ethertype); if (ether_encap_print(extracted_ethertype, p+addr_len+ETHERTYPE_LEN, length-addr_len-ETHERTYPE_LEN, length-addr_len-ETHERTYPE_LEN, &extracted_ethertype) == 0) /* ether_type not known, probably it wasn't one */ printf("UI %02x! ", p[addr_len]); else return hdr_len; } if (!p[addr_len + 1]) { /* pad byte should be used with 3-byte Q.922 */ if (addr_len != 3) printf("Pad! "); } else if (addr_len == 3) printf("No pad! "); nlpid = p[hdr_len - 1]; if (eflag) fr_hdr_print(length, addr_len, dlci, flags, nlpid); p += hdr_len; length -= hdr_len; switch (nlpid) { case NLPID_IP: ip_print(gndo, p, length); break;#ifdef INET6 case NLPID_IP6: ip6_print(p, length); break;#endif case NLPID_CLNP: case NLPID_ESIS: case NLPID_ISIS: isoclns_print(p-1, length+1, length+1); /* OSI printers need the NLPID field */ break; case NLPID_SNAP: if (snap_print(p, length, length, &extracted_ethertype, 0) == 0) { /* ether_type not known, print raw packet */ if (!eflag) fr_hdr_print(length + hdr_len, hdr_len, dlci, flags, nlpid); if (!suppress_default_print) default_print(p - hdr_len, length + hdr_len); } break; case NLPID_Q933: q933_print(p, length); break; case NLPID_MFR: frf15_print(p, length); break; case NLPID_PPP: ppp_print(p, length); break; default: if (!eflag) fr_hdr_print(length + hdr_len, addr_len, dlci, flags, nlpid); if (!xflag) default_print(p, length); } return hdr_len; trunc: printf("[|fr]"); return 0;}u_intmfr_if_print(const struct pcap_pkthdr *h, register const u_char *p){ register u_int length = h->len; register u_int caplen = h->caplen; TCHECK2(*p, 2); /* minimum frame header length */ if ((length = mfr_print(p, length)) == 0) return (0); else return length; trunc: printf("[|mfr]"); return caplen;}#define MFR_CTRL_MSG_ADD_LINK 1#define MFR_CTRL_MSG_ADD_LINK_ACK 2#define MFR_CTRL_MSG_ADD_LINK_REJ 3#define MFR_CTRL_MSG_HELLO 4#define MFR_CTRL_MSG_HELLO_ACK 5#define MFR_CTRL_MSG_REMOVE_LINK 6#define MFR_CTRL_MSG_REMOVE_LINK_ACK 7struct tok mfr_ctrl_msg_values[] = { { MFR_CTRL_MSG_ADD_LINK, "Add Link" }, { MFR_CTRL_MSG_ADD_LINK_ACK, "Add Link ACK" }, { MFR_CTRL_MSG_ADD_LINK_REJ, "Add Link Reject" }, { MFR_CTRL_MSG_HELLO, "Hello" }, { MFR_CTRL_MSG_HELLO_ACK, "Hello ACK" }, { MFR_CTRL_MSG_REMOVE_LINK, "Remove Link" }, { MFR_CTRL_MSG_REMOVE_LINK_ACK, "Remove Link ACK" }, { 0, NULL }};#define MFR_CTRL_IE_BUNDLE_ID 1#define MFR_CTRL_IE_LINK_ID 2#define MFR_CTRL_IE_MAGIC_NUM 3#define MFR_CTRL_IE_TIMESTAMP 5#define MFR_CTRL_IE_VENDOR_EXT 6#define MFR_CTRL_IE_CAUSE 7struct tok mfr_ctrl_ie_values[] = { { MFR_CTRL_IE_BUNDLE_ID, "Bundle ID"}, { MFR_CTRL_IE_LINK_ID, "Link ID"}, { MFR_CTRL_IE_MAGIC_NUM, "Magic Number"}, { MFR_CTRL_IE_TIMESTAMP, "Timestamp"}, { MFR_CTRL_IE_VENDOR_EXT, "Vendor Extension"}, { MFR_CTRL_IE_CAUSE, "Cause"}, { 0, NULL }};#define MFR_ID_STRING_MAXLEN 50struct ie_tlv_header_t { u_int8_t ie_type; u_int8_t ie_len;};u_intmfr_print(register const u_char *p, u_int length){ u_int tlen,idx,hdr_len = 0; u_int16_t sequence_num; u_int8_t ie_type,ie_len; const u_int8_t *tptr;/* * FRF.16 Link Integrity Control Frame * * 7 6 5 4 3 2 1 0 * +----+----+----+----+----+----+----+----+ * | B | E | C=1| 0 0 0 0 | EA | * +----+----+----+----+----+----+----+----+ * | 0 0 0 0 0 0 0 0 | * +----+----+----+----+----+----+----+----+ * | message type | * +----+----+----+----+----+----+----+----+ */ TCHECK2(*p, 4); /* minimum frame header length */ if ((p[0] & MFR_BEC_MASK) == MFR_CTRL_FRAME && p[1] == 0) { printf("FRF.16 Control, Flags [%s], %s, length %u", bittok2str(frf_flag_values,"none",(p[0] & MFR_BEC_MASK)), tok2str(mfr_ctrl_msg_values,"Unknown Message (0x%02x)",p[2]), length); tptr = p + 3; tlen = length -3; hdr_len = 3; if (!vflag) return hdr_len; while (tlen>sizeof(struct ie_tlv_header_t)) { TCHECK2(*tptr, sizeof(struct ie_tlv_header_t)); ie_type=tptr[0]; ie_len=tptr[1]; printf("\n\tIE %s (%u), length %u: ", tok2str(mfr_ctrl_ie_values,"Unknown",ie_type), ie_type, ie_len);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -