print-ppp.c revision 235530
117680Spst/* 239300Sfenner * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997 317680Spst * The Regents of the University of California. All rights reserved. 417680Spst * 517680Spst * Redistribution and use in source and binary forms, with or without 617680Spst * modification, are permitted provided that: (1) source code distributions 717680Spst * retain the above copyright notice and this paragraph in its entirety, (2) 817680Spst * distributions including binary code include the above copyright notice and 917680Spst * this paragraph in its entirety in the documentation or other materials 1017680Spst * provided with the distribution, and (3) all advertising materials mentioning 1117680Spst * features or use of this software display the following acknowledgement: 1217680Spst * ``This product includes software developed by the University of California, 1317680Spst * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 1417680Spst * the University nor the names of its contributors may be used to endorse 1517680Spst * or promote products derived from this software without specific prior 1617680Spst * written permission. 1717680Spst * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 1817680Spst * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 1917680Spst * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 2053146Sbrian * 2175118Sfenner * Extensively modified by Motonori Shindo (mshindo@mshindo.net) for more 2275118Sfenner * complete PPP support. 2375118Sfenner * 2453146Sbrian * $FreeBSD: head/contrib/tcpdump/print-ppp.c 235530 2012-05-17 05:11:57Z delphij $ 2517680Spst */ 2617680Spst 2775118Sfenner/* 2875118Sfenner * TODO: 2975118Sfenner * o resolve XXX as much as possible 3075118Sfenner * o MP support 3175118Sfenner * o BAP support 3275118Sfenner */ 3375118Sfenner 3417680Spst#ifndef lint 35127675Sbmsstatic const char rcsid[] _U_ = 36190207Srpaulo "@(#) $Header: /tcpdump/master/tcpdump/print-ppp.c,v 1.114 2005-12-05 11:35:58 hannes Exp $ (LBL)"; 3717680Spst#endif 3817680Spst 3956896Sfenner#ifdef HAVE_CONFIG_H 4056896Sfenner#include "config.h" 4156896Sfenner#endif 4256896Sfenner 43127675Sbms#include <tcpdump-stdinc.h> 4417680Spst 4575118Sfenner#ifdef __bsdi__ 4675118Sfenner#include <net/slcompress.h> 4775118Sfenner#include <net/if_ppp.h> 4817680Spst#endif 4917680Spst 5017680Spst#include <pcap.h> 5117680Spst#include <stdio.h> 52146778Ssam#include <stdlib.h> 5317680Spst 5417680Spst#include "interface.h" 5556896Sfenner#include "extract.h" 5617680Spst#include "addrtoname.h" 5739300Sfenner#include "ppp.h" 5875118Sfenner#include "chdlc.h" 5975118Sfenner#include "ethertype.h" 60146778Ssam#include "oui.h" 6117680Spst 6275118Sfenner/* 6375118Sfenner * The following constatns are defined by IANA. Please refer to 6475118Sfenner * http://www.isi.edu/in-notes/iana/assignments/ppp-numbers 6575118Sfenner * for the up-to-date information. 6675118Sfenner */ 6717680Spst 68127675Sbms/* Protocol Codes defined in ppp.h */ 6917692Spst 70127675Sbmsstruct tok ppptype2str[] = { 71127675Sbms { PPP_IP, "IP" }, 72127675Sbms { PPP_OSI, "OSI" }, 73127675Sbms { PPP_NS, "NS" }, 74127675Sbms { PPP_DECNET, "DECNET" }, 75127675Sbms { PPP_APPLE, "APPLE" }, 76127675Sbms { PPP_IPX, "IPX" }, 77146778Ssam { PPP_VJC, "VJC IP" }, 78146778Ssam { PPP_VJNC, "VJNC IP" }, 79127675Sbms { PPP_BRPDU, "BRPDU" }, 80127675Sbms { PPP_STII, "STII" }, 81127675Sbms { PPP_VINES, "VINES" }, 82127675Sbms { PPP_MPLS_UCAST, "MPLS" }, 83127675Sbms { PPP_MPLS_MCAST, "MPLS" }, 84146778Ssam { PPP_COMP, "Compressed"}, 85146778Ssam { PPP_ML, "MLPPP"}, 86146778Ssam { PPP_IPV6, "IP6"}, 87127675Sbms 88127675Sbms { PPP_HELLO, "HELLO" }, 89127675Sbms { PPP_LUXCOM, "LUXCOM" }, 90127675Sbms { PPP_SNS, "SNS" }, 91127675Sbms { PPP_IPCP, "IPCP" }, 92127675Sbms { PPP_OSICP, "OSICP" }, 93127675Sbms { PPP_NSCP, "NSCP" }, 94127675Sbms { PPP_DECNETCP, "DECNETCP" }, 95127675Sbms { PPP_APPLECP, "APPLECP" }, 96127675Sbms { PPP_IPXCP, "IPXCP" }, 97127675Sbms { PPP_STIICP, "STIICP" }, 98127675Sbms { PPP_VINESCP, "VINESCP" }, 99146778Ssam { PPP_IPV6CP, "IP6CP" }, 100127675Sbms { PPP_MPLSCP, "MPLSCP" }, 101127675Sbms 102127675Sbms { PPP_LCP, "LCP" }, 103127675Sbms { PPP_PAP, "PAP" }, 104127675Sbms { PPP_LQM, "LQM" }, 105127675Sbms { PPP_CHAP, "CHAP" }, 106146778Ssam { PPP_EAP, "EAP" }, 107146778Ssam { PPP_SPAP, "SPAP" }, 108146778Ssam { PPP_SPAP_OLD, "Old-SPAP" }, 109127675Sbms { PPP_BACP, "BACP" }, 110127675Sbms { PPP_BAP, "BAP" }, 111146778Ssam { PPP_MPCP, "MLPPP-CP" }, 112127675Sbms { 0, NULL } 113127675Sbms}; 114127675Sbms 115127675Sbms/* Control Protocols (LCP/IPCP/CCP etc.) Codes defined in RFC 1661 */ 116127675Sbms 11775118Sfenner#define CPCODES_VEXT 0 /* Vendor-Specific (RFC2153) */ 11875118Sfenner#define CPCODES_CONF_REQ 1 /* Configure-Request */ 11975118Sfenner#define CPCODES_CONF_ACK 2 /* Configure-Ack */ 12075118Sfenner#define CPCODES_CONF_NAK 3 /* Configure-Nak */ 12175118Sfenner#define CPCODES_CONF_REJ 4 /* Configure-Reject */ 12275118Sfenner#define CPCODES_TERM_REQ 5 /* Terminate-Request */ 12375118Sfenner#define CPCODES_TERM_ACK 6 /* Terminate-Ack */ 12475118Sfenner#define CPCODES_CODE_REJ 7 /* Code-Reject */ 12575118Sfenner#define CPCODES_PROT_REJ 8 /* Protocol-Reject (LCP only) */ 12675118Sfenner#define CPCODES_ECHO_REQ 9 /* Echo-Request (LCP only) */ 12775118Sfenner#define CPCODES_ECHO_RPL 10 /* Echo-Reply (LCP only) */ 12875118Sfenner#define CPCODES_DISC_REQ 11 /* Discard-Request (LCP only) */ 129127675Sbms#define CPCODES_ID 12 /* Identification (LCP only) RFC1570 */ 130127675Sbms#define CPCODES_TIME_REM 13 /* Time-Remaining (LCP only) RFC1570 */ 131127675Sbms#define CPCODES_RESET_REQ 14 /* Reset-Request (CCP only) RFC1962 */ 13275118Sfenner#define CPCODES_RESET_REP 15 /* Reset-Reply (CCP only) */ 13338638Sthepish 134127675Sbmsstruct tok cpcodes[] = { 135127675Sbms {CPCODES_VEXT, "Vendor-Extension"}, /* RFC2153 */ 136127675Sbms {CPCODES_CONF_REQ, "Conf-Request"}, 137127675Sbms {CPCODES_CONF_ACK, "Conf-Ack"}, 138127675Sbms {CPCODES_CONF_NAK, "Conf-Nack"}, 139127675Sbms {CPCODES_CONF_REJ, "Conf-Reject"}, 140127675Sbms {CPCODES_TERM_REQ, "Term-Request"}, 141127675Sbms {CPCODES_TERM_ACK, "Term-Ack"}, 142127675Sbms {CPCODES_CODE_REJ, "Code-Reject"}, 143127675Sbms {CPCODES_PROT_REJ, "Prot-Reject"}, 144127675Sbms {CPCODES_ECHO_REQ, "Echo-Request"}, 145127675Sbms {CPCODES_ECHO_RPL, "Echo-Reply"}, 146127675Sbms {CPCODES_DISC_REQ, "Disc-Req"}, 147127675Sbms {CPCODES_ID, "Ident"}, /* RFC1570 */ 148127675Sbms {CPCODES_TIME_REM, "Time-Rem"}, /* RFC1570 */ 149127675Sbms {CPCODES_RESET_REQ, "Reset-Req"}, /* RFC1962 */ 150127675Sbms {CPCODES_RESET_REP, "Reset-Ack"}, /* RFC1962 */ 151127675Sbms {0, NULL} 15238638Sthepish}; 15338638Sthepish 15475118Sfenner/* LCP Config Options */ 15575118Sfenner 15638638Sthepish#define LCPOPT_VEXT 0 15738638Sthepish#define LCPOPT_MRU 1 15838638Sthepish#define LCPOPT_ACCM 2 15938638Sthepish#define LCPOPT_AP 3 16038638Sthepish#define LCPOPT_QP 4 16138638Sthepish#define LCPOPT_MN 5 16275118Sfenner#define LCPOPT_DEP6 6 16338638Sthepish#define LCPOPT_PFC 7 16438638Sthepish#define LCPOPT_ACFC 8 16575118Sfenner#define LCPOPT_FCSALT 9 16675118Sfenner#define LCPOPT_SDP 10 16775118Sfenner#define LCPOPT_NUMMODE 11 16875118Sfenner#define LCPOPT_DEP12 12 16975118Sfenner#define LCPOPT_CBACK 13 17075118Sfenner#define LCPOPT_DEP14 14 17175118Sfenner#define LCPOPT_DEP15 15 17275118Sfenner#define LCPOPT_DEP16 16 17375118Sfenner#define LCPOPT_MLMRRU 17 17475118Sfenner#define LCPOPT_MLSSNHF 18 17575118Sfenner#define LCPOPT_MLED 19 17675118Sfenner#define LCPOPT_PROP 20 17775118Sfenner#define LCPOPT_DCEID 21 17875118Sfenner#define LCPOPT_MPP 22 17975118Sfenner#define LCPOPT_LD 23 18075118Sfenner#define LCPOPT_LCPAOPT 24 18175118Sfenner#define LCPOPT_COBS 25 18275118Sfenner#define LCPOPT_PE 26 18375118Sfenner#define LCPOPT_MLHF 27 18475118Sfenner#define LCPOPT_I18N 28 18575118Sfenner#define LCPOPT_SDLOS 29 18675118Sfenner#define LCPOPT_PPPMUX 30 18738638Sthepish 18875118Sfenner#define LCPOPT_MIN LCPOPT_VEXT 18975118Sfenner#define LCPOPT_MAX LCPOPT_PPPMUX 19038638Sthepish 19175118Sfennerstatic const char *lcpconfopts[] = { 19275118Sfenner "Vend-Ext", /* (0) */ 19375118Sfenner "MRU", /* (1) */ 19475118Sfenner "ACCM", /* (2) */ 19575118Sfenner "Auth-Prot", /* (3) */ 19675118Sfenner "Qual-Prot", /* (4) */ 19775118Sfenner "Magic-Num", /* (5) */ 19875118Sfenner "deprecated(6)", /* used to be a Quality Protocol */ 19975118Sfenner "PFC", /* (7) */ 20075118Sfenner "ACFC", /* (8) */ 20175118Sfenner "FCS-Alt", /* (9) */ 20275118Sfenner "SDP", /* (10) */ 20375118Sfenner "Num-Mode", /* (11) */ 20475118Sfenner "deprecated(12)", /* used to be a Multi-Link-Procedure*/ 20575118Sfenner "Call-Back", /* (13) */ 20675118Sfenner "deprecated(14)", /* used to be a Connect-Time */ 20775118Sfenner "deprecated(15)", /* used to be a Compund-Frames */ 20875118Sfenner "deprecated(16)", /* used to be a Nominal-Data-Encap */ 20975118Sfenner "MRRU", /* (17) */ 210146778Ssam "12-Bit seq #", /* (18) */ 21175118Sfenner "End-Disc", /* (19) */ 21275118Sfenner "Proprietary", /* (20) */ 21375118Sfenner "DCE-Id", /* (21) */ 21475118Sfenner "MP+", /* (22) */ 21575118Sfenner "Link-Disc", /* (23) */ 21675118Sfenner "LCP-Auth-Opt", /* (24) */ 21775118Sfenner "COBS", /* (25) */ 21875118Sfenner "Prefix-elision", /* (26) */ 21975118Sfenner "Multilink-header-Form",/* (27) */ 22075118Sfenner "I18N", /* (28) */ 22175118Sfenner "SDL-over-SONET/SDH", /* (29) */ 22275118Sfenner "PPP-Muxing", /* (30) */ 22338638Sthepish}; 22438638Sthepish 22575118Sfenner/* ECP - to be supported */ 22675118Sfenner 22775118Sfenner/* CCP Config Options */ 22875118Sfenner 22975118Sfenner#define CCPOPT_OUI 0 /* RFC1962 */ 23075118Sfenner#define CCPOPT_PRED1 1 /* RFC1962 */ 23175118Sfenner#define CCPOPT_PRED2 2 /* RFC1962 */ 23275118Sfenner#define CCPOPT_PJUMP 3 /* RFC1962 */ 23375118Sfenner/* 4-15 unassigned */ 23475118Sfenner#define CCPOPT_HPPPC 16 /* RFC1962 */ 23575118Sfenner#define CCPOPT_STACLZS 17 /* RFC1974 */ 23675118Sfenner#define CCPOPT_MPPC 18 /* RFC2118 */ 23775118Sfenner#define CCPOPT_GFZA 19 /* RFC1962 */ 23875118Sfenner#define CCPOPT_V42BIS 20 /* RFC1962 */ 23975118Sfenner#define CCPOPT_BSDCOMP 21 /* RFC1977 */ 24075118Sfenner/* 22 unassigned */ 24175118Sfenner#define CCPOPT_LZSDCP 23 /* RFC1967 */ 24275118Sfenner#define CCPOPT_MVRCA 24 /* RFC1975 */ 24375118Sfenner#define CCPOPT_DEC 25 /* RFC1976 */ 24475118Sfenner#define CCPOPT_DEFLATE 26 /* RFC1979 */ 24575118Sfenner/* 27-254 unassigned */ 24675118Sfenner#define CCPOPT_RESV 255 /* RFC1962 */ 24775118Sfenner 248147904Ssamconst struct tok ccpconfopts_values[] = { 249147904Ssam { CCPOPT_OUI, "OUI" }, 250147904Ssam { CCPOPT_PRED1, "Pred-1" }, 251147904Ssam { CCPOPT_PRED2, "Pred-2" }, 252147904Ssam { CCPOPT_PJUMP, "Puddle" }, 253147904Ssam { CCPOPT_HPPPC, "HP-PPC" }, 254147904Ssam { CCPOPT_STACLZS, "Stac-LZS" }, 255147904Ssam { CCPOPT_MPPC, "MPPC" }, 256147904Ssam { CCPOPT_GFZA, "Gand-FZA" }, 257147904Ssam { CCPOPT_V42BIS, "V.42bis" }, 258147904Ssam { CCPOPT_BSDCOMP, "BSD-Comp" }, 259147904Ssam { CCPOPT_LZSDCP, "LZS-DCP" }, 260147904Ssam { CCPOPT_MVRCA, "MVRCA" }, 261147904Ssam { CCPOPT_DEC, "DEC" }, 262147904Ssam { CCPOPT_DEFLATE, "Deflate" }, 263147904Ssam { CCPOPT_RESV, "Reserved"}, 264147904Ssam {0, NULL} 26575118Sfenner}; 26675118Sfenner 26775118Sfenner/* BACP Config Options */ 26875118Sfenner 26975118Sfenner#define BACPOPT_FPEER 1 /* RFC2125 */ 27075118Sfenner 271147904Ssamconst struct tok bacconfopts_values[] = { 272147904Ssam { BACPOPT_FPEER, "Favored-Peer" }, 273147904Ssam {0, NULL} 274147904Ssam}; 275147904Ssam 276147904Ssam 27775118Sfenner/* SDCP - to be supported */ 27875118Sfenner 27975118Sfenner/* IPCP Config Options */ 28075118Sfenner#define IPCPOPT_2ADDR 1 /* RFC1172, RFC1332 (deprecated) */ 28175118Sfenner#define IPCPOPT_IPCOMP 2 /* RFC1332 */ 28275118Sfenner#define IPCPOPT_ADDR 3 /* RFC1332 */ 28375118Sfenner#define IPCPOPT_MOBILE4 4 /* RFC2290 */ 28475118Sfenner#define IPCPOPT_PRIDNS 129 /* RFC1877 */ 28575118Sfenner#define IPCPOPT_PRINBNS 130 /* RFC1877 */ 28675118Sfenner#define IPCPOPT_SECDNS 131 /* RFC1877 */ 28775118Sfenner#define IPCPOPT_SECNBNS 132 /* RFC1877 */ 28875118Sfenner 289146778Ssamstruct tok ipcpopt_values[] = { 290146778Ssam { IPCPOPT_2ADDR, "IP-Addrs" }, 291146778Ssam { IPCPOPT_IPCOMP, "IP-Comp" }, 292146778Ssam { IPCPOPT_ADDR, "IP-Addr" }, 293146778Ssam { IPCPOPT_MOBILE4, "Home-Addr" }, 294146778Ssam { IPCPOPT_PRIDNS, "Pri-DNS" }, 295146778Ssam { IPCPOPT_PRINBNS, "Pri-NBNS" }, 296146778Ssam { IPCPOPT_SECDNS, "Sec-DNS" }, 297146778Ssam { IPCPOPT_SECNBNS, "Sec-NBNS" }, 298146778Ssam { 0, NULL } 299146778Ssam}; 300146778Ssam 301172686Smlaier#define IPCPOPT_IPCOMP_HDRCOMP 0x61 /* rfc3544 */ 302172686Smlaier#define IPCPOPT_IPCOMP_MINLEN 14 303146778Ssam 304172686Smlaierstruct tok ipcpopt_compproto_values[] = { 305172686Smlaier { PPP_VJC, "VJ-Comp" }, 306172686Smlaier { IPCPOPT_IPCOMP_HDRCOMP, "IP Header Compression" }, 307172686Smlaier { 0, NULL } 308172686Smlaier}; 309172686Smlaier 310172686Smlaierstruct tok ipcpopt_compproto_subopt_values[] = { 311172686Smlaier { 1, "RTP-Compression" }, 312172686Smlaier { 2, "Enhanced RTP-Compression" }, 313172686Smlaier { 0, NULL } 314172686Smlaier}; 315172686Smlaier 316146778Ssam/* IP6CP Config Options */ 317146778Ssam#define IP6CP_IFID 1 318146778Ssam 319146778Ssamstruct tok ip6cpopt_values[] = { 320146778Ssam { IP6CP_IFID, "Interface-ID" }, 321146778Ssam { 0, NULL } 322146778Ssam}; 323146778Ssam 32475118Sfenner/* ATCP - to be supported */ 32575118Sfenner/* OSINLCP - to be supported */ 32675118Sfenner/* BVCP - to be supported */ 32775118Sfenner/* BCP - to be supported */ 32875118Sfenner/* IPXCP - to be supported */ 329127675Sbms/* MPLSCP - to be supported */ 33075118Sfenner 33175118Sfenner/* Auth Algorithms */ 33275118Sfenner 33375118Sfenner/* 0-4 Reserved (RFC1994) */ 33475118Sfenner#define AUTHALG_CHAPMD5 5 /* RFC1994 */ 33575118Sfenner#define AUTHALG_MSCHAP1 128 /* RFC2433 */ 33675118Sfenner#define AUTHALG_MSCHAP2 129 /* RFC2795 */ 33775118Sfenner 338146778Ssamstruct tok authalg_values[] = { 339146778Ssam { AUTHALG_CHAPMD5, "MD5" }, 340146778Ssam { AUTHALG_MSCHAP1, "MS-CHAPv1" }, 341146778Ssam { AUTHALG_MSCHAP2, "MS-CHAPv2" }, 342146778Ssam { 0, NULL } 343146778Ssam}; 344146778Ssam 34575118Sfenner/* FCS Alternatives - to be supported */ 34675118Sfenner 34775118Sfenner/* Multilink Endpoint Discriminator (RFC1717) */ 34875118Sfenner#define MEDCLASS_NULL 0 /* Null Class */ 34975118Sfenner#define MEDCLASS_LOCAL 1 /* Locally Assigned */ 35075118Sfenner#define MEDCLASS_IPV4 2 /* Internet Protocol (IPv4) */ 35175118Sfenner#define MEDCLASS_MAC 3 /* IEEE 802.1 global MAC address */ 35275118Sfenner#define MEDCLASS_MNB 4 /* PPP Magic Number Block */ 35375118Sfenner#define MEDCLASS_PSNDN 5 /* Public Switched Network Director Number */ 35475118Sfenner 35575118Sfenner/* PPP LCP Callback */ 35675118Sfenner#define CALLBACK_AUTH 0 /* Location determined by user auth */ 35775118Sfenner#define CALLBACK_DSTR 1 /* Dialing string */ 35875118Sfenner#define CALLBACK_LID 2 /* Location identifier */ 35975118Sfenner#define CALLBACK_E164 3 /* E.164 number */ 36075118Sfenner#define CALLBACK_X500 4 /* X.500 distinguished name */ 36175118Sfenner#define CALLBACK_CBCP 6 /* Location is determined during CBCP nego */ 36275118Sfenner 363147904Ssamstruct tok ppp_callback_values[] = { 364147904Ssam { CALLBACK_AUTH, "UserAuth" }, 365147904Ssam { CALLBACK_DSTR, "DialString" }, 366147904Ssam { CALLBACK_LID, "LocalID" }, 367147904Ssam { CALLBACK_E164, "E.164" }, 368147904Ssam { CALLBACK_X500, "X.500" }, 369147904Ssam { CALLBACK_CBCP, "CBCP" }, 370147904Ssam { 0, NULL } 371147904Ssam}; 372147904Ssam 37338638Sthepish/* CHAP */ 37438638Sthepish 37538638Sthepish#define CHAP_CHAL 1 37638638Sthepish#define CHAP_RESP 2 37738638Sthepish#define CHAP_SUCC 3 37838638Sthepish#define CHAP_FAIL 4 37938638Sthepish 380146778Ssamstruct tok chapcode_values[] = { 381146778Ssam { CHAP_CHAL, "Challenge" }, 382146778Ssam { CHAP_RESP, "Response" }, 383146778Ssam { CHAP_SUCC, "Success" }, 384146778Ssam { CHAP_FAIL, "Fail" }, 385146778Ssam { 0, NULL} 38638638Sthepish}; 38738638Sthepish 38838638Sthepish/* PAP */ 38938638Sthepish 39038638Sthepish#define PAP_AREQ 1 39138638Sthepish#define PAP_AACK 2 39238638Sthepish#define PAP_ANAK 3 39338638Sthepish 394146778Ssamstruct tok papcode_values[] = { 395146778Ssam { PAP_AREQ, "Auth-Req" }, 396146778Ssam { PAP_AACK, "Auth-ACK" }, 397146778Ssam { PAP_ANAK, "Auth-NACK" }, 398146778Ssam { 0, NULL } 39938638Sthepish}; 40038638Sthepish 40175118Sfenner/* BAP */ 40275118Sfenner#define BAP_CALLREQ 1 40375118Sfenner#define BAP_CALLRES 2 40475118Sfenner#define BAP_CBREQ 3 40575118Sfenner#define BAP_CBRES 4 40675118Sfenner#define BAP_LDQREQ 5 40775118Sfenner#define BAP_LDQRES 6 40875118Sfenner#define BAP_CSIND 7 40975118Sfenner#define BAP_CSRES 8 41038638Sthepish 41175118Sfennerstatic void handle_ctrl_proto (u_int proto,const u_char *p, int length); 41275118Sfennerstatic void handle_chap (const u_char *p, int length); 41375118Sfennerstatic void handle_pap (const u_char *p, int length); 41475118Sfennerstatic void handle_bap (const u_char *p, int length); 415146778Ssamstatic void handle_mlppp(const u_char *p, int length); 41675118Sfennerstatic int print_lcp_config_options (const u_char *p, int); 41775118Sfennerstatic int print_ipcp_config_options (const u_char *p, int); 418146778Ssamstatic int print_ip6cp_config_options (const u_char *p, int); 41975118Sfennerstatic int print_ccp_config_options (const u_char *p, int); 42075118Sfennerstatic int print_bacp_config_options (const u_char *p, int); 42175118Sfennerstatic void handle_ppp (u_int proto, const u_char *p, int length); 422146778Ssamstatic void ppp_hdlc(const u_char *p, int length); 42338638Sthepish 42475118Sfenner/* generic Control Protocol (e.g. LCP, IPCP, CCP, etc.) handler */ 42556896Sfennerstatic void 426127675Sbmshandle_ctrl_proto(u_int proto, const u_char *pptr, int length) 42717680Spst{ 428127675Sbms const char *typestr; 42975118Sfenner u_int code, len; 43075118Sfenner int (*pfunc)(const u_char *, int); 43138638Sthepish int x, j; 432127675Sbms const u_char *tptr; 43317680Spst 434127675Sbms tptr=pptr; 43532149Spst 436146778Ssam typestr = tok2str(ppptype2str, "unknown ctrl-proto (0x%04x)", proto); 437127675Sbms printf("%s, ",typestr); 43832149Spst 439127675Sbms if (length < 4) /* FIXME weak boundary checking */ 440127675Sbms goto trunc; 441127675Sbms TCHECK2(*tptr, 2); 44275118Sfenner 443127675Sbms code = *tptr++; 444127675Sbms 445147904Ssam printf("%s (0x%02x), id %u, length %u", 446127675Sbms tok2str(cpcodes, "Unknown Opcode",code), 447147904Ssam code, 448147904Ssam *tptr++, /* ID */ 449147904Ssam length+2); 45075118Sfenner 451147904Ssam if (!vflag) 452147904Ssam return; 453147904Ssam 454147904Ssam if (length <= 4) 455147904Ssam return; /* there may be a NULL confreq etc. */ 456147904Ssam 457127675Sbms TCHECK2(*tptr, 2); 458127675Sbms len = EXTRACT_16BITS(tptr); 459127675Sbms tptr += 2; 460127675Sbms 461147904Ssam printf("\n\tencoded length %u (=Option(s) length %u)",len,len-4); 46275118Sfenner 463147904Ssam if (vflag>1) 464147904Ssam print_unknown_data(pptr-2,"\n\t",6); 465147904Ssam 466147904Ssam 46775118Sfenner switch (code) { 46875118Sfenner case CPCODES_VEXT: 46975118Sfenner if (length < 11) 47075118Sfenner break; 471127675Sbms TCHECK2(*tptr, 4); 472147904Ssam printf("\n\t Magic-Num 0x%08x", EXTRACT_32BITS(tptr)); 473127675Sbms tptr += 4; 474127675Sbms TCHECK2(*tptr, 3); 475146778Ssam printf(" Vendor: %s (%u)", 476146778Ssam tok2str(oui_values,"Unknown",EXTRACT_24BITS(tptr)), 477146778Ssam EXTRACT_24BITS(tptr)); 47875118Sfenner /* XXX: need to decode Kind and Value(s)? */ 47975118Sfenner break; 48075118Sfenner case CPCODES_CONF_REQ: 48175118Sfenner case CPCODES_CONF_ACK: 48275118Sfenner case CPCODES_CONF_NAK: 48375118Sfenner case CPCODES_CONF_REJ: 48475118Sfenner x = len - 4; /* Code(1), Identifier(1) and Length(2) */ 48556896Sfenner do { 48675118Sfenner switch (proto) { 48775118Sfenner case PPP_LCP: 48875118Sfenner pfunc = print_lcp_config_options; 48956896Sfenner break; 49075118Sfenner case PPP_IPCP: 49175118Sfenner pfunc = print_ipcp_config_options; 49275118Sfenner break; 493146778Ssam case PPP_IPV6CP: 494146778Ssam pfunc = print_ip6cp_config_options; 495146778Ssam break; 49675118Sfenner case PPP_CCP: 49775118Sfenner pfunc = print_ccp_config_options; 49875118Sfenner break; 49975118Sfenner case PPP_BACP: 50075118Sfenner pfunc = print_bacp_config_options; 50175118Sfenner break; 50275118Sfenner default: 50375118Sfenner /* 504146778Ssam * No print routine for the options for 505146778Ssam * this protocol. 50675118Sfenner */ 50775118Sfenner pfunc = NULL; 50875118Sfenner break; 50975118Sfenner } 510140744Sbms 511146778Ssam if (pfunc == NULL) /* catch the above null pointer if unknown CP */ 512146778Ssam break; 513146778Ssam 514127675Sbms if ((j = (*pfunc)(tptr, len)) == 0) 51575118Sfenner break; 51656896Sfenner x -= j; 517127675Sbms tptr += j; 51856896Sfenner } while (x > 0); 51956896Sfenner break; 52032149Spst 52175118Sfenner case CPCODES_TERM_REQ: 52275118Sfenner case CPCODES_TERM_ACK: 52375118Sfenner /* XXX: need to decode Data? */ 52456896Sfenner break; 52575118Sfenner case CPCODES_CODE_REJ: 52675118Sfenner /* XXX: need to decode Rejected-Packet? */ 52775118Sfenner break; 52875118Sfenner case CPCODES_PROT_REJ: 52975118Sfenner if (length < 6) 53075118Sfenner break; 531127675Sbms TCHECK2(*tptr, 2); 532147904Ssam printf("\n\t Rejected %s Protocol (0x%04x)", 533127675Sbms tok2str(ppptype2str,"unknown", EXTRACT_16BITS(tptr)), 534127675Sbms EXTRACT_16BITS(tptr)); 535147904Ssam /* XXX: need to decode Rejected-Information? - hexdump for now */ 536147904Ssam if (len > 6) { 537147904Ssam printf("\n\t Rejected Packet"); 538147904Ssam print_unknown_data(tptr+2,"\n\t ",len-2); 539147904Ssam } 54075118Sfenner break; 54175118Sfenner case CPCODES_ECHO_REQ: 54275118Sfenner case CPCODES_ECHO_RPL: 54375118Sfenner case CPCODES_DISC_REQ: 544147904Ssam if (length < 8) 545147904Ssam break; 546147904Ssam TCHECK2(*tptr, 4); 547147904Ssam printf("\n\t Magic-Num 0x%08x", EXTRACT_32BITS(tptr)); 548147904Ssam /* XXX: need to decode Data? - hexdump for now */ 549147904Ssam if (len > 8) { 550172686Smlaier printf("\n\t -----trailing data-----"); 551172686Smlaier TCHECK2(tptr[4], len-8); 552172686Smlaier print_unknown_data(tptr+4,"\n\t ",len-8); 553147904Ssam } 554147904Ssam break; 55575118Sfenner case CPCODES_ID: 55675118Sfenner if (length < 8) 55775118Sfenner break; 558127675Sbms TCHECK2(*tptr, 4); 559147904Ssam printf("\n\t Magic-Num 0x%08x", EXTRACT_32BITS(tptr)); 560147904Ssam /* RFC 1661 says this is intended to be human readable */ 561147904Ssam if (len > 8) { 562147904Ssam printf("\n\t Message\n\t "); 563147904Ssam fn_printn(tptr+4,len-4,snapend); 564147904Ssam } 56575118Sfenner break; 56675118Sfenner case CPCODES_TIME_REM: 56775118Sfenner if (length < 12) 56875118Sfenner break; 569127675Sbms TCHECK2(*tptr, 4); 570147904Ssam printf("\n\t Magic-Num 0x%08x", EXTRACT_32BITS(tptr)); 571127675Sbms TCHECK2(*(tptr + 4), 4); 572127675Sbms printf(", Seconds-Remaining %us", EXTRACT_32BITS(tptr + 4)); 57375118Sfenner /* XXX: need to decode Message? */ 57475118Sfenner break; 57556896Sfenner default: 576127675Sbms /* XXX this is dirty but we do not get the 577127675Sbms * original pointer passed to the begin 578127675Sbms * the PPP packet */ 579127675Sbms if (vflag <= 1) 580147904Ssam print_unknown_data(pptr-2,"\n\t ",length+2); 58156896Sfenner break; 58238638Sthepish } 583127675Sbms return; 584127675Sbms 585127675Sbmstrunc: 586127675Sbms printf("[|%s]", typestr); 58738638Sthepish} 58832149Spst 58938638Sthepish/* LCP config options */ 59038638Sthepishstatic int 59175118Sfennerprint_lcp_config_options(const u_char *p, int length) 59238638Sthepish{ 59375118Sfenner int len, opt; 59475118Sfenner 59575118Sfenner if (length < 2) 59675118Sfenner return 0; 597127675Sbms TCHECK2(*p, 2); 59875118Sfenner len = p[1]; 59975118Sfenner opt = p[0]; 60075118Sfenner if (length < len) 60175118Sfenner return 0; 602147904Ssam if (len < 2) { 603147904Ssam if ((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX)) 604147904Ssam printf("\n\t %s Option (0x%02x), length %u (bogus, should be >= 2)", lcpconfopts[opt],opt,len); 605147904Ssam else 606147904Ssam printf("\n\tunknown LCP option 0x%02x", opt); 607147904Ssam return 0; 608147904Ssam } 60956896Sfenner if ((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX)) 610147904Ssam printf("\n\t %s Option (0x%02x), length %u: ", lcpconfopts[opt],opt,len); 61175118Sfenner else { 612147904Ssam printf("\n\tunknown LCP option 0x%02x", opt); 61375118Sfenner return len; 61475118Sfenner } 61538638Sthepish 61656896Sfenner switch (opt) { 61775118Sfenner case LCPOPT_VEXT: 61875118Sfenner if (len >= 6) { 619127675Sbms TCHECK2(*(p + 2), 3); 620147904Ssam printf("Vendor: %s (%u)", 621146778Ssam tok2str(oui_values,"Unknown",EXTRACT_24BITS(p+2)), 622146778Ssam EXTRACT_24BITS(p+2)); 62375118Sfenner#if 0 624127675Sbms TCHECK(p[5]); 625146778Ssam printf(", kind: 0x%02x", p[5]); 626146778Ssam printf(", Value: 0x") 62775118Sfenner for (i = 0; i < len - 6; i++) { 628127675Sbms TCHECK(p[6 + i]); 62975118Sfenner printf("%02x", p[6 + i]); 63075118Sfenner } 63175118Sfenner#endif 63275118Sfenner } 63375118Sfenner break; 63456896Sfenner case LCPOPT_MRU: 635127675Sbms if (len == 4) { 636127675Sbms TCHECK2(*(p + 2), 2); 637147904Ssam printf("%u", EXTRACT_16BITS(p + 2)); 638127675Sbms } 63956896Sfenner break; 64075118Sfenner case LCPOPT_ACCM: 641127675Sbms if (len == 6) { 642127675Sbms TCHECK2(*(p + 2), 4); 643147904Ssam printf("0x%08x", EXTRACT_32BITS(p + 2)); 644127675Sbms } 64575118Sfenner break; 64656896Sfenner case LCPOPT_AP: 64756896Sfenner if (len >= 4) { 648127675Sbms TCHECK2(*(p + 2), 2); 649147904Ssam printf("%s", tok2str(ppptype2str,"Unknown Auth Proto (0x04x)",EXTRACT_16BITS(p+2))); 650146778Ssam 651127675Sbms switch (EXTRACT_16BITS(p+2)) { 652127675Sbms case PPP_CHAP: 653127675Sbms TCHECK(p[4]); 654146778Ssam printf(", %s",tok2str(authalg_values,"Unknown Auth Alg %u",p[4])); 655127675Sbms break; 656146778Ssam case PPP_PAP: /* fall through */ 657127675Sbms case PPP_EAP: 658127675Sbms case PPP_SPAP: 659127675Sbms case PPP_SPAP_OLD: 660146778Ssam break; 661127675Sbms default: 662146778Ssam print_unknown_data(p,"\n\t",len); 663127675Sbms } 66456896Sfenner } 66556896Sfenner break; 66656896Sfenner case LCPOPT_QP: 66756896Sfenner if (len >= 4) { 668127675Sbms TCHECK2(*(p + 2), 2); 669127675Sbms if (EXTRACT_16BITS(p+2) == PPP_LQM) 67056896Sfenner printf(" LQR"); 67156896Sfenner else 67256896Sfenner printf(" unknown"); 67356896Sfenner } 67456896Sfenner break; 67556896Sfenner case LCPOPT_MN: 676127675Sbms if (len == 6) { 677127675Sbms TCHECK2(*(p + 2), 4); 678147904Ssam printf("0x%08x", EXTRACT_32BITS(p + 2)); 679127675Sbms } 68056896Sfenner break; 68156896Sfenner case LCPOPT_PFC: 68256896Sfenner break; 68356896Sfenner case LCPOPT_ACFC: 68456896Sfenner break; 68575118Sfenner case LCPOPT_LD: 686127675Sbms if (len == 4) { 687127675Sbms TCHECK2(*(p + 2), 2); 688147904Ssam printf("0x%04x", EXTRACT_16BITS(p + 2)); 689127675Sbms } 69075118Sfenner break; 69175118Sfenner case LCPOPT_CBACK: 69275118Sfenner if (len < 3) 69375118Sfenner break; 694127675Sbms TCHECK(p[2]); 695147904Ssam printf("Callback Operation %s (%u)", 696147904Ssam tok2str(ppp_callback_values,"Unknown",p[2]), 697147904Ssam p[2]); 69875118Sfenner break; 69975118Sfenner case LCPOPT_MLMRRU: 700127675Sbms if (len == 4) { 701127675Sbms TCHECK2(*(p + 2), 2); 702147904Ssam printf("%u", EXTRACT_16BITS(p + 2)); 703127675Sbms } 70475118Sfenner break; 70575118Sfenner case LCPOPT_MLED: 70675118Sfenner if (len < 3) 70775118Sfenner break; 708127675Sbms TCHECK(p[2]); 70975118Sfenner switch (p[2]) { /* class */ 71075118Sfenner case MEDCLASS_NULL: 711147904Ssam printf("Null"); 71275118Sfenner break; 71375118Sfenner case MEDCLASS_LOCAL: 714147904Ssam printf("Local"); /* XXX */ 71575118Sfenner break; 71675118Sfenner case MEDCLASS_IPV4: 71775118Sfenner if (len != 7) 71875118Sfenner break; 719127675Sbms TCHECK2(*(p + 3), 4); 720147904Ssam printf("IPv4 %s", ipaddr_string(p + 3)); 72175118Sfenner break; 72275118Sfenner case MEDCLASS_MAC: 72375118Sfenner if (len != 9) 72475118Sfenner break; 725127675Sbms TCHECK(p[8]); 726147904Ssam printf("MAC %02x:%02x:%02x:%02x:%02x:%02x", 72775118Sfenner p[3], p[4], p[5], p[6], p[7], p[8]); 72875118Sfenner break; 72975118Sfenner case MEDCLASS_MNB: 730147904Ssam printf("Magic-Num-Block"); /* XXX */ 73175118Sfenner break; 73275118Sfenner case MEDCLASS_PSNDN: 733147904Ssam printf("PSNDN"); /* XXX */ 73475118Sfenner break; 73575118Sfenner } 73675118Sfenner break; 73775118Sfenner 73875118Sfenner/* XXX: to be supported */ 73975118Sfenner#if 0 74075118Sfenner case LCPOPT_DEP6: 74175118Sfenner case LCPOPT_FCSALT: 74275118Sfenner case LCPOPT_SDP: 74375118Sfenner case LCPOPT_NUMMODE: 74475118Sfenner case LCPOPT_DEP12: 74575118Sfenner case LCPOPT_DEP14: 74675118Sfenner case LCPOPT_DEP15: 74775118Sfenner case LCPOPT_DEP16: 748146778Ssam case LCPOPT_MLSSNHF: 74975118Sfenner case LCPOPT_PROP: 75075118Sfenner case LCPOPT_DCEID: 75175118Sfenner case LCPOPT_MPP: 75275118Sfenner case LCPOPT_LCPAOPT: 75375118Sfenner case LCPOPT_COBS: 75475118Sfenner case LCPOPT_PE: 75575118Sfenner case LCPOPT_MLHF: 75675118Sfenner case LCPOPT_I18N: 75775118Sfenner case LCPOPT_SDLOS: 75875118Sfenner case LCPOPT_PPPMUX: 75975118Sfenner break; 76075118Sfenner#endif 761147904Ssam default: 762147904Ssam if(vflag<2) 763147904Ssam print_unknown_data(&p[2],"\n\t ",len-2); 764147904Ssam break; 76538638Sthepish } 766147904Ssam 767147904Ssam if (vflag>1) 768147904Ssam print_unknown_data(&p[2],"\n\t ",len-2); /* exclude TLV header */ 769147904Ssam 77056896Sfenner return len; 771127675Sbms 772127675Sbmstrunc: 773127675Sbms printf("[|lcp]"); 774127675Sbms return 0; 77538638Sthepish} 77638638Sthepish 777146778Ssam/* ML-PPP*/ 778146778Ssamstruct tok ppp_ml_flag_values[] = { 779146778Ssam { 0x80, "begin" }, 780146778Ssam { 0x40, "end" }, 781146778Ssam { 0, NULL } 782146778Ssam}; 783146778Ssam 784146778Ssamstatic void 785146778Ssamhandle_mlppp(const u_char *p, int length) { 786146778Ssam 787146778Ssam if (!eflag) 788146778Ssam printf("MLPPP, "); 789146778Ssam 790146778Ssam printf("seq 0x%03x, Flags [%s], length %u", 791146778Ssam (EXTRACT_16BITS(p))&0x0fff, /* only support 12-Bit sequence space for now */ 792146778Ssam bittok2str(ppp_ml_flag_values, "none", *p & 0xc0), 793146778Ssam length); 794146778Ssam 795146778Ssam return; 796146778Ssam} 797146778Ssam 79838638Sthepish/* CHAP */ 79956896Sfennerstatic void 80038638Sthepishhandle_chap(const u_char *p, int length) 80138638Sthepish{ 80275118Sfenner u_int code, len; 80375118Sfenner int val_size, name_size, msg_size; 80475118Sfenner const u_char *p0; 80575118Sfenner int i; 80638638Sthepish 80775118Sfenner p0 = p; 80875118Sfenner if (length < 1) { 80975118Sfenner printf("[|chap]"); 81075118Sfenner return; 81175118Sfenner } else if (length < 4) { 812127675Sbms TCHECK(*p); 81375118Sfenner printf("[|chap 0x%02x]", *p); 81475118Sfenner return; 81575118Sfenner } 81638638Sthepish 817127675Sbms TCHECK(*p); 81875118Sfenner code = *p; 819146778Ssam printf("CHAP, %s (0x%02x)", 820146778Ssam tok2str(chapcode_values,"unknown",code), 821146778Ssam code); 82275118Sfenner p++; 82332149Spst 824127675Sbms TCHECK(*p); 825146778Ssam printf(", id %u", *p); /* ID */ 82675118Sfenner p++; 82775118Sfenner 828127675Sbms TCHECK2(*p, 2); 82975118Sfenner len = EXTRACT_16BITS(p); 83075118Sfenner p += 2; 83175118Sfenner 83275118Sfenner /* 83375118Sfenner * Note that this is a generic CHAP decoding routine. Since we 83475118Sfenner * don't know which flavor of CHAP (i.e. CHAP-MD5, MS-CHAPv1, 83575118Sfenner * MS-CHAPv2) is used at this point, we can't decode packet 83675118Sfenner * specifically to each algorithms. Instead, we simply decode 83775118Sfenner * the GCD (Gratest Common Denominator) for all algorithms. 83875118Sfenner */ 83975118Sfenner switch (code) { 84056896Sfenner case CHAP_CHAL: 84156896Sfenner case CHAP_RESP: 84275118Sfenner if (length - (p - p0) < 1) 84375118Sfenner return; 844127675Sbms TCHECK(*p); 84575118Sfenner val_size = *p; /* value size */ 84675118Sfenner p++; 84775118Sfenner if (length - (p - p0) < val_size) 84875118Sfenner return; 849127675Sbms printf(", Value "); 850127675Sbms for (i = 0; i < val_size; i++) { 851127675Sbms TCHECK(*p); 85275118Sfenner printf("%02x", *p++); 853127675Sbms } 85475118Sfenner name_size = len - (p - p0); 855127675Sbms printf(", Name "); 856127675Sbms for (i = 0; i < name_size; i++) { 857127675Sbms TCHECK(*p); 85875118Sfenner safeputchar(*p++); 859127675Sbms } 86056896Sfenner break; 86175118Sfenner case CHAP_SUCC: 86275118Sfenner case CHAP_FAIL: 86375118Sfenner msg_size = len - (p - p0); 864127675Sbms printf(", Msg "); 865127675Sbms for (i = 0; i< msg_size; i++) { 866127675Sbms TCHECK(*p); 86775118Sfenner safeputchar(*p++); 868127675Sbms } 86975118Sfenner break; 87038638Sthepish } 871127675Sbms return; 872127675Sbms 873127675Sbmstrunc: 874127675Sbms printf("[|chap]"); 87538638Sthepish} 87638638Sthepish 87775118Sfenner/* PAP (see RFC 1334) */ 87856896Sfennerstatic void 87938638Sthepishhandle_pap(const u_char *p, int length) 88038638Sthepish{ 88175118Sfenner u_int code, len; 88275118Sfenner int peerid_len, passwd_len, msg_len; 88375118Sfenner const u_char *p0; 88475118Sfenner int i; 88538638Sthepish 88675118Sfenner p0 = p; 88775118Sfenner if (length < 1) { 88875118Sfenner printf("[|pap]"); 88975118Sfenner return; 89075118Sfenner } else if (length < 4) { 891127675Sbms TCHECK(*p); 89275118Sfenner printf("[|pap 0x%02x]", *p); 89375118Sfenner return; 89475118Sfenner } 89538638Sthepish 896127675Sbms TCHECK(*p); 89775118Sfenner code = *p; 898146778Ssam printf("PAP, %s (0x%02x)", 899146778Ssam tok2str(papcode_values,"unknown",code), 900146778Ssam code); 90175118Sfenner p++; 90238638Sthepish 903127675Sbms TCHECK(*p); 904146778Ssam printf(", id %u", *p); /* ID */ 90575118Sfenner p++; 90675118Sfenner 907127675Sbms TCHECK2(*p, 2); 90875118Sfenner len = EXTRACT_16BITS(p); 90975118Sfenner p += 2; 91075118Sfenner 911147904Ssam if ((int)len > length) { 912147904Ssam printf(", length %u > packet size", len); 913147904Ssam return; 914147904Ssam } 915147904Ssam length = len; 916147904Ssam if (length < (p - p0)) { 917147904Ssam printf(", length %u < PAP header length", length); 918147904Ssam return; 919147904Ssam } 920147904Ssam 92175118Sfenner switch (code) { 92256896Sfenner case PAP_AREQ: 92375118Sfenner if (length - (p - p0) < 1) 92475118Sfenner return; 925127675Sbms TCHECK(*p); 92675118Sfenner peerid_len = *p; /* Peer-ID Length */ 92775118Sfenner p++; 92875118Sfenner if (length - (p - p0) < peerid_len) 92975118Sfenner return; 930127675Sbms printf(", Peer "); 931127675Sbms for (i = 0; i < peerid_len; i++) { 932127675Sbms TCHECK(*p); 93375118Sfenner safeputchar(*p++); 934127675Sbms } 93575118Sfenner 93675118Sfenner if (length - (p - p0) < 1) 93775118Sfenner return; 938127675Sbms TCHECK(*p); 93975118Sfenner passwd_len = *p; /* Password Length */ 94075118Sfenner p++; 94175118Sfenner if (length - (p - p0) < passwd_len) 94275118Sfenner return; 943127675Sbms printf(", Name "); 944127675Sbms for (i = 0; i < passwd_len; i++) { 945127675Sbms TCHECK(*p); 94675118Sfenner safeputchar(*p++); 947127675Sbms } 94856896Sfenner break; 94956896Sfenner case PAP_AACK: 95056896Sfenner case PAP_ANAK: 95175118Sfenner if (length - (p - p0) < 1) 95275118Sfenner return; 953127675Sbms TCHECK(*p); 95475118Sfenner msg_len = *p; /* Msg-Length */ 95575118Sfenner p++; 95675118Sfenner if (length - (p - p0) < msg_len) 95775118Sfenner return; 958127675Sbms printf(", Msg "); 959127675Sbms for (i = 0; i< msg_len; i++) { 960127675Sbms TCHECK(*p); 96175118Sfenner safeputchar(*p++); 962127675Sbms } 96356896Sfenner break; 96438638Sthepish } 96575118Sfenner return; 966127675Sbms 967127675Sbmstrunc: 968127675Sbms printf("[|pap]"); 96938638Sthepish} 97038638Sthepish 97175118Sfenner/* BAP */ 97256896Sfennerstatic void 973127675Sbmshandle_bap(const u_char *p _U_, int length _U_) 97438638Sthepish{ 97575118Sfenner /* XXX: to be supported!! */ 97675118Sfenner} 97775118Sfenner 97875118Sfenner 97975118Sfenner/* IPCP config options */ 98075118Sfennerstatic int 98175118Sfennerprint_ipcp_config_options(const u_char *p, int length) 98275118Sfenner{ 98375118Sfenner int len, opt; 984172686Smlaier u_int compproto, ipcomp_subopttotallen, ipcomp_subopt, ipcomp_suboptlen; 98575118Sfenner 98675118Sfenner if (length < 2) 98775118Sfenner return 0; 988127675Sbms TCHECK2(*p, 2); 98975118Sfenner len = p[1]; 99075118Sfenner opt = p[0]; 99175118Sfenner if (length < len) 99275118Sfenner return 0; 993147904Ssam if (len < 2) { 994147904Ssam printf("\n\t %s Option (0x%02x), length %u (bogus, should be >= 2)", 995147904Ssam tok2str(ipcpopt_values,"unknown",opt), 996147904Ssam opt, 997147904Ssam len); 998147904Ssam return 0; 999147904Ssam } 1000146778Ssam 1001147904Ssam printf("\n\t %s Option (0x%02x), length %u: ", 1002146778Ssam tok2str(ipcpopt_values,"unknown",opt), 1003147904Ssam opt, 1004147904Ssam len); 1005146778Ssam 100675118Sfenner switch (opt) { 100775118Sfenner case IPCPOPT_2ADDR: /* deprecated */ 100875118Sfenner if (len != 10) 100975118Sfenner goto invlen; 1010127675Sbms TCHECK2(*(p + 6), 4); 1011146778Ssam printf("src %s, dst %s", 101275118Sfenner ipaddr_string(p + 2), 101375118Sfenner ipaddr_string(p + 6)); 101456896Sfenner break; 101575118Sfenner case IPCPOPT_IPCOMP: 101675118Sfenner if (len < 4) 101775118Sfenner goto invlen; 1018127675Sbms TCHECK2(*(p + 2), 2); 1019172686Smlaier compproto = EXTRACT_16BITS(p+2); 1020172686Smlaier 1021172686Smlaier printf("%s (0x%02x):", 1022172686Smlaier tok2str(ipcpopt_compproto_values,"Unknown",compproto), 1023172686Smlaier compproto); 1024172686Smlaier 1025172686Smlaier switch (compproto) { 1026172686Smlaier case PPP_VJC: 102775118Sfenner /* XXX: VJ-Comp parameters should be decoded */ 1028172686Smlaier break; 1029172686Smlaier case IPCPOPT_IPCOMP_HDRCOMP: 1030172686Smlaier if (len < IPCPOPT_IPCOMP_MINLEN) 1031172686Smlaier goto invlen; 1032172686Smlaier 1033172686Smlaier TCHECK2(*(p + 2), IPCPOPT_IPCOMP_MINLEN); 1034172686Smlaier printf("\n\t TCP Space %u, non-TCP Space %u" \ 1035172686Smlaier ", maxPeriod %u, maxTime %u, maxHdr %u", 1036172686Smlaier EXTRACT_16BITS(p+4), 1037172686Smlaier EXTRACT_16BITS(p+6), 1038172686Smlaier EXTRACT_16BITS(p+8), 1039172686Smlaier EXTRACT_16BITS(p+10), 1040172686Smlaier EXTRACT_16BITS(p+12)); 1041172686Smlaier 1042172686Smlaier /* suboptions present ? */ 1043172686Smlaier if (len > IPCPOPT_IPCOMP_MINLEN) { 1044172686Smlaier ipcomp_subopttotallen = len - IPCPOPT_IPCOMP_MINLEN; 1045172686Smlaier p += IPCPOPT_IPCOMP_MINLEN; 1046172686Smlaier 1047172686Smlaier printf("\n\t Suboptions, length %u", ipcomp_subopttotallen); 1048172686Smlaier 1049172686Smlaier while (ipcomp_subopttotallen >= 2) { 1050172686Smlaier TCHECK2(*p, 2); 1051172686Smlaier ipcomp_subopt = *p; 1052172686Smlaier ipcomp_suboptlen = *(p+1); 1053172686Smlaier 1054172686Smlaier /* sanity check */ 1055172686Smlaier if (ipcomp_subopt == 0 || 1056172686Smlaier ipcomp_suboptlen == 0 ) 1057172686Smlaier break; 1058172686Smlaier 1059172686Smlaier /* XXX: just display the suboptions for now */ 1060172686Smlaier printf("\n\t\t%s Suboption #%u, length %u", 1061172686Smlaier tok2str(ipcpopt_compproto_subopt_values, 1062172686Smlaier "Unknown", 1063172686Smlaier ipcomp_subopt), 1064172686Smlaier ipcomp_subopt, 1065172686Smlaier ipcomp_suboptlen); 1066172686Smlaier 1067172686Smlaier ipcomp_subopttotallen -= ipcomp_suboptlen; 1068172686Smlaier p += ipcomp_suboptlen; 1069172686Smlaier } 1070172686Smlaier } 1071172686Smlaier break; 1072172686Smlaier default: 1073172686Smlaier break; 1074172686Smlaier } 107556896Sfenner break; 1076146778Ssam 1077146778Ssam case IPCPOPT_ADDR: /* those options share the same format - fall through */ 107875118Sfenner case IPCPOPT_MOBILE4: 107975118Sfenner case IPCPOPT_PRIDNS: 108075118Sfenner case IPCPOPT_PRINBNS: 108175118Sfenner case IPCPOPT_SECDNS: 108275118Sfenner case IPCPOPT_SECNBNS: 108375118Sfenner if (len != 6) 108475118Sfenner goto invlen; 1085127675Sbms TCHECK2(*(p + 2), 4); 1086146778Ssam printf("%s", ipaddr_string(p + 2)); 108775118Sfenner break; 108875118Sfenner default: 1089147904Ssam if(vflag<2) 1090147904Ssam print_unknown_data(&p[2],"\n\t ",len-2); 109175118Sfenner break; 109275118Sfenner } 1093147904Ssam if (vflag>1) 1094147904Ssam print_unknown_data(&p[2],"\n\t ",len-2); /* exclude TLV header */ 109575118Sfenner return len; 109638638Sthepish 109775118Sfennerinvlen: 109875118Sfenner printf(", invalid-length-%d", opt); 109975118Sfenner return 0; 1100127675Sbms 1101127675Sbmstrunc: 1102127675Sbms printf("[|ipcp]"); 1103127675Sbms return 0; 110475118Sfenner} 110575118Sfenner 1106146778Ssam/* IP6CP config options */ 1107146778Ssamstatic int 1108146778Ssamprint_ip6cp_config_options(const u_char *p, int length) 1109146778Ssam{ 1110146778Ssam int len, opt; 1111146778Ssam 1112146778Ssam if (length < 2) 1113146778Ssam return 0; 1114146778Ssam TCHECK2(*p, 2); 1115146778Ssam len = p[1]; 1116146778Ssam opt = p[0]; 1117146778Ssam if (length < len) 1118146778Ssam return 0; 1119147904Ssam if (len < 2) { 1120147904Ssam printf("\n\t %s Option (0x%02x), length %u (bogus, should be >= 2)", 1121147904Ssam tok2str(ip6cpopt_values,"unknown",opt), 1122147904Ssam opt, 1123147904Ssam len); 1124147904Ssam return 0; 1125147904Ssam } 1126146778Ssam 1127147904Ssam printf("\n\t %s Option (0x%02x), length %u: ", 1128146778Ssam tok2str(ip6cpopt_values,"unknown",opt), 1129147904Ssam opt, 1130147904Ssam len); 1131146778Ssam 1132146778Ssam switch (opt) { 1133146778Ssam case IP6CP_IFID: 1134146778Ssam if (len != 10) 1135146778Ssam goto invlen; 1136146778Ssam TCHECK2(*(p + 2), 8); 1137146778Ssam printf("%04x:%04x:%04x:%04x", 1138146778Ssam EXTRACT_16BITS(p + 2), 1139146778Ssam EXTRACT_16BITS(p + 4), 1140146778Ssam EXTRACT_16BITS(p + 6), 1141146778Ssam EXTRACT_16BITS(p + 8)); 1142146778Ssam break; 1143146778Ssam default: 1144147904Ssam if(vflag<2) 1145147904Ssam print_unknown_data(&p[2],"\n\t ",len-2); 1146146778Ssam break; 1147146778Ssam } 1148147904Ssam if (vflag>1) 1149147904Ssam print_unknown_data(&p[2],"\n\t ",len-2); /* exclude TLV header */ 1150147904Ssam 1151146778Ssam return len; 1152146778Ssam 1153146778Ssaminvlen: 1154146778Ssam printf(", invalid-length-%d", opt); 1155146778Ssam return 0; 1156146778Ssam 1157146778Ssamtrunc: 1158146778Ssam printf("[|ip6cp]"); 1159146778Ssam return 0; 1160146778Ssam} 1161146778Ssam 1162146778Ssam 116375118Sfenner/* CCP config options */ 116475118Sfennerstatic int 116575118Sfennerprint_ccp_config_options(const u_char *p, int length) 116675118Sfenner{ 116775118Sfenner int len, opt; 116875118Sfenner 116975118Sfenner if (length < 2) 117075118Sfenner return 0; 1171127675Sbms TCHECK2(*p, 2); 117275118Sfenner len = p[1]; 117375118Sfenner opt = p[0]; 117475118Sfenner if (length < len) 117575118Sfenner return 0; 1176147904Ssam if (len < 2) { 1177147904Ssam printf("\n\t %s Option (0x%02x), length %u (bogus, should be >= 2)", 1178147904Ssam tok2str(ccpconfopts_values, "Unknown", opt), 1179147904Ssam opt, 1180147904Ssam len); 1181147904Ssam return 0; 1182147904Ssam } 1183147904Ssam 1184147904Ssam printf("\n\t %s Option (0x%02x), length %u:", 1185147904Ssam tok2str(ccpconfopts_values, "Unknown", opt), 1186147904Ssam opt, 1187147904Ssam len); 1188147904Ssam 118975118Sfenner switch (opt) { 1190147904Ssam /* fall through --> default: nothing supported yet */ 119175118Sfenner case CCPOPT_OUI: 119275118Sfenner case CCPOPT_PRED1: 119375118Sfenner case CCPOPT_PRED2: 119475118Sfenner case CCPOPT_PJUMP: 119575118Sfenner case CCPOPT_HPPPC: 119675118Sfenner case CCPOPT_STACLZS: 119775118Sfenner case CCPOPT_MPPC: 119875118Sfenner case CCPOPT_GFZA: 119975118Sfenner case CCPOPT_V42BIS: 120075118Sfenner case CCPOPT_BSDCOMP: 120175118Sfenner case CCPOPT_LZSDCP: 120275118Sfenner case CCPOPT_MVRCA: 120375118Sfenner case CCPOPT_DEC: 120475118Sfenner case CCPOPT_DEFLATE: 120575118Sfenner case CCPOPT_RESV: 120675118Sfenner default: 1207147904Ssam if(vflag<2) 1208147904Ssam print_unknown_data(&p[2],"\n\t ",len-2); 120975118Sfenner break; 121038638Sthepish } 1211147904Ssam if (vflag>1) 1212147904Ssam print_unknown_data(&p[2],"\n\t ",len-2); /* exclude TLV header */ 1213147904Ssam 121475118Sfenner return len; 1215127675Sbms 1216127675Sbmstrunc: 1217127675Sbms printf("[|ccp]"); 1218127675Sbms return 0; 121938638Sthepish} 122075118Sfenner 122175118Sfenner/* BACP config options */ 122275118Sfennerstatic int 122375118Sfennerprint_bacp_config_options(const u_char *p, int length) 122475118Sfenner{ 122575118Sfenner int len, opt; 122675118Sfenner 122775118Sfenner if (length < 2) 122875118Sfenner return 0; 1229127675Sbms TCHECK2(*p, 2); 123075118Sfenner len = p[1]; 123175118Sfenner opt = p[0]; 123275118Sfenner if (length < len) 123375118Sfenner return 0; 1234147904Ssam if (len < 2) { 1235147904Ssam printf("\n\t %s Option (0x%02x), length %u (bogus, should be >= 2)", 1236147904Ssam tok2str(bacconfopts_values, "Unknown", opt), 1237147904Ssam opt, 1238147904Ssam len); 1239147904Ssam return 0; 1240147904Ssam } 1241147904Ssam 1242147904Ssam printf("\n\t %s Option (0x%02x), length %u:", 1243147904Ssam tok2str(bacconfopts_values, "Unknown", opt), 1244147904Ssam opt, 1245147904Ssam len); 1246147904Ssam 1247147904Ssam switch (opt) { 1248147904Ssam case BACPOPT_FPEER: 1249127675Sbms TCHECK2(*(p + 2), 4); 1250127675Sbms printf(", Magic-Num 0x%08x", EXTRACT_32BITS(p + 2)); 1251147904Ssam break; 1252147904Ssam default: 1253147904Ssam if(vflag<2) 1254147904Ssam print_unknown_data(&p[2],"\n\t ",len-2); 1255147904Ssam break; 125675118Sfenner } 1257147904Ssam if (vflag>1) 1258147904Ssam print_unknown_data(&p[2],"\n\t ",len-2); /* exclude TLV header */ 1259147904Ssam 126075118Sfenner return len; 1261127675Sbms 1262127675Sbmstrunc: 1263127675Sbms printf("[|bacp]"); 1264127675Sbms return 0; 126575118Sfenner} 126675118Sfenner 126775118Sfenner 1268146778Ssamstatic void 1269146778Ssamppp_hdlc(const u_char *p, int length) 1270146778Ssam{ 1271146778Ssam u_char *b, *s, *t, c; 1272146778Ssam int i, proto; 1273146778Ssam const void *se; 1274146778Ssam 1275146778Ssam b = (u_int8_t *)malloc(length); 1276146778Ssam if (b == NULL) 1277146778Ssam return; 1278146778Ssam 1279146778Ssam /* 1280146778Ssam * Unescape all the data into a temporary, private, buffer. 1281146778Ssam * Do this so that we dont overwrite the original packet 1282146778Ssam * contents. 1283146778Ssam */ 1284146778Ssam for (s = (u_char *)p, t = b, i = length; i > 0; i--) { 1285146778Ssam c = *s++; 1286146778Ssam if (c == 0x7d) { 1287146778Ssam if (i > 1) { 1288146778Ssam i--; 1289146778Ssam c = *s++ ^ 0x20; 1290146778Ssam } else 1291146778Ssam continue; 1292146778Ssam } 1293146778Ssam *t++ = c; 1294146778Ssam } 1295146778Ssam 1296146778Ssam se = snapend; 1297146778Ssam snapend = t; 1298146778Ssam 1299146778Ssam /* now lets guess about the payload codepoint format */ 1300146778Ssam proto = *b; /* start with a one-octet codepoint guess */ 1301146778Ssam 1302146778Ssam switch (proto) { 1303146778Ssam case PPP_IP: 1304146778Ssam ip_print(gndo, b+1, t - b - 1); 1305146778Ssam goto cleanup; 1306146778Ssam#ifdef INET6 1307146778Ssam case PPP_IPV6: 1308235530Sdelphij ip6_print(gndo, b+1, t - b - 1); 1309235530Sdelphij goto cleanup; 1310146778Ssam#endif 1311146778Ssam default: /* no luck - try next guess */ 1312235530Sdelphij break; 1313146778Ssam } 1314146778Ssam 1315146778Ssam proto = EXTRACT_16BITS(b); /* next guess - load two octets */ 1316146778Ssam 1317146778Ssam switch (proto) { 1318146778Ssam case (PPP_ADDRESS << 8 | PPP_CONTROL): /* looks like a PPP frame */ 1319146778Ssam proto = EXTRACT_16BITS(b+2); /* load the PPP proto-id */ 1320146778Ssam handle_ppp(proto, b+4, t - b - 4); 1321146778Ssam break; 1322146778Ssam default: /* last guess - proto must be a PPP proto-id */ 1323146778Ssam handle_ppp(proto, b+2, t - b - 2); 1324146778Ssam break; 1325146778Ssam } 1326146778Ssam 1327146778Ssamcleanup: 1328146778Ssam snapend = se; 1329146778Ssam free(b); 1330146778Ssam return; 1331146778Ssam} 1332146778Ssam 1333146778Ssam 133475118Sfenner/* PPP */ 133575118Sfennerstatic void 133675118Sfennerhandle_ppp(u_int proto, const u_char *p, int length) 133775118Sfenner{ 1338146778Ssam if ((proto & 0xff00) == 0x7e00) {/* is this an escape code ? */ 1339146778Ssam ppp_hdlc(p-1, length); 1340146778Ssam return; 1341146778Ssam } 1342146778Ssam 134375118Sfenner switch (proto) { 1344146778Ssam case PPP_LCP: /* fall through */ 134575118Sfenner case PPP_IPCP: 1346127675Sbms case PPP_OSICP: 1347127675Sbms case PPP_MPLSCP: 1348127675Sbms case PPP_IPV6CP: 134975118Sfenner case PPP_CCP: 135075118Sfenner case PPP_BACP: 135175118Sfenner handle_ctrl_proto(proto, p, length); 135275118Sfenner break; 1353146778Ssam case PPP_ML: 1354146778Ssam handle_mlppp(p, length); 1355146778Ssam break; 135675118Sfenner case PPP_CHAP: 135775118Sfenner handle_chap(p, length); 135875118Sfenner break; 135975118Sfenner case PPP_PAP: 136075118Sfenner handle_pap(p, length); 136175118Sfenner break; 136275118Sfenner case PPP_BAP: /* XXX: not yet completed */ 136375118Sfenner handle_bap(p, length); 136475118Sfenner break; 136575118Sfenner case ETHERTYPE_IP: /*XXX*/ 1366146778Ssam case PPP_VJNC: 136775118Sfenner case PPP_IP: 1368146778Ssam ip_print(gndo, p, length); 136975118Sfenner break; 137075118Sfenner#ifdef INET6 137175118Sfenner case ETHERTYPE_IPV6: /*XXX*/ 137275118Sfenner case PPP_IPV6: 1373235530Sdelphij ip6_print(gndo, p, length); 137475118Sfenner break; 137575118Sfenner#endif 137675118Sfenner case ETHERTYPE_IPX: /*XXX*/ 137775118Sfenner case PPP_IPX: 137875118Sfenner ipx_print(p, length); 137975118Sfenner break; 138098527Sfenner case PPP_OSI: 1381127675Sbms isoclns_print(p, length, length); 138298527Sfenner break; 1383127675Sbms case PPP_MPLS_UCAST: 1384127675Sbms case PPP_MPLS_MCAST: 1385127675Sbms mpls_print(p, length); 1386127675Sbms break; 1387146778Ssam case PPP_COMP: 1388146778Ssam printf("compressed PPP data"); 1389146778Ssam break; 139098527Sfenner default: 1391146778Ssam printf("%s ", tok2str(ppptype2str, "unknown PPP protocol (0x%04x)", proto)); 1392146778Ssam print_unknown_data(p,"\n\t",length); 1393146778Ssam break; 139475118Sfenner } 139575118Sfenner} 139675118Sfenner 139756896Sfenner/* Standard PPP printer */ 1398127675Sbmsu_int 139975118Sfennerppp_print(register const u_char *p, u_int length) 140075118Sfenner{ 1401146778Ssam u_int proto,ppp_header; 1402127675Sbms u_int olen = length; /* _o_riginal length */ 1403127675Sbms u_int hdr_len = 0; 140475118Sfenner 140575118Sfenner /* 140675118Sfenner * Here, we assume that p points to the Address and Control 140775118Sfenner * field (if they present). 140875118Sfenner */ 140975118Sfenner if (length < 2) 141075118Sfenner goto trunc; 1411127675Sbms TCHECK2(*p, 2); 1412146778Ssam ppp_header = EXTRACT_16BITS(p); 141375118Sfenner 1414146778Ssam switch(ppp_header) { 1415146778Ssam case (PPP_WITHDIRECTION_IN << 8 | PPP_CONTROL): 1416146778Ssam if (eflag) printf("In "); 1417146778Ssam p += 2; 1418146778Ssam length -= 2; 1419146778Ssam hdr_len += 2; 1420146778Ssam break; 1421146778Ssam case (PPP_WITHDIRECTION_OUT << 8 | PPP_CONTROL): 1422146778Ssam if (eflag) printf("Out "); 1423146778Ssam p += 2; 1424146778Ssam length -= 2; 1425146778Ssam hdr_len += 2; 1426146778Ssam break; 1427146778Ssam case (PPP_ADDRESS << 8 | PPP_CONTROL): 1428146778Ssam p += 2; /* ACFC not used */ 1429146778Ssam length -= 2; 1430146778Ssam hdr_len += 2; 1431146778Ssam break; 1432146778Ssam 1433146778Ssam default: 1434146778Ssam break; 1435146778Ssam } 1436146778Ssam 143775118Sfenner if (length < 2) 143875118Sfenner goto trunc; 1439127675Sbms TCHECK(*p); 144075118Sfenner if (*p % 2) { 144175118Sfenner proto = *p; /* PFC is used */ 144275118Sfenner p++; 144375118Sfenner length--; 1444127675Sbms hdr_len++; 144575118Sfenner } else { 1446127675Sbms TCHECK2(*p, 2); 144775118Sfenner proto = EXTRACT_16BITS(p); 144875118Sfenner p += 2; 144975118Sfenner length -= 2; 1450127675Sbms hdr_len += 2; 145175118Sfenner } 145275118Sfenner 1453127675Sbms if (eflag) 1454146778Ssam printf("%s (0x%04x), length %u: ", 1455127675Sbms tok2str(ppptype2str, "unknown", proto), 1456127675Sbms proto, 1457127675Sbms olen); 145875118Sfenner 145975118Sfenner handle_ppp(proto, p, length); 1460127675Sbms return (hdr_len); 146175118Sfennertrunc: 146275118Sfenner printf("[|ppp]"); 1463127675Sbms return (0); 146475118Sfenner} 146575118Sfenner 146675118Sfenner 146775118Sfenner/* PPP I/F printer */ 1468127675Sbmsu_int 1469127675Sbmsppp_if_print(const struct pcap_pkthdr *h, register const u_char *p) 147038638Sthepish{ 147138638Sthepish register u_int length = h->len; 147238638Sthepish register u_int caplen = h->caplen; 147338638Sthepish 147417680Spst if (caplen < PPP_HDRLEN) { 147575118Sfenner printf("[|ppp]"); 1476127675Sbms return (caplen); 147717680Spst } 147817680Spst 147975118Sfenner#if 0 148075118Sfenner /* 148175118Sfenner * XXX: seems to assume that there are 2 octets prepended to an 148275118Sfenner * actual PPP frame. The 1st octet looks like Input/Output flag 148375118Sfenner * while 2nd octet is unknown, at least to me 148475118Sfenner * (mshindo@mshindo.net). 148575118Sfenner * 148675118Sfenner * That was what the original tcpdump code did. 148775118Sfenner * 148875118Sfenner * FreeBSD's "if_ppp.c" *does* set the first octet to 1 for outbound 148975118Sfenner * packets and 0 for inbound packets - but only if the 149075118Sfenner * protocol field has the 0x8000 bit set (i.e., it's a network 149175118Sfenner * control protocol); it does so before running the packet through 149275118Sfenner * "bpf_filter" to see if it should be discarded, and to see 149375118Sfenner * if we should update the time we sent the most recent packet... 149475118Sfenner * 149575118Sfenner * ...but it puts the original address field back after doing 149675118Sfenner * so. 149775118Sfenner * 149875118Sfenner * NetBSD's "if_ppp.c" doesn't set the first octet in that fashion. 149975118Sfenner * 150075118Sfenner * I don't know if any PPP implementation handed up to a BPF 150175118Sfenner * device packets with the first octet being 1 for outbound and 150275118Sfenner * 0 for inbound packets, so I (guy@alum.mit.edu) don't know 150375118Sfenner * whether that ever needs to be checked or not. 150475118Sfenner * 150575118Sfenner * Note that NetBSD has a DLT_PPP_SERIAL, which it uses for PPP, 150675118Sfenner * and its tcpdump appears to assume that the frame always 150775118Sfenner * begins with an address field and a control field, and that 150875118Sfenner * the address field might be 0x0f or 0x8f, for Cisco 150975118Sfenner * point-to-point with HDLC framing as per section 4.3.1 of RFC 151075118Sfenner * 1547, as well as 0xff, for PPP in HDLC-like framing as per 151175118Sfenner * RFC 1662. 151275118Sfenner * 151375118Sfenner * (Is the Cisco framing in question what DLT_C_HDLC, in 151475118Sfenner * BSD/OS, is?) 151575118Sfenner */ 151675118Sfenner if (eflag) 151775118Sfenner printf("%c %4d %02x ", p[0] ? 'O' : 'I', length, p[1]); 151875118Sfenner#endif 151975118Sfenner 152075118Sfenner ppp_print(p, length); 152175118Sfenner 1522127675Sbms return (0); 152353146Sbrian} 152453146Sbrian 152553146Sbrian/* 152675118Sfenner * PPP I/F printer to use if we know that RFC 1662-style PPP in HDLC-like 152775118Sfenner * framing, or Cisco PPP with HDLC framing as per section 4.3.1 of RFC 1547, 152875118Sfenner * is being used (i.e., we don't check for PPP_ADDRESS and PPP_CONTROL, 152975118Sfenner * discard them *if* those are the first two octets, and parse the remaining 153075118Sfenner * packet as a PPP packet, as "ppp_print()" does). 153175118Sfenner * 153275118Sfenner * This handles, for example, DLT_PPP_SERIAL in NetBSD. 153353146Sbrian */ 1534127675Sbmsu_int 1535127675Sbmsppp_hdlc_if_print(const struct pcap_pkthdr *h, register const u_char *p) 153653146Sbrian{ 153775118Sfenner register u_int length = h->len; 153875118Sfenner register u_int caplen = h->caplen; 153975118Sfenner u_int proto; 1540127675Sbms u_int hdrlen = 0; 154117680Spst 154275118Sfenner if (caplen < 2) { 154375118Sfenner printf("[|ppp]"); 1544127675Sbms return (caplen); 154575118Sfenner } 154617680Spst 154775118Sfenner switch (p[0]) { 154875118Sfenner 154975118Sfenner case PPP_ADDRESS: 155075118Sfenner if (caplen < 4) { 155175118Sfenner printf("[|ppp]"); 1552127675Sbms return (caplen); 155375118Sfenner } 155475118Sfenner 155575118Sfenner if (eflag) 155675118Sfenner printf("%02x %02x %d ", p[0], p[1], length); 155775118Sfenner p += 2; 155875118Sfenner length -= 2; 1559127675Sbms hdrlen += 2; 156075118Sfenner 156175118Sfenner proto = EXTRACT_16BITS(p); 156275118Sfenner p += 2; 156375118Sfenner length -= 2; 1564127675Sbms hdrlen += 2; 1565127675Sbms printf("%s: ", tok2str(ppptype2str, "unknown PPP protocol (0x%04x)", proto)); 156675118Sfenner 156775118Sfenner handle_ppp(proto, p, length); 156817692Spst break; 156938638Sthepish 157075118Sfenner case CHDLC_UNICAST: 157175118Sfenner case CHDLC_BCAST: 1572127675Sbms return (chdlc_if_print(h, p)); 157375118Sfenner 157417692Spst default: 157575118Sfenner if (eflag) 157675118Sfenner printf("%02x %02x %d ", p[0], p[1], length); 157775118Sfenner p += 2; 157875118Sfenner length -= 2; 1579127675Sbms hdrlen += 2; 158075118Sfenner 158175118Sfenner /* 158275118Sfenner * XXX - NetBSD's "ppp_netbsd_serial_if_print()" treats 158375118Sfenner * the next two octets as an Ethernet type; does that 158475118Sfenner * ever happen? 158575118Sfenner */ 158675118Sfenner printf("unknown addr %02x; ctrl %02x", p[0], p[1]); 158775118Sfenner break; 158817692Spst } 158917692Spst 1590127675Sbms return (hdrlen); 159117680Spst} 159217680Spst 159339300Sfenner#define PPP_BSDI_HDRLEN 24 159439300Sfenner 159539300Sfenner/* BSD/OS specific PPP printer */ 1596127675Sbmsu_int 1597127675Sbmsppp_bsdos_if_print(const struct pcap_pkthdr *h _U_, register const u_char *p _U_) 159817680Spst{ 1599127675Sbms register int hdrlength; 160056896Sfenner#ifdef __bsdi__ 160139300Sfenner register u_int length = h->len; 160239300Sfenner register u_int caplen = h->caplen; 160375118Sfenner u_int16_t ptype; 160456896Sfenner const u_char *q; 160556896Sfenner int i; 160639300Sfenner 160739300Sfenner if (caplen < PPP_BSDI_HDRLEN) { 160839300Sfenner printf("[|ppp]"); 1609127675Sbms return (caplen) 161039300Sfenner } 161139300Sfenner 161239300Sfenner hdrlength = 0; 161339300Sfenner 161456896Sfenner#if 0 161539300Sfenner if (p[0] == PPP_ADDRESS && p[1] == PPP_CONTROL) { 161675118Sfenner if (eflag) 161739300Sfenner printf("%02x %02x ", p[0], p[1]); 161839300Sfenner p += 2; 161939300Sfenner hdrlength = 2; 162039300Sfenner } 162139300Sfenner 162275118Sfenner if (eflag) 162339300Sfenner printf("%d ", length); 162439300Sfenner /* Retrieve the protocol type */ 162539300Sfenner if (*p & 01) { 162639300Sfenner /* Compressed protocol field */ 162739300Sfenner ptype = *p; 162875118Sfenner if (eflag) 162939300Sfenner printf("%02x ", ptype); 163039300Sfenner p++; 163139300Sfenner hdrlength += 1; 163239300Sfenner } else { 163339300Sfenner /* Un-compressed protocol field */ 1634214478Srpaulo ptype = EXTRACT_16BITS(p); 163575118Sfenner if (eflag) 163639300Sfenner printf("%04x ", ptype); 163739300Sfenner p += 2; 163839300Sfenner hdrlength += 2; 163939300Sfenner } 164056896Sfenner#else 164156896Sfenner ptype = 0; /*XXX*/ 164256896Sfenner if (eflag) 164356896Sfenner printf("%c ", p[SLC_DIR] ? 'O' : 'I'); 164456896Sfenner if (p[SLC_LLHL]) { 164556896Sfenner /* link level header */ 164656896Sfenner struct ppp_header *ph; 164756896Sfenner 164856896Sfenner q = p + SLC_BPFHDRLEN; 164956896Sfenner ph = (struct ppp_header *)q; 165056896Sfenner if (ph->phdr_addr == PPP_ADDRESS 165156896Sfenner && ph->phdr_ctl == PPP_CONTROL) { 165275118Sfenner if (eflag) 165356896Sfenner printf("%02x %02x ", q[0], q[1]); 1654214478Srpaulo ptype = EXTRACT_16BITS(&ph->phdr_type); 165556896Sfenner if (eflag && (ptype == PPP_VJC || ptype == PPP_VJNC)) { 165656896Sfenner printf("%s ", tok2str(ppptype2str, 165756896Sfenner "proto-#%d", ptype)); 165856896Sfenner } 165956896Sfenner } else { 166056896Sfenner if (eflag) { 166156896Sfenner printf("LLH=["); 166256896Sfenner for (i = 0; i < p[SLC_LLHL]; i++) 166356896Sfenner printf("%02x", q[i]); 166456896Sfenner printf("] "); 166556896Sfenner } 166656896Sfenner } 166756896Sfenner } 166875118Sfenner if (eflag) 166975118Sfenner printf("%d ", length); 167056896Sfenner if (p[SLC_CHL]) { 167156896Sfenner q = p + SLC_BPFHDRLEN + p[SLC_LLHL]; 167256896Sfenner 167356896Sfenner switch (ptype) { 167456896Sfenner case PPP_VJC: 1675127675Sbms ptype = vjc_print(q, ptype); 167656896Sfenner hdrlength = PPP_BSDI_HDRLEN; 167756896Sfenner p += hdrlength; 167875118Sfenner switch (ptype) { 167975118Sfenner case PPP_IP: 1680235530Sdelphij ip_print(gndo, p, length); 168175118Sfenner break; 168275118Sfenner#ifdef INET6 168375118Sfenner case PPP_IPV6: 1684235530Sdelphij ip6_print(gndo, p, length); 168575118Sfenner break; 168675118Sfenner#endif 1687127675Sbms case PPP_MPLS_UCAST: 1688127675Sbms case PPP_MPLS_MCAST: 1689127675Sbms mpls_print(p, length); 1690127675Sbms break; 169175118Sfenner } 169256896Sfenner goto printx; 169356896Sfenner case PPP_VJNC: 1694127675Sbms ptype = vjc_print(q, ptype); 169556896Sfenner hdrlength = PPP_BSDI_HDRLEN; 169656896Sfenner p += hdrlength; 169775118Sfenner switch (ptype) { 169875118Sfenner case PPP_IP: 1699235530Sdelphij ip_print(gndo, p, length); 170075118Sfenner break; 170175118Sfenner#ifdef INET6 170275118Sfenner case PPP_IPV6: 1703235530Sdelphij ip6_print(gndo, p, length); 170475118Sfenner break; 170575118Sfenner#endif 1706127675Sbms case PPP_MPLS_UCAST: 1707127675Sbms case PPP_MPLS_MCAST: 1708127675Sbms mpls_print(p, length); 1709127675Sbms break; 171075118Sfenner } 171156896Sfenner goto printx; 171256896Sfenner default: 171356896Sfenner if (eflag) { 171456896Sfenner printf("CH=["); 171556896Sfenner for (i = 0; i < p[SLC_LLHL]; i++) 171656896Sfenner printf("%02x", q[i]); 171756896Sfenner printf("] "); 171856896Sfenner } 171956896Sfenner break; 172056896Sfenner } 172156896Sfenner } 172256896Sfenner 172356896Sfenner hdrlength = PPP_BSDI_HDRLEN; 172456896Sfenner#endif 172556896Sfenner 172639300Sfenner length -= hdrlength; 172756896Sfenner p += hdrlength; 172839300Sfenner 172975118Sfenner switch (ptype) { 173075118Sfenner case PPP_IP: 173139300Sfenner ip_print(p, length); 173275118Sfenner break; 173375118Sfenner#ifdef INET6 173475118Sfenner case PPP_IPV6: 1735235530Sdelphij ip6_print(gndo, p, length); 173675118Sfenner break; 173775118Sfenner#endif 1738127675Sbms case PPP_MPLS_UCAST: 1739127675Sbms case PPP_MPLS_MCAST: 1740235530Sdelphij mpls_print(gndo, p, length); 1741127675Sbms break; 174275118Sfenner default: 1743127675Sbms printf("%s ", tok2str(ppptype2str, "unknown PPP protocol (0x%04x)", ptype)); 174475118Sfenner } 174539300Sfenner 174656896Sfennerprintx: 1747127675Sbms#else /* __bsdi */ 1748127675Sbms hdrlength = 0; 174956896Sfenner#endif /* __bsdi__ */ 1750127675Sbms return (hdrlength); 175117680Spst} 1752146778Ssam 1753146778Ssam 1754146778Ssam/* 1755146778Ssam * Local Variables: 1756146778Ssam * c-style: whitesmith 1757146778Ssam * c-basic-offset: 8 1758146778Ssam * End: 1759146778Ssam */ 1760