print-isoclns.c revision 56896
117680Spst/* 217680Spst * Copyright (c) 1992, 1993, 1994, 1995, 1996 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. 2026183Sfenner * 2117680Spst * Original code by Matt Thomas, Digital Equipment Corporation 2256896Sfenner * 2356896Sfenner * $FreeBSD: head/contrib/tcpdump/print-isoclns.c 56896 2000-01-30 01:05:24Z fenner $ 2417680Spst */ 2517680Spst 2617680Spst#ifndef lint 2726183Sfennerstatic const char rcsid[] = 2856896Sfenner "@(#) $Header: /tcpdump/master/tcpdump/print-isoclns.c,v 1.16 1999/11/21 09:36:55 fenner Exp $ (LBL)"; 2917680Spst#endif 3017680Spst 3156896Sfenner#ifdef HAVE_CONFIG_H 3256896Sfenner#include "config.h" 3356896Sfenner#endif 3456896Sfenner 3517680Spst#include <sys/types.h> 3617680Spst#include <sys/time.h> 3717680Spst#include <sys/socket.h> 3817680Spst 3917680Spst#if __STDC__ 4017680Spststruct mbuf; 4117680Spststruct rtentry; 4217680Spst#endif 4317680Spst#include <net/if.h> 4417680Spst 4517680Spst#include <netinet/in.h> 4621262Swollman#include <net/ethernet.h> 4717680Spst 4817680Spst#include <stdio.h> 4917680Spst 5017680Spst#include "interface.h" 5117680Spst#include "addrtoname.h" 5217680Spst#include "ethertype.h" 5317688Spst#include "extract.h" 5417680Spst 5517688Spst#define NLPID_CLNS 129 /* 0x81 */ 5617688Spst#define NLPID_ESIS 130 /* 0x82 */ 5717688Spst#define NLPID_ISIS 131 /* 0x83 */ 5817688Spst#define NLPID_NULLNS 0 5917680Spst 6032149Spst 6132149Spst/* 6232149Spst * IS-IS is defined in ISO 10589. Look there for protocol definitions. 6332149Spst */ 6432149Spst 6532149Spst#define SYSTEM_ID_LEN sizeof(struct ether_addr) 6632149Spst#define ISIS_VERSION 1 6732149Spst#define PDU_TYPE_MASK 0x1F 6832149Spst#define PRIORITY_MASK 0x7F 6932149Spst 7032149Spst#define L1_LAN_IIH 15 7132149Spst#define L2_LAN_IIH 16 7232149Spst#define PTP_IIH 17 7332149Spst#define L1_LS_PDU 18 7432149Spst#define L2_LS_PDU 19 7532149Spst#define L1_COMPLETE_SEQ_PDU 24 7632149Spst#define L2_COMPLETE_SEQ_PDU 25 7732149Spst 7832149Spst/* 7932149Spst * A TLV is a tuple of a type, length and a value and is normally used for 8032149Spst * encoding information in all sorts of places. This is an enumeration of 8132149Spst * the well known types. 8232149Spst */ 8332149Spst 8432149Spst#define TLV_AREA_ADDR 1 8532149Spst#define TLV_IS_REACH 2 8632149Spst#define TLV_ES_REACH 3 8732149Spst#define TLV_SUMMARY 5 8832149Spst#define TLV_ISNEIGH 6 8932149Spst#define TLV_PADDING 8 9032149Spst#define TLV_LSP 9 9132149Spst#define TLV_AUTHENT 10 9232149Spst#define TLV_IP_REACH 128 9332149Spst#define TLV_PROTOCOLS 129 9432149Spst#define TLV_IP_EXTERN 130 9532149Spst#define TLV_IDRP_INFO 131 9632149Spst#define TLV_IPADDR 132 9732149Spst#define TLV_IPAUTH 133 9832149Spst#define TLV_PTP_ADJ 240 9932149Spst 10032149Spst/* 10132149Spst * Katz's point to point adjacency TLV uses codes to tell us the state of 10232149Spst * the remote adjacency. Enumerate them. 10332149Spst */ 10432149Spst 10532149Spst#define ISIS_PTP_ADJ_UP 0 10632149Spst#define ISIS_PTP_ADJ_INIT 1 10732149Spst#define ISIS_PTP_ADJ_DOWN 2 10832149Spst 10917751Spststatic int osi_cksum(const u_char *, int, u_char *); 11017680Spststatic void esis_print(const u_char *, u_int); 11117688Spststatic int isis_print(const u_char *, u_int); 11217680Spst 11332149Spst 11432149Spststruct isis_ptp_adjancey_values { 11532149Spst u_char id; 11632149Spst char *name; 11732149Spst}; 11832149Spst 11932149Spststatic struct isis_ptp_adjancey_values isis_ptp_adjancey_values[] = { 12032149Spst ISIS_PTP_ADJ_UP, "UP", 12132149Spst ISIS_PTP_ADJ_INIT, "INIT", 12232149Spst ISIS_PTP_ADJ_DOWN, "DOWN" 12332149Spst}; 12432149Spst 12532149Spststruct isis_common_header { 12632149Spst u_char nlpid; 12732149Spst u_char fixed_len; 12832149Spst u_char version; /* Protocol version? */ 12932149Spst u_char id_length; 13032149Spst u_char enc_pdu_type; /* 3 MSbs are reserved */ 13132149Spst u_char pkt_version; /* Packet format version? */ 13232149Spst u_char reserved; 13332149Spst u_char enc_max_area; 13432149Spst}; 13532149Spst 13632149Spststruct isis_header { 13732149Spst u_char nlpid; 13832149Spst u_char fixed_len; 13932149Spst u_char version; /* Protocol version? */ 14032149Spst u_char id_length; 14132149Spst u_char enc_pdu_type; /* 3 MSbs are reserved */ 14232149Spst u_char pkt_version; /* Packet format version? */ 14332149Spst u_char reserved; 14432149Spst u_char enc_max_area; 14532149Spst u_char circuit; 14632149Spst u_char enc_source_id[SYSTEM_ID_LEN]; 14732149Spst u_char enc_holding_time[2]; 14832149Spst u_char enc_packet_len[2]; 14932149Spst u_char enc_priority; 15032149Spst u_char enc_lan_id[SYSTEM_ID_LEN+1]; 15132149Spst}; 15232149Spststruct isis_lan_header { 15332149Spst u_char circuit; 15432149Spst u_char enc_source_id[SYSTEM_ID_LEN]; 15532149Spst u_char enc_holding_time[2]; 15632149Spst u_char enc_packet_len[2]; 15732149Spst u_char enc_priority; 15832149Spst u_char enc_lan_id[SYSTEM_ID_LEN+1]; 15932149Spst}; 16032149Spst 16132149Spststruct isis_ptp_header { 16232149Spst u_char circuit; 16332149Spst u_char enc_source_id[SYSTEM_ID_LEN]; 16432149Spst u_char enc_holding_time[2]; 16532149Spst u_char enc_packet_len[2]; 16632149Spst u_char loc_circuit_id; 16732149Spst}; 16832149Spst 16932149Spst#define ISIS_COMMON_HEADER_SIZE (sizeof(struct isis_common_header)) 17032149Spst#define ISIS_HEADER_SIZE (15+(SYSTEM_ID_LEN<<1)) 17132149Spst#define ISIS_PTP_HEADER_SIZE (14+SYSTEM_ID_LEN) 17232149Spst#define L1_LS_PDU_HEADER_SIZE (21+SYSTEM_ID_LEN) 17332149Spst#define L2_LS_PDU_HEADER_SIZE L1_LS_PDU_HEADER_SIZE 17432149Spst#define L1_COMPLETE_SEQ_PDU_HEADER_SIZE 33 17532149Spst#define L2_COMPLETE_SEQ_PDU_HEADER_SIZE L1_COMPLETE_SEQ_PDU_HEADER_SIZE 17632149Spst 17732149Spst 17832149Spst 17917680Spstvoid 18017680Spstisoclns_print(const u_char *p, u_int length, u_int caplen, 18117680Spst const u_char *esrc, const u_char *edst) 18217680Spst{ 18332149Spst u_char pdu_type; 18432149Spst struct isis_header *header; 18532149Spst 18632149Spst header = (struct isis_header *)p; 18732149Spst pdu_type = header->enc_pdu_type & PDU_TYPE_MASK; 18832149Spst 18917680Spst if (caplen < 1) { 19017680Spst printf("[|iso-clns] "); 19117680Spst if (!eflag) 19217680Spst printf("%s > %s", 19317680Spst etheraddr_string(esrc), 19417680Spst etheraddr_string(edst)); 19517680Spst return; 19617680Spst } 19717680Spst 19817680Spst switch (*p) { 19917680Spst 20017688Spst case NLPID_CLNS: 20117688Spst printf("iso clns"); 20217680Spst if (!eflag) 20317680Spst (void)printf(" %s > %s", 20417680Spst etheraddr_string(esrc), 20517680Spst etheraddr_string(edst)); 20617680Spst break; 20717680Spst 20817688Spst case NLPID_ESIS: 20917688Spst printf("iso esis"); 21017680Spst if (!eflag) 21117680Spst (void)printf(" %s > %s", 21217680Spst etheraddr_string(esrc), 21317680Spst etheraddr_string(edst)); 21417680Spst esis_print(p, length); 21517680Spst return; 21617680Spst 21717688Spst case NLPID_ISIS: 21817688Spst printf("iso isis"); 21932149Spst if (!eflag) { 22032149Spst if(pdu_type != PTP_IIH) 22132149Spst (void)printf(" %s > %s", 22217680Spst etheraddr_string(esrc), 22317680Spst etheraddr_string(edst)); 22432149Spst } 22517680Spst (void)printf(" len=%d ", length); 22617751Spst if (!isis_print(p, length)) 22717688Spst default_print_unaligned(p, caplen); 22817680Spst break; 22917680Spst 23017688Spst case NLPID_NULLNS: 23117688Spst printf("iso nullns"); 23217680Spst if (!eflag) 23317680Spst (void)printf(" %s > %s", 23417680Spst etheraddr_string(esrc), 23517680Spst etheraddr_string(edst)); 23617680Spst break; 23717680Spst 23817680Spst default: 23917688Spst printf("iso clns %02x", p[0]); 24017680Spst if (!eflag) 24117680Spst (void)printf(" %s > %s", 24217680Spst etheraddr_string(esrc), 24317680Spst etheraddr_string(edst)); 24417680Spst (void)printf(" len=%d ", length); 24517680Spst if (caplen > 1) 24617680Spst default_print_unaligned(p, caplen); 24717680Spst break; 24817680Spst } 24917680Spst} 25017680Spst 25117680Spst#define ESIS_REDIRECT 6 25217680Spst#define ESIS_ESH 2 25317680Spst#define ESIS_ISH 4 25417680Spst 25517680Spststruct esis_hdr { 25617680Spst u_char version; 25717680Spst u_char reserved; 25817680Spst u_char type; 25917680Spst u_char tmo[2]; 26017680Spst u_char cksum[2]; 26117680Spst}; 26217680Spst 26317680Spststatic void 26417680Spstesis_print(const u_char *p, u_int length) 26517680Spst{ 26617680Spst const u_char *ep; 26717680Spst int li = p[1]; 26817680Spst const struct esis_hdr *eh = (const struct esis_hdr *) &p[2]; 26917680Spst u_char cksum[2]; 27017680Spst u_char off[2]; 27117680Spst 27217680Spst if (length == 2) { 27317680Spst if (qflag) 27417680Spst printf(" bad pkt!"); 27517680Spst else 27617680Spst printf(" no header at all!"); 27717680Spst return; 27817680Spst } 27917680Spst ep = p + li; 28017680Spst if (li > length) { 28117680Spst if (qflag) 28217680Spst printf(" bad pkt!"); 28317680Spst else 28417680Spst printf(" LI(%d) > PDU size (%d)!", li, length); 28517680Spst return; 28617680Spst } 28717680Spst if (li < sizeof(struct esis_hdr) + 2) { 28817680Spst if (qflag) 28917680Spst printf(" bad pkt!"); 29017680Spst else { 29117680Spst printf(" too short for esis header %d:", li); 29239300Sfenner while (--length != 0) 29317680Spst printf("%02X", *p++); 29417680Spst } 29517680Spst return; 29617680Spst } 29717680Spst switch (eh->type & 0x1f) { 29817680Spst 29917680Spst case ESIS_REDIRECT: 30017680Spst printf(" redirect"); 30117680Spst break; 30217680Spst 30317680Spst case ESIS_ESH: 30417680Spst printf(" esh"); 30517680Spst break; 30617680Spst 30717680Spst case ESIS_ISH: 30817680Spst printf(" ish"); 30917680Spst break; 31017680Spst 31117680Spst default: 31217680Spst printf(" type %d", eh->type & 0x1f); 31317680Spst break; 31417680Spst } 31517680Spst off[0] = eh->cksum[0]; 31617680Spst off[1] = eh->cksum[1]; 31717751Spst if (vflag && osi_cksum(p, li, off)) { 31817751Spst printf(" bad cksum (got %02x%02x)", 31917751Spst eh->cksum[1], eh->cksum[0]); 32017751Spst default_print(p, length); 32117680Spst return; 32217680Spst } 32317680Spst if (eh->version != 1) { 32417680Spst printf(" unsupported version %d", eh->version); 32517680Spst return; 32617680Spst } 32717680Spst p += sizeof(*eh) + 2; 32817680Spst li -= sizeof(*eh) + 2; /* protoid * li */ 32917680Spst 33017680Spst switch (eh->type & 0x1f) { 33117680Spst case ESIS_REDIRECT: { 33217680Spst const u_char *dst, *snpa, *is; 33317680Spst 33417680Spst dst = p; p += *p + 1; 33517680Spst if (p > snapend) 33617680Spst return; 33717688Spst printf("\n\t\t\t %s", isonsap_string(dst)); 33817680Spst snpa = p; p += *p + 1; 33917680Spst is = p; p += *p + 1; 34017680Spst if (p > snapend) 34117680Spst return; 34217680Spst if (p > ep) { 34317680Spst printf(" [bad li]"); 34417680Spst return; 34517680Spst } 34617680Spst if (is[0] == 0) 34717680Spst printf(" > %s", etheraddr_string(&snpa[1])); 34817680Spst else 34917680Spst printf(" > %s", isonsap_string(is)); 35017680Spst li = ep - p; 35117680Spst break; 35217680Spst } 35317680Spst#if 0 35417680Spst case ESIS_ESH: 35517680Spst printf(" esh"); 35617680Spst break; 35717680Spst#endif 35817680Spst case ESIS_ISH: { 35917680Spst const u_char *is; 36017680Spst 36117680Spst is = p; p += *p + 1; 36217680Spst if (p > ep) { 36317680Spst printf(" [bad li]"); 36417680Spst return; 36517680Spst } 36617680Spst if (p > snapend) 36717680Spst return; 36817751Spst if (!qflag) 36917751Spst printf("\n\t\t\t %s", isonsap_string(is)); 37017680Spst li = ep - p; 37117680Spst break; 37217680Spst } 37317680Spst 37417680Spst default: 37517680Spst (void)printf(" len=%d", length); 37617680Spst if (length && p < snapend) { 37717680Spst length = snapend - p; 37817680Spst default_print(p, length); 37917680Spst } 38017680Spst return; 38117680Spst } 38217680Spst if (vflag) 38317680Spst while (p < ep && li) { 38417680Spst int op, opli; 38517680Spst const u_char *q; 38617680Spst 38717680Spst if (snapend - p < 2) 38817680Spst return; 38917680Spst if (li < 2) { 39017680Spst printf(" bad opts/li"); 39117680Spst return; 39217680Spst } 39317680Spst op = *p++; 39417680Spst opli = *p++; 39517680Spst li -= 2; 39617680Spst if (opli > li) { 39717680Spst printf(" opt (%d) too long", op); 39817680Spst return; 39917680Spst } 40017680Spst li -= opli; 40117680Spst q = p; 40217680Spst p += opli; 40317680Spst if (snapend < p) 40417680Spst return; 40517680Spst if (op == 198 && opli == 2) { 40617680Spst printf(" tmo=%d", q[0] * 256 + q[1]); 40717680Spst continue; 40817680Spst } 40917680Spst printf (" %d:<", op); 41017680Spst while (--opli >= 0) 41117680Spst printf("%02x", *q++); 41217680Spst printf (">"); 41317680Spst } 41417680Spst} 41517680Spst 41617688Spst/* 41717688Spst * print_nsap 41817688Spst * Print out an NSAP. 41917688Spst */ 42017688Spst 42117688Spstvoid 42217688Spstprint_nsap (register const u_char *cp, register int length) 42317688Spst{ 42417688Spst int i; 42517688Spst 42617688Spst for (i = 0; i < length; i++) { 42717688Spst printf("%02x", *cp++); 42817688Spst if (((i & 1) == 0) && (i + 1 < length)) { 42917688Spst printf("."); 43017688Spst } 43117688Spst 43217688Spst } 43317688Spst} 43417688Spst 43517688Spst/* 43617688Spst * isis_print 43717688Spst * Decode IS-IS packets. Return 0 on error. 43817688Spst * 43917688Spst * So far, this is only smart enough to print IIH's. Someday... 44017688Spst */ 44117688Spst 44217680Spststatic int 44317688Spstisis_print (const u_char *p, u_int length) 44417688Spst{ 44517688Spst struct isis_header *header; 44632149Spst struct isis_ptp_header *header_ptp; 44717688Spst u_char pdu_type, max_area, priority, *pptr, type, len, *tptr, tmp, alen; 44817688Spst u_short packet_len, holding_time; 44932149Spst int i; 45017688Spst 45132149Spst header_ptp = (struct isis_ptp_header *)header = (struct isis_header *)p; 45217688Spst printf("\n\t\t\t"); 45317688Spst 45417688Spst /* 45517688Spst * Sanity checking of the header. 45617688Spst */ 45717688Spst if (header->nlpid != NLPID_ISIS) { 45817688Spst printf(" coding error!"); 45917688Spst return(0); 46017688Spst } 46117688Spst 46217688Spst if (header->version != ISIS_VERSION) { 46317688Spst printf(" version %d packet not supported", header->version); 46417688Spst return(0); 46517688Spst } 46617688Spst 46717688Spst if ((header->id_length != SYSTEM_ID_LEN) && (header->id_length != 0)) { 46817688Spst printf(" system ID length of %d is not supported", 46917688Spst header->id_length); 47017688Spst return(0); 47117688Spst } 47217688Spst 47332149Spst if ((header->fixed_len != ISIS_HEADER_SIZE) && 47432149Spst (header->fixed_len != ISIS_PTP_HEADER_SIZE) && 47532149Spst (header->fixed_len != L1_LS_PDU_HEADER_SIZE) && 47632149Spst (header-> fixed_len != L1_COMPLETE_SEQ_PDU_HEADER_SIZE) ) { 47732149Spst printf(" bogus fixed header length", 47832149Spst header->fixed_len); 47932149Spst return(0); 48017688Spst } 48117688Spst 48217688Spst pdu_type = header->enc_pdu_type & PDU_TYPE_MASK; 48332149Spst if ((pdu_type != L1_LAN_IIH) && (pdu_type != L2_LAN_IIH) && 48432149Spst (pdu_type != PTP_IIH) && 48532149Spst (pdu_type != L1_COMPLETE_SEQ_PDU) && 48632149Spst (pdu_type != L2_COMPLETE_SEQ_PDU) ) { 48717688Spst printf(" PDU type (%d) not supported", pdu_type); 48817688Spst return; 48917688Spst } 49017688Spst 49117688Spst if (header->pkt_version != ISIS_VERSION) { 49217688Spst printf(" version %d packet not supported", header->pkt_version); 49317688Spst return; 49417688Spst } 49517688Spst 49617688Spst max_area = header->enc_max_area; 49717688Spst switch(max_area) { 49817688Spst case 0: 49917688Spst max_area = 3; /* silly shit */ 50017688Spst break; 50117688Spst case 255: 50217688Spst printf(" bad packet -- 255 areas"); 50317688Spst return(0); 50417688Spst default: 50517688Spst break; 50617688Spst } 50717688Spst 50817688Spst switch (header->circuit) { 50917688Spst case 0: 51017688Spst printf(" PDU with circuit type 0"); 51117688Spst return(0); 51217688Spst case 1: 51317688Spst if (pdu_type == L2_LAN_IIH) { 51417688Spst printf(" L2 IIH on an L1 only circuit"); 51517688Spst return(0); 51617688Spst } 51717688Spst break; 51817688Spst case 2: 51917688Spst if (pdu_type == L1_LAN_IIH) { 52017688Spst printf(" L1 IIH on an L2 only circuit"); 52117688Spst return(0); 52217688Spst } 52317688Spst break; 52417688Spst case 3: 52517688Spst break; 52617688Spst default: 52717688Spst printf(" unknown circuit type"); 52817688Spst return(0); 52917688Spst } 53017688Spst 53117688Spst holding_time = EXTRACT_16BITS(header->enc_holding_time); 53217688Spst 53317688Spst packet_len = EXTRACT_16BITS(header->enc_packet_len); 53417688Spst if ((packet_len < ISIS_HEADER_SIZE) || 53517688Spst (packet_len > length)) { 53617688Spst printf(" bogus packet length %d, real length %d", packet_len, 53717688Spst length); 53817688Spst return(0); 53917688Spst } 54017688Spst 54132149Spst if(pdu_type != PTP_IIH) 54232149Spst priority = header->enc_priority & PRIORITY_MASK; 54317688Spst 54417688Spst /* 54517688Spst * Now print the fixed header. 54617688Spst */ 54717688Spst switch (pdu_type) { 54817688Spst case L1_LAN_IIH: 54917688Spst printf(" L1 lan iih, "); 55017688Spst break; 55117688Spst case L2_LAN_IIH: 55217688Spst printf(" L2 lan iih, "); 55317688Spst break; 55432149Spst case PTP_IIH: 55532149Spst printf(" PTP iih, "); 55632149Spst break; 55717688Spst } 55817688Spst 55917688Spst printf("circuit "); 56017688Spst switch (header->circuit) { 56117688Spst case 1: 56217688Spst printf("l1 only, "); 56317688Spst break; 56417688Spst case 2: 56517688Spst printf("l2 only, "); 56617688Spst break; 56717688Spst case 3: 56817688Spst printf("l1-l2, "); 56917688Spst break; 57017688Spst } 57117688Spst 57217688Spst printf ("holding time %d ", holding_time); 57317688Spst printf ("\n\t\t\t source %s, length %d", 57417688Spst etheraddr_string(header->enc_source_id), packet_len); 57532149Spst if((pdu_type==L1_LAN_IIH)||(pdu_type==L2_LAN_IIH)) 57632149Spst printf ("\n\t\t\t lan id %s(%d)", etheraddr_string(header->enc_lan_id), 57732149Spst header->enc_lan_id[SYSTEM_ID_LEN]); 57817688Spst 57917688Spst /* 58017688Spst * Now print the TLV's. 58117688Spst */ 58232149Spst if(pdu_type==PTP_IIH) { 58332149Spst packet_len -= ISIS_PTP_HEADER_SIZE; 58432149Spst pptr = (char *)p + ISIS_PTP_HEADER_SIZE; 58532149Spst } else { 58632149Spst packet_len -= ISIS_HEADER_SIZE; 58732149Spst pptr = (char *)p + ISIS_HEADER_SIZE; 58832149Spst } 58917688Spst while (packet_len >= 2) { 59017688Spst if (pptr >= snapend) { 59117688Spst printf("\n\t\t\t packet exceeded snapshot"); 59217688Spst return(1); 59317688Spst } 59417688Spst type = *pptr++; 59517688Spst len = *pptr++; 59617688Spst packet_len -= 2; 59717688Spst if (len > packet_len) { 59817688Spst break; 59917688Spst } 60017688Spst 60117688Spst switch (type) { 60217688Spst case TLV_AREA_ADDR: 60317688Spst printf("\n\t\t\t area addresses"); 60417688Spst tmp = len; 60517688Spst tptr = pptr; 60617688Spst alen = *tptr++; 60717688Spst while (tmp && alen < tmp) { 60817688Spst printf("\n\t\t\t "); 60917688Spst print_nsap(tptr, alen); 61017688Spst printf(" (%d)", alen); 61117688Spst tptr += alen; 61217688Spst tmp -= alen + 1; 61317688Spst alen = *tptr++; 61417688Spst } 61517688Spst break; 61617688Spst case TLV_ISNEIGH: 61717688Spst printf("\n\t\t\t neighbor addresses"); 61817688Spst tmp = len; 61917688Spst tptr = pptr; 62017688Spst while (tmp >= sizeof(struct ether_addr)) { 62117688Spst printf("\n\t\t\t %s", etheraddr_string(tptr)); 62217688Spst tmp -= sizeof(struct ether_addr); 62317688Spst tptr += sizeof(struct ether_addr); 62417688Spst } 62517688Spst break; 62617688Spst case TLV_PADDING: 62717688Spst printf("\n\t\t\t padding for %d bytes", len); 62817688Spst break; 62917688Spst case TLV_AUTHENT: 63017688Spst printf("\n\t\t\t authentication data"); 63117688Spst default_print(pptr, len); 63217688Spst break; 63332149Spst case TLV_PTP_ADJ: 63432149Spst printf("\n\t\t\t PTP adjacency status %s", 63532149Spst isis_ptp_adjancey_values[*pptr].name); 63632149Spst break; 63732149Spst case TLV_PROTOCOLS: 63832149Spst printf("\n\t\t\t Supports protocols %s", (len>1)? "are":"is"); 63932149Spst for(i=0;i<len;i++) 64032149Spst printf(" %02X", (u_char)*(pptr+i)); 64132149Spst break; 64232149Spst case TLV_IPADDR: 64332149Spst printf("\n\t\t\t IP address: %s", ipaddr_string(pptr)); 64432149Spst break; 64517688Spst default: 64617688Spst printf("\n\t\t\t unknown TLV, type %d, length %d", type, len); 64717688Spst break; 64817688Spst } 64917688Spst 65017688Spst pptr += len; 65117688Spst packet_len -= len; 65217688Spst } 65317688Spst 65417688Spst if (packet_len != 0) { 65517688Spst printf("\n\t\t\t %d straggler bytes", packet_len); 65617688Spst } 65717688Spst return(1); 65817688Spst} 65917688Spst 66017751Spst/* 66117751Spst * Verify the checksum. See 8473-1, Appendix C, section C.4. 66217751Spst */ 66317751Spst 66417688Spststatic int 66517751Spstosi_cksum(register const u_char *p, register int len, u_char *off) 66617680Spst{ 66717680Spst int32_t c0 = 0, c1 = 0; 66817680Spst 66917751Spst if ((off[0] == 0) && (off[1] == 0)) 67017680Spst return 0; 67117680Spst 67239300Sfenner off[0] = off[1] = 0; 67339300Sfenner while ((int)--len >= 0) { 67417680Spst c0 += *p++; 67517751Spst c0 %= 255; 67617680Spst c1 += c0; 67717680Spst c1 %= 255; 67817680Spst } 67917751Spst return (c0 | c1); 68017680Spst} 681