print-atm.c revision 172686
129881Swollman/* 229881Swollman * Copyright (c) 1994, 1995, 1996, 1997 329881Swollman * The Regents of the University of California. All rights reserved. 429881Swollman * 529881Swollman * Redistribution and use in source and binary forms, with or without 629881Swollman * modification, are permitted provided that: (1) source code distributions 729881Swollman * retain the above copyright notice and this paragraph in its entirety, (2) 829881Swollman * distributions including binary code include the above copyright notice and 929881Swollman * this paragraph in its entirety in the documentation or other materials 1029881Swollman * provided with the distribution, and (3) all advertising materials mentioning 1129881Swollman * features or use of this software display the following acknowledgement: 1229881Swollman * ``This product includes software developed by the University of California, 1329881Swollman * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 1429881Swollman * the University nor the names of its contributors may be used to endorse 1529881Swollman * or promote products derived from this software without specific prior 1629881Swollman * written permission. 1729881Swollman * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 1829881Swollman * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 1929881Swollman * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 2029881Swollman * 2129881Swollman * $FreeBSD: head/contrib/tcpdump/print-atm.c 172686 2007-10-16 02:31:48Z mlaier $ 2229881Swollman */ 2329881Swollman#ifndef lint 2429881Swollmanstatic const char rcsid[] _U_ = 2529881Swollman "@(#) $Header: /tcpdump/master/tcpdump/print-atm.c,v 1.38.2.6 2006/01/25 13:27:24 hannes Exp $ (LBL)"; 2629881Swollman#endif 2729881Swollman 2829881Swollman#ifdef HAVE_CONFIG_H 2929881Swollman#include "config.h" 3029881Swollman#endif 3129881Swollman 3229881Swollman#include <tcpdump-stdinc.h> 3329881Swollman 34126229Sbde#include <stdio.h> 35126229Sbde#include <pcap.h> 36126229Sbde#include <string.h> 37126229Sbde 38126229Sbde#include "interface.h" 39126229Sbde#include "extract.h" 40126229Sbde#include "addrtoname.h" 41126229Sbde#include "ethertype.h" 42126229Sbde#include "atm.h" 4387715Smarkm#include "atmuni31.h" 4487715Smarkm#include "llc.h" 4587715Smarkm 4629881Swollman#include "ether.h" 4729881Swollman 4829881Swollmanstruct tok oam_f_values[] = { 4929881Swollman { OAMF4SC, "OAM F4 (segment)" }, 5029881Swollman { OAMF4EC, "OAM F4 (end)" }, 5129881Swollman { 0, NULL } 5229881Swollman}; 5329881Swollman 5429881Swollmanstruct tok oam_celltype_values[] = { 5529881Swollman { 0x1, "Fault Management" }, 5629881Swollman { 0x2, "Performance Management" }, 5729881Swollman { 0x8, "activate/deactivate" }, 5829881Swollman { 0xf, "System Management" }, 5929881Swollman { 0, NULL } 6029881Swollman}; 6129881Swollman 6229881Swollmanstruct tok oam_fm_functype_values[] = { 6387715Smarkm { 0x0, "AIS" }, 6429881Swollman { 0x1, "RDI" }, 6529881Swollman { 0x4, "Continuity Check" }, 6629881Swollman { 0x8, "Loopback" }, 6729881Swollman { 0, NULL } 6829881Swollman}; 6929881Swollman 7029881Swollmanstruct tok oam_pm_functype_values[] = { 7129881Swollman { 0x0, "Forward Monitoring" }, 7229881Swollman { 0x1, "Backward Reporting" }, 73158160Sbde { 0x2, "Monitoring and Reporting" }, 74158160Sbde { 0, NULL } 75158160Sbde}; 76158160Sbde 77158160Sbdestruct tok oam_ad_functype_values[] = { 78158160Sbde { 0x0, "Performance Monitoring" }, 79158160Sbde { 0x1, "Continuity Check" }, 80158160Sbde { 0, NULL } 81158160Sbde}; 82158160Sbde 83158160Sbdestatic const struct tok *oam_functype_values[16] = { 84158160Sbde NULL, 85158160Sbde oam_fm_functype_values, /* 1 */ 86158160Sbde oam_pm_functype_values, /* 2 */ 87158160Sbde NULL, 88158160Sbde NULL, 89158160Sbde NULL, 90158160Sbde NULL, 91158160Sbde NULL, 92158160Sbde oam_ad_functype_values, /* 8 */ 9329881Swollman NULL, 9429881Swollman NULL, 9529881Swollman NULL, 9629881Swollman NULL, 9729881Swollman NULL, 9829881Swollman NULL, 9929881Swollman NULL 100158160Sbde}; 10129881Swollman 10229881Swollman/* 10329881Swollman * Print an RFC 1483 LLC-encapsulated ATM frame. 10429881Swollman */ 10529881Swollmanstatic void 10629881Swollmanatm_llc_print(const u_char *p, int length, int caplen) 10729881Swollman{ 10829881Swollman u_short extracted_ethertype; 10929881Swollman 11029881Swollman if (!llc_print(p, length, caplen, NULL, NULL, 111158160Sbde &extracted_ethertype)) { 11229881Swollman /* ether_type not known, print raw packet */ 11329881Swollman if (extracted_ethertype) { 11429881Swollman printf("(LLC %s) ", 11529881Swollman etherproto_string(htons(extracted_ethertype))); 11629881Swollman } 11729881Swollman if (!suppress_default_print) 11829881Swollman default_print(p, caplen); 11929881Swollman } 120158160Sbde} 121158160Sbde 122158160Sbde/* 123158160Sbde * Given a SAP value, generate the LLC header value for a UI packet 124158160Sbde * with that SAP as the source and destination SAP. 125158160Sbde */ 126158160Sbde#define LLC_UI_HDR(sap) ((sap)<<16 | (sap<<8) | 0x03) 127158160Sbde 128158160Sbde/* 129158160Sbde * This is the top level routine of the printer. 'p' points 130158160Sbde * to the LLC/SNAP header of the packet, 'h->ts' is the timestamp, 131158160Sbde * 'h->len' is the length of the packet off the wire, and 'h->caplen' 132158160Sbde * is the number of bytes actually captured. 133158160Sbde */ 134158160Sbdeu_int 135158160Sbdeatm_if_print(const struct pcap_pkthdr *h, const u_char *p) 136158160Sbde{ 137158160Sbde u_int caplen = h->caplen; 138158160Sbde u_int length = h->len; 139158160Sbde u_int32_t llchdr; 14029881Swollman u_int hdrlen = 0; 14129881Swollman 14229881Swollman if (caplen < 8) { 14329881Swollman printf("[|atm]"); 14429881Swollman return (caplen); 14529881Swollman } 14629881Swollman 14729881Swollman /* Cisco Style NLPID ? */ 14840060Sobrien if (*p == LLC_UI) { 14929881Swollman if (eflag) 15029881Swollman printf("CNLPID "); 15129881Swollman isoclns_print(p+1, length-1, caplen-1); 15229881Swollman return hdrlen; 15329881Swollman } 15429881Swollman 15529881Swollman /* 15629881Swollman * Extract the presumed LLC header into a variable, for quick 15729881Swollman * testing. 15829881Swollman * Then check for a header that's neither a header for a SNAP 15929881Swollman * packet nor an RFC 2684 routed NLPID-formatted PDU nor 16029881Swollman * an 802.2-but-no-SNAP IP packet. 16129881Swollman */ 16229881Swollman llchdr = EXTRACT_24BITS(p); 16329881Swollman if (llchdr != LLC_UI_HDR(LLCSAP_SNAP) && 16429881Swollman llchdr != LLC_UI_HDR(LLCSAP_ISONS) && 16529881Swollman llchdr != LLC_UI_HDR(LLCSAP_IP)) { 16629881Swollman /* 16729881Swollman * XXX - assume 802.6 MAC header from Fore driver. 16829881Swollman * 16929881Swollman * Unfortunately, the above list doesn't check for 17029881Swollman * all known SAPs, doesn't check for headers where 17129881Swollman * the source and destination SAP aren't the same, 17229881Swollman * and doesn't check for non-UI frames. It also 17329881Swollman * runs the risk of an 802.6 MAC header that happens 17429881Swollman * to begin with one of those values being 17529881Swollman * incorrectly treated as an 802.2 header. 17629881Swollman * 17729881Swollman * So is that Fore driver still around? And, if so, 17829881Swollman * is it still putting 802.6 MAC headers on ATM 17929881Swollman * packets? If so, could it be changed to use a 18029881Swollman * new DLT_IEEE802_6 value if we added it? 18129881Swollman */ 18229881Swollman if (eflag) 18329881Swollman printf("%08x%08x %08x%08x ", 18429881Swollman EXTRACT_32BITS(p), 18529881Swollman EXTRACT_32BITS(p+4), 18629881Swollman EXTRACT_32BITS(p+8), 18729881Swollman EXTRACT_32BITS(p+12)); 18829881Swollman p += 20; 18929881Swollman length -= 20; 19029881Swollman caplen -= 20; 19129881Swollman hdrlen += 20; 19229881Swollman } 19329881Swollman atm_llc_print(p, length, caplen); 19429881Swollman return (hdrlen); 19529881Swollman} 19629881Swollman 19729881Swollman/* 19829881Swollman * ATM signalling. 19929881Swollman */ 20029881Swollmanstatic struct tok msgtype2str[] = { 20129881Swollman { CALL_PROCEED, "Call_proceeding" }, 20229881Swollman { CONNECT, "Connect" }, 20329881Swollman { CONNECT_ACK, "Connect_ack" }, 20429881Swollman { SETUP, "Setup" }, 20529881Swollman { RELEASE, "Release" }, 20629881Swollman { RELEASE_DONE, "Release_complete" }, 20729881Swollman { RESTART, "Restart" }, 20829881Swollman { RESTART_ACK, "Restart_ack" }, 20929881Swollman { STATUS, "Status" }, 21029881Swollman { STATUS_ENQ, "Status_enquiry" }, 21129881Swollman { ADD_PARTY, "Add_party" }, 21229881Swollman { ADD_PARTY_ACK, "Add_party_ack" }, 21329881Swollman { ADD_PARTY_REJ, "Add_party_reject" }, 21429881Swollman { DROP_PARTY, "Drop_party" }, 21529881Swollman { DROP_PARTY_ACK, "Drop_party_ack" }, 21629881Swollman { 0, NULL } 21729881Swollman}; 21829881Swollman 21929881Swollmanstatic void 22029881Swollmansig_print(const u_char *p, int caplen) 22129881Swollman{ 22229881Swollman bpf_u_int32 call_ref; 22329881Swollman 22429881Swollman if (caplen < PROTO_POS) { 22529881Swollman printf("[|atm]"); 22629881Swollman return; 22729881Swollman } 22829881Swollman if (p[PROTO_POS] == Q2931) { 22929881Swollman /* 23029881Swollman * protocol:Q.2931 for User to Network Interface 23129881Swollman * (UNI 3.1) signalling 23229881Swollman */ 23329881Swollman printf("Q.2931"); 23429881Swollman if (caplen < MSG_TYPE_POS) { 23529881Swollman printf(" [|atm]"); 23629881Swollman return; 23729881Swollman } 23829881Swollman printf(":%s ", 23929881Swollman tok2str(msgtype2str, "msgtype#%d", p[MSG_TYPE_POS])); 24029881Swollman 24129881Swollman if (caplen < CALL_REF_POS+3) { 24229881Swollman printf("[|atm]"); 243158160Sbde return; 244158160Sbde } 245158160Sbde call_ref = EXTRACT_24BITS(&p[CALL_REF_POS]); 246158160Sbde printf("CALL_REF:0x%06x", call_ref); 247158160Sbde } else { 248158160Sbde /* SCCOP with some unknown protocol atop it */ 249158160Sbde printf("SSCOP, proto %d ", p[PROTO_POS]); 250158160Sbde } 251158160Sbde} 252158160Sbde 253158160Sbde/* 254158160Sbde * Print an ATM PDU (such as an AAL5 PDU). 255158160Sbde */ 256158160Sbdevoid 257158160Sbdeatm_print(u_int vpi, u_int vci, u_int traftype, const u_char *p, u_int length, 258158160Sbde u_int caplen) 259158160Sbde{ 260158160Sbde if (eflag) 261158160Sbde printf("VPI:%u VCI:%u ", vpi, vci); 26229881Swollman 26329881Swollman if (vpi == 0) { 26429881Swollman switch (vci) { 26529881Swollman 26629881Swollman case PPC: 26729881Swollman sig_print(p, caplen); 26829881Swollman return; 26929881Swollman 27029881Swollman case BCC: 27129881Swollman printf("broadcast sig: "); 27229881Swollman return; 27329881Swollman 27429881Swollman case OAMF4SC: /* fall through */ 27529881Swollman case OAMF4EC: 27629881Swollman oam_print(p, length, ATM_OAM_HEC); 27729881Swollman return; 27829881Swollman 27929881Swollman case METAC: 28029881Swollman printf("meta: "); 28129881Swollman return; 28229881Swollman 28329881Swollman case ILMIC: 28429881Swollman printf("ilmi: "); 28529881Swollman snmp_print(p, length); 28629881Swollman return; 28729881Swollman } 28829881Swollman } 28929881Swollman 29029881Swollman switch (traftype) { 29129881Swollman 29229881Swollman case ATM_LLC: 29329881Swollman default: 29429881Swollman /* 29529881Swollman * Assumes traffic is LLC if unknown. 29629881Swollman */ 29729881Swollman atm_llc_print(p, length, caplen); 29829881Swollman break; 29929881Swollman 30029881Swollman case ATM_LANE: 30129881Swollman lane_print(p, length, caplen); 30229881Swollman break; 30329881Swollman } 30429881Swollman} 30529881Swollman 30629881Swollmanint 30729881Swollmanoam_print (const u_char *p, u_int length, u_int hec) { 30829881Swollman 30929881Swollman u_int32_t cell_header; 31029881Swollman u_int16_t cell_type, func_type,vpi,vci,payload,clp; 31129881Swollman 31229881Swollman cell_header = EXTRACT_32BITS(p+hec); 31329881Swollman cell_type = ((*(p+4+hec))>>4) & 0x0f; 31429881Swollman func_type = *(p+4+hec) & 0x0f; 31529881Swollman 31629881Swollman vpi = (cell_header>>20)&0xff; 31729881Swollman vci = (cell_header>>4)&0xffff; 31829881Swollman payload = (cell_header>>1)&0x7; 31929881Swollman clp = cell_header&0x1; 32029881Swollman 32129881Swollman printf("%s, vpi %u, vci %u, payload %u, clp %u, ", 32229881Swollman tok2str(oam_f_values, "OAM F5", vci), 32329881Swollman vpi, vci, payload, clp); 32429881Swollman 32529881Swollman printf("cell-type %s (%u)", 32629881Swollman tok2str(oam_celltype_values, "unknown", cell_type), 32729881Swollman cell_type); 32829881Swollman 32929881Swollman if (oam_functype_values[cell_type] == NULL) 330 printf(", func-type unknown (%u)", func_type); 331 else 332 printf(", func-type %s (%u)", 333 bittok2str(oam_functype_values[cell_type],"none",func_type), 334 func_type); 335 336 printf(", length %u",length); 337 return 1; 338} 339