print-ip.c revision 111729
117680Spst/* 239300Sfenner * Copyright (c) 1988, 1989, 1990, 1991, 1992, 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. 2056896Sfenner * 2156896Sfenner * $FreeBSD: head/contrib/tcpdump/print-ip.c 111729 2003-03-02 08:25:48Z fenner $ 2217680Spst */ 2317680Spst 2417680Spst#ifndef lint 2526183Sfennerstatic const char rcsid[] = 26111729Sfenner "@(#) $Header: /tcpdump/master/tcpdump/print-ip.c,v 1.100.4.1 2002/01/25 05:39:54 guy Exp $ (LBL)"; 2717680Spst#endif 2817680Spst 2956896Sfenner#ifdef HAVE_CONFIG_H 3056896Sfenner#include "config.h" 3156896Sfenner#endif 3256896Sfenner 3317680Spst#include <sys/param.h> 3417680Spst#include <sys/time.h> 3517680Spst#include <sys/socket.h> 3617680Spst 3717680Spst#include <netinet/in.h> 3817680Spst 39111729Sfenner#include <netdb.h> 4017680Spst#include <stdio.h> 4117680Spst#include <stdlib.h> 4217680Spst#include <string.h> 4317680Spst#include <unistd.h> 4417680Spst 4517680Spst#include "addrtoname.h" 4617680Spst#include "interface.h" 4717680Spst#include "extract.h" /* must come after interface.h */ 4817680Spst 4975118Sfenner#include "ip.h" 5075118Sfenner 5117680Spst/* Compatibility */ 5217680Spst#ifndef IPPROTO_ND 5317680Spst#define IPPROTO_ND 77 5417680Spst#endif 5517680Spst 5617680Spst/* 5717680Spst * print the recorded route in an IP RR, LSRR or SSRR option. 5817680Spst */ 5917680Spststatic void 6017680Spstip_printroute(const char *type, register const u_char *cp, u_int length) 6117680Spst{ 6217680Spst register u_int ptr = cp[2] - 1; 6317680Spst register u_int len; 6417680Spst 6517680Spst printf(" %s{", type); 6617680Spst if ((length + 1) & 3) 6717680Spst printf(" [bad length %d]", length); 6817680Spst if (ptr < 3 || ((ptr + 1) & 3) || ptr > length + 1) 6917680Spst printf(" [bad ptr %d]", cp[2]); 7017680Spst 7117680Spst type = ""; 7217680Spst for (len = 3; len < length; len += 4) { 7317680Spst if (ptr == len) 7417680Spst type = "#"; 7517680Spst printf("%s%s", type, ipaddr_string(&cp[len])); 7617680Spst type = " "; 7717680Spst } 7817680Spst printf("%s}", ptr == len? "#" : ""); 7917680Spst} 8017680Spst 8156896Sfennerstatic void 8256896Sfennerip_printts(register const u_char *cp, u_int length) 8356896Sfenner{ 8456896Sfenner register u_int ptr = cp[2] - 1; 8556896Sfenner register u_int len = 0; 8656896Sfenner int hoplen; 8756896Sfenner char *type; 8856896Sfenner 8956896Sfenner printf(" TS{"); 9056896Sfenner hoplen = ((cp[3]&0xF) != IPOPT_TS_TSONLY) ? 8 : 4; 9156896Sfenner if ((length - 4) & (hoplen-1)) 9256896Sfenner printf("[bad length %d]", length); 9356896Sfenner if (ptr < 4 || ((ptr - 4) & (hoplen-1)) || ptr > length + 1) 9456896Sfenner printf("[bad ptr %d]", cp[2]); 9556896Sfenner switch (cp[3]&0xF) { 9656896Sfenner case IPOPT_TS_TSONLY: 9756896Sfenner printf("TSONLY"); 9856896Sfenner break; 9956896Sfenner case IPOPT_TS_TSANDADDR: 10056896Sfenner printf("TS+ADDR"); 10156896Sfenner break; 10256896Sfenner /* 10356896Sfenner * prespecified should really be 3, but some ones might send 2 10456896Sfenner * instead, and the IPOPT_TS_PRESPEC constant can apparently 10556896Sfenner * have both values, so we have to hard-code it here. 10656896Sfenner */ 10756896Sfenner 10856896Sfenner case 2: 10956896Sfenner printf("PRESPEC2.0"); 11056896Sfenner break; 11156896Sfenner case 3: /* IPOPT_TS_PRESPEC */ 11256896Sfenner printf("PRESPEC"); 11356896Sfenner break; 11456896Sfenner default: 11556896Sfenner printf("[bad ts type %d]", cp[3]&0xF); 11656896Sfenner goto done; 11756896Sfenner } 11856896Sfenner 11956896Sfenner type = " "; 12056896Sfenner for (len = 4; len < length; len += hoplen) { 12156896Sfenner if (ptr == len) 12256896Sfenner type = " ^ "; 12356896Sfenner printf("%s%d@%s", type, EXTRACT_32BITS(&cp[len+hoplen-4]), 12456896Sfenner hoplen!=8 ? "" : ipaddr_string(&cp[len])); 12556896Sfenner type = " "; 12656896Sfenner } 12756896Sfenner 12856896Sfennerdone: 12956896Sfenner printf("%s", ptr == len ? " ^ " : ""); 13056896Sfenner 13156896Sfenner if (cp[3]>>4) 13256896Sfenner printf(" [%d hops not recorded]} ", cp[3]>>4); 13356896Sfenner else 13456896Sfenner printf("}"); 13556896Sfenner} 13656896Sfenner 13717680Spst/* 13817680Spst * print IP options. 13917680Spst */ 14017680Spststatic void 14117680Spstip_optprint(register const u_char *cp, u_int length) 14217680Spst{ 14317680Spst register u_int len; 14417680Spst 14517680Spst for (; length > 0; cp += len, length -= len) { 14617680Spst int tt = *cp; 14717680Spst 14875118Sfenner if (tt == IPOPT_NOP || tt == IPOPT_EOL) 14975118Sfenner len = 1; 15075118Sfenner else { 15175118Sfenner if (&cp[1] >= snapend) { 15275118Sfenner printf("[|ip]"); 15375118Sfenner return; 15475118Sfenner } 15575118Sfenner len = cp[1]; 15675118Sfenner } 15717680Spst if (len <= 0) { 15817680Spst printf("[|ip op len %d]", len); 15917680Spst return; 16017680Spst } 16117680Spst if (&cp[1] >= snapend || cp + len > snapend) { 16217680Spst printf("[|ip]"); 16317680Spst return; 16417680Spst } 16517680Spst switch (tt) { 16617680Spst 16717680Spst case IPOPT_EOL: 16817680Spst printf(" EOL"); 16917680Spst if (length > 1) 17017680Spst printf("-%d", length - 1); 17117680Spst return; 17217680Spst 17317680Spst case IPOPT_NOP: 17417680Spst printf(" NOP"); 17517680Spst break; 17617680Spst 17717680Spst case IPOPT_TS: 17856896Sfenner ip_printts(cp, len); 17917680Spst break; 18017680Spst 18156896Sfenner#ifndef IPOPT_SECURITY 18256896Sfenner#define IPOPT_SECURITY 130 18356896Sfenner#endif /* IPOPT_SECURITY */ 18417680Spst case IPOPT_SECURITY: 18517680Spst printf(" SECURITY{%d}", len); 18617680Spst break; 18717680Spst 18817680Spst case IPOPT_RR: 18917680Spst ip_printroute("RR", cp, len); 19017680Spst break; 19117680Spst 19217680Spst case IPOPT_SSRR: 19317680Spst ip_printroute("SSRR", cp, len); 19417680Spst break; 19517680Spst 19617680Spst case IPOPT_LSRR: 19717680Spst ip_printroute("LSRR", cp, len); 19817680Spst break; 19917680Spst 20056896Sfenner#ifndef IPOPT_RA 20156896Sfenner#define IPOPT_RA 148 /* router alert */ 20256896Sfenner#endif 20317691Spst case IPOPT_RA: 20456896Sfenner printf(" RA"); 20556896Sfenner if (len != 4) 20656896Sfenner printf("{%d}", len); 20756896Sfenner else if (cp[2] || cp[3]) 20856896Sfenner printf("%d.%d", cp[2], cp[3]); 20998527Sfenner break; 21017691Spst 21117680Spst default: 21217680Spst printf(" IPOPT-%d{%d}", cp[0], len); 21317680Spst break; 21417680Spst } 21517680Spst } 21617680Spst} 21717680Spst 21817680Spst/* 21917680Spst * compute an IP header checksum. 22017680Spst * don't modifiy the packet. 22117680Spst */ 22256896Sfenneru_short 22398527Sfennerin_cksum(const u_short *addr, register u_int len, int csum) 22417680Spst{ 22556896Sfenner int nleft = len; 22656896Sfenner const u_short *w = addr; 22756896Sfenner u_short answer; 22856896Sfenner int sum = csum; 22917680Spst 23056896Sfenner /* 23156896Sfenner * Our algorithm is simple, using a 32 bit accumulator (sum), 23256896Sfenner * we add sequential 16 bit words to it, and at the end, fold 23356896Sfenner * back all the carry bits from the top 16 bits into the lower 23456896Sfenner * 16 bits. 23556896Sfenner */ 23656896Sfenner while (nleft > 1) { 23756896Sfenner sum += *w++; 23856896Sfenner nleft -= 2; 23956896Sfenner } 24056896Sfenner if (nleft == 1) 24156896Sfenner sum += htons(*(u_char *)w<<8); 24256896Sfenner 24317680Spst /* 24456896Sfenner * add back carry outs from top 16 bits to low 16 bits 24517680Spst */ 24656896Sfenner sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ 24756896Sfenner sum += (sum >> 16); /* add carry */ 24856896Sfenner answer = ~sum; /* truncate to 16 bits */ 24956896Sfenner return (answer); 25017680Spst} 25117680Spst 25217680Spst/* 25317680Spst * print an IP datagram. 25417680Spst */ 25517680Spstvoid 25617680Spstip_print(register const u_char *bp, register u_int length) 25717680Spst{ 25817680Spst register const struct ip *ip; 25956896Sfenner register u_int hlen, len, len0, off; 26017680Spst register const u_char *cp; 26156896Sfenner u_char nh; 26256896Sfenner int advance; 263111729Sfenner struct protoent *proto; 26417680Spst 26517680Spst ip = (const struct ip *)bp; 26617680Spst#ifdef LBL_ALIGN 26717680Spst /* 26817680Spst * If the IP header is not aligned, copy into abuf. 26917680Spst */ 27017680Spst if ((long)ip & 3) { 27117680Spst static u_char *abuf = NULL; 27217680Spst static int didwarn = 0; 27317680Spst 27417680Spst if (abuf == NULL) { 27517680Spst abuf = (u_char *)malloc(snaplen); 27617680Spst if (abuf == NULL) 27717680Spst error("ip_print: malloc"); 27817680Spst } 27917680Spst memcpy((char *)abuf, (char *)ip, min(length, snaplen)); 28017680Spst snapend += abuf - (u_char *)ip; 28117680Spst packetp = abuf; 28217680Spst ip = (struct ip *)abuf; 28317680Spst /* We really want libpcap to give us aligned packets */ 28417680Spst if (!didwarn) { 28517680Spst warning("compensating for unaligned libpcap packets"); 28617680Spst ++didwarn; 28717680Spst } 28817680Spst } 28917680Spst#endif 29017680Spst if ((u_char *)(ip + 1) > snapend) { 29117680Spst printf("[|ip]"); 29217680Spst return; 29317680Spst } 29417680Spst if (length < sizeof (struct ip)) { 29517680Spst (void)printf("truncated-ip %d", length); 29617680Spst return; 29717680Spst } 29875118Sfenner hlen = IP_HL(ip) * 4; 29975118Sfenner if (hlen < sizeof (struct ip)) { 30075118Sfenner (void)printf("bad-hlen %d", hlen); 30175118Sfenner return; 30275118Sfenner } 30317680Spst 30417680Spst len = ntohs(ip->ip_len); 30517680Spst if (length < len) 30698527Sfenner (void)printf("truncated-ip - %d bytes missing! ", 30717680Spst len - length); 30817680Spst len -= hlen; 30956896Sfenner len0 = len; 31017680Spst 31117680Spst /* 31217680Spst * If this is fragment zero, hand it to the next higher 31317680Spst * level protocol. 31417680Spst */ 31517680Spst off = ntohs(ip->ip_off); 31617680Spst if ((off & 0x1fff) == 0) { 31717680Spst cp = (const u_char *)ip + hlen; 31856896Sfenner nh = ip->ip_p; 31917680Spst 32098527Sfenner#ifndef IPPROTO_SCTP 32198527Sfenner#define IPPROTO_SCTP 132 32298527Sfenner#endif 32398527Sfenner if (nh != IPPROTO_TCP && nh != IPPROTO_UDP && 32498527Sfenner nh != IPPROTO_SCTP) { 32556896Sfenner (void)printf("%s > %s: ", ipaddr_string(&ip->ip_src), 32656896Sfenner ipaddr_string(&ip->ip_dst)); 32756896Sfenner } 32856896Sfenneragain: 32956896Sfenner switch (nh) { 33056896Sfenner 33156896Sfenner#ifndef IPPROTO_AH 33256896Sfenner#define IPPROTO_AH 51 33356896Sfenner#endif 33456896Sfenner case IPPROTO_AH: 33556896Sfenner nh = *cp; 33656896Sfenner advance = ah_print(cp, (const u_char *)ip); 33756896Sfenner cp += advance; 33856896Sfenner len -= advance; 33956896Sfenner goto again; 34056896Sfenner 34156896Sfenner#ifndef IPPROTO_ESP 34256896Sfenner#define IPPROTO_ESP 50 34356896Sfenner#endif 34456896Sfenner case IPPROTO_ESP: 34556896Sfenner { 34698527Sfenner int enh, padlen; 34798527Sfenner advance = esp_print(cp, (const u_char *)ip, &enh, &padlen); 34856896Sfenner cp += advance; 34998527Sfenner len -= advance + padlen; 35056896Sfenner if (enh < 0) 35156896Sfenner break; 35256896Sfenner nh = enh & 0xff; 35356896Sfenner goto again; 35456896Sfenner } 35556896Sfenner 35656896Sfenner#ifndef IPPROTO_IPCOMP 35756896Sfenner#define IPPROTO_IPCOMP 108 35856896Sfenner#endif 35956896Sfenner case IPPROTO_IPCOMP: 36056896Sfenner { 36156896Sfenner int enh; 36256896Sfenner advance = ipcomp_print(cp, (const u_char *)ip, &enh); 36356896Sfenner cp += advance; 36456896Sfenner len -= advance; 36556896Sfenner if (enh < 0) 36656896Sfenner break; 36756896Sfenner nh = enh & 0xff; 36856896Sfenner goto again; 36956896Sfenner } 37056896Sfenner 37198527Sfenner case IPPROTO_SCTP: 37298527Sfenner sctp_print(cp, (const u_char *)ip, len); 37398527Sfenner break; 37498527Sfenner 37517680Spst case IPPROTO_TCP: 37675118Sfenner tcp_print(cp, len, (const u_char *)ip, (off &~ 0x6000)); 37717680Spst break; 37817680Spst 37917680Spst case IPPROTO_UDP: 38075118Sfenner udp_print(cp, len, (const u_char *)ip, (off &~ 0x6000)); 38117680Spst break; 38217680Spst 38317680Spst case IPPROTO_ICMP: 38456896Sfenner icmp_print(cp, len, (const u_char *)ip); 38517680Spst break; 38617680Spst 38717680Spst#ifndef IPPROTO_IGRP 38817680Spst#define IPPROTO_IGRP 9 38917680Spst#endif 39017680Spst case IPPROTO_IGRP: 39117680Spst igrp_print(cp, len, (const u_char *)ip); 39217680Spst break; 39317680Spst 39417680Spst case IPPROTO_ND: 39517680Spst (void)printf(" nd %d", len); 39617680Spst break; 39717680Spst 39817680Spst case IPPROTO_EGP: 39917680Spst egp_print(cp, len, (const u_char *)ip); 40017680Spst break; 40117680Spst 40217680Spst#ifndef IPPROTO_OSPF 40317680Spst#define IPPROTO_OSPF 89 40417680Spst#endif 40517680Spst case IPPROTO_OSPF: 40617680Spst ospf_print(cp, len, (const u_char *)ip); 40717680Spst break; 40817680Spst 40917680Spst#ifndef IPPROTO_IGMP 41017680Spst#define IPPROTO_IGMP 2 41117680Spst#endif 41217680Spst case IPPROTO_IGMP: 41398527Sfenner igmp_print(cp, len); 41417680Spst break; 41517680Spst 41639300Sfenner case 4: 41739300Sfenner /* DVMRP multicast tunnel (ip-in-ip encapsulation) */ 41817680Spst ip_print(cp, len); 41917680Spst if (! vflag) { 42098527Sfenner printf(" (ipip-proto-4)"); 42117680Spst return; 42217680Spst } 42317680Spst break; 42417680Spst 42556896Sfenner#ifdef INET6 42656896Sfenner#ifndef IP6PROTO_ENCAP 42756896Sfenner#define IP6PROTO_ENCAP 41 42856896Sfenner#endif 42956896Sfenner case IP6PROTO_ENCAP: 43056896Sfenner /* ip6-in-ip encapsulation */ 43156896Sfenner ip6_print(cp, len); 43256896Sfenner break; 43356896Sfenner#endif /*INET6*/ 43456896Sfenner 43556896Sfenner 43626183Sfenner#ifndef IPPROTO_GRE 43726183Sfenner#define IPPROTO_GRE 47 43826183Sfenner#endif 43926183Sfenner case IPPROTO_GRE: 44026183Sfenner /* do it */ 44126183Sfenner gre_print(cp, len); 44298527Sfenner break; 44326183Sfenner 44456896Sfenner#ifndef IPPROTO_MOBILE 44556896Sfenner#define IPPROTO_MOBILE 55 44656896Sfenner#endif 44756896Sfenner case IPPROTO_MOBILE: 44856896Sfenner mobile_print(cp, len); 44956896Sfenner break; 45056896Sfenner 45156896Sfenner#ifndef IPPROTO_PIM 45256896Sfenner#define IPPROTO_PIM 103 45356896Sfenner#endif 45456896Sfenner case IPPROTO_PIM: 45556896Sfenner pim_print(cp, len); 45656896Sfenner break; 45756896Sfenner 45875118Sfenner#ifndef IPPROTO_VRRP 45975118Sfenner#define IPPROTO_VRRP 112 46075118Sfenner#endif 46175118Sfenner case IPPROTO_VRRP: 46275118Sfenner vrrp_print(cp, len, ip->ip_ttl); 46375118Sfenner break; 46475118Sfenner 46517680Spst default: 466111729Sfenner if ((proto = getprotobynumber(nh)) != NULL) 467111729Sfenner (void)printf(" %s", proto->p_name); 468111729Sfenner else 469111729Sfenner (void)printf(" ip-proto-%d", nh); 470111729Sfenner printf(" %d", len); 47117680Spst break; 47217680Spst } 47317680Spst } 47456896Sfenner 47556896Sfenner /* Ultra quiet now means that all this stuff should be suppressed */ 47656896Sfenner /* res 3-Nov-98 */ 47756896Sfenner if (qflag > 1) return; 47856896Sfenner 47956896Sfenner 48017680Spst /* 48117680Spst * for fragmented datagrams, print id:size@offset. On all 48217680Spst * but the last stick a "+". For unfragmented datagrams, note 48317680Spst * the don't fragment flag. 48417680Spst */ 48556896Sfenner len = len0; /* get the original length */ 48617680Spst if (off & 0x3fff) { 48717680Spst /* 48817680Spst * if this isn't the first frag, we're missing the 489111729Sfenner * next level protocol header. print the ip addr 490111729Sfenner * and the protocol. 49117680Spst */ 492111729Sfenner if (off & 0x1fff) { 49317680Spst (void)printf("%s > %s:", ipaddr_string(&ip->ip_src), 49417680Spst ipaddr_string(&ip->ip_dst)); 495111729Sfenner if ((proto = getprotobynumber(ip->ip_p)) != NULL) 496111729Sfenner (void)printf(" %s", proto->p_name); 497111729Sfenner else 498111729Sfenner (void)printf(" ip-proto-%d", ip->ip_p); 499111729Sfenner } 50056896Sfenner#ifndef IP_MF 50156896Sfenner#define IP_MF 0x2000 50256896Sfenner#endif /* IP_MF */ 50356896Sfenner#ifndef IP_DF 50456896Sfenner#define IP_DF 0x4000 50556896Sfenner#endif /* IP_DF */ 50656896Sfenner (void)printf(" (frag %d:%u@%d%s)", ntohs(ip->ip_id), len, 50717680Spst (off & 0x1fff) * 8, 50817680Spst (off & IP_MF)? "+" : ""); 50956896Sfenner 51017680Spst } else if (off & IP_DF) 51117680Spst (void)printf(" (DF)"); 51217680Spst 51356896Sfenner if (ip->ip_tos) { 51456896Sfenner (void)printf(" [tos 0x%x", (int)ip->ip_tos); 51556896Sfenner /* ECN bits */ 51698527Sfenner if (ip->ip_tos & 0x03) { 51798527Sfenner switch (ip->ip_tos & 0x03) { 51898527Sfenner case 1: 51998527Sfenner (void)printf(",ECT(1)"); 52098527Sfenner break; 52198527Sfenner case 2: 52298527Sfenner (void)printf(",ECT(0)"); 52398527Sfenner break; 52498527Sfenner case 3: 52556896Sfenner (void)printf(",CE"); 52698527Sfenner } 52756896Sfenner } 52856896Sfenner (void)printf("] "); 52956896Sfenner } 53056896Sfenner 53117680Spst if (ip->ip_ttl <= 1) 53217680Spst (void)printf(" [ttl %d]", (int)ip->ip_ttl); 53317680Spst 53417680Spst if (vflag) { 53517680Spst int sum; 53617680Spst char *sep = ""; 53717680Spst 53817680Spst printf(" ("); 53917680Spst if (ip->ip_ttl > 1) { 54017680Spst (void)printf("%sttl %d", sep, (int)ip->ip_ttl); 54117680Spst sep = ", "; 54217680Spst } 54317680Spst if ((off & 0x3fff) == 0) { 54417680Spst (void)printf("%sid %d", sep, (int)ntohs(ip->ip_id)); 54517680Spst sep = ", "; 54617680Spst } 54775118Sfenner (void)printf("%slen %d", sep, (int)ntohs(ip->ip_len)); 54875118Sfenner sep = ", "; 54917680Spst if ((u_char *)ip + hlen <= snapend) { 55056896Sfenner sum = in_cksum((const u_short *)ip, hlen, 0); 55117680Spst if (sum != 0) { 55217680Spst (void)printf("%sbad cksum %x!", sep, 55317680Spst ntohs(ip->ip_sum)); 55417680Spst sep = ", "; 55517680Spst } 55617680Spst } 55717680Spst if ((hlen -= sizeof(struct ip)) > 0) { 55817680Spst (void)printf("%soptlen=%d", sep, hlen); 55917680Spst ip_optprint((u_char *)(ip + 1), hlen); 56017680Spst } 56117680Spst printf(")"); 56217680Spst } 56317680Spst} 56475118Sfenner 56575118Sfennervoid 56675118SfenneripN_print(register const u_char *bp, register u_int length) 56775118Sfenner{ 56875118Sfenner struct ip *ip, hdr; 56975118Sfenner 57075118Sfenner ip = (struct ip *)bp; 57175118Sfenner if (length < 4) { 57275118Sfenner (void)printf("truncated-ip %d", length); 57375118Sfenner return; 57475118Sfenner } 57575118Sfenner memcpy (&hdr, (char *)ip, 4); 57675118Sfenner switch (IP_V(&hdr)) { 57775118Sfenner case 4: 57898527Sfenner ip_print (bp, length); 57998527Sfenner return; 58075118Sfenner#ifdef INET6 58175118Sfenner case 6: 58298527Sfenner ip6_print (bp, length); 58398527Sfenner return; 58475118Sfenner#endif 58575118Sfenner default: 58698527Sfenner (void)printf("unknown ip %d", IP_V(&hdr)); 58798527Sfenner return; 58875118Sfenner } 58975118Sfenner} 590