1/* 2 * Copyright (c) 2012-2013 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 29#ifdef HAVE_CONFIG_H 30#include "config.h" 31#endif 32 33#include <tcpdump-stdinc.h> 34 35#include <pcap.h> 36 37#include "interface.h" 38 39#ifdef DLT_PKTAP 40 41#include <net/pktap.h> 42#include <strings.h> 43 44extern char *svc2str(uint32_t); 45 46#define DEBUG 1 47#ifdef DEBUG 48void 49print_pktap_header(struct pktap_header *pktp_hdr) 50{ 51 printf("pth_length %u (sizeof(struct pktap_header) %lu)\n", 52 pktp_hdr->pth_length, sizeof(struct pktap_header)); 53 printf("pth_type_next %u\n", pktp_hdr->pth_type_next); 54 printf("pth_dlt %u\n", pktp_hdr->pth_dlt); 55 printf("pth_ifname %s\n", pktp_hdr->pth_ifname); 56 printf("pth_flags 0x%x\n", pktp_hdr->pth_flags); 57 printf("pth_protocol_family %u\n", pktp_hdr->pth_protocol_family); 58 printf("pth_frame_pre_length %u\n", pktp_hdr->pth_frame_pre_length); 59 printf("pth_frame_post_length %u\n", pktp_hdr->pth_frame_post_length); 60 printf("pth_pid %d\n", pktp_hdr->pth_pid); 61 printf("pth_comm %s\n", pktp_hdr->pth_comm); 62 printf("pth_svc %u\n", pktp_hdr->pth_svc); 63 printf("pth_epid %d\n", pktp_hdr->pth_epid); 64 printf("pth_ecomm %s\n", pktp_hdr->pth_ecomm); 65} 66#endif /* DEBUG */ 67 68u_int 69pktap_if_print(struct netdissect_options *ndo, const struct pcap_pkthdr *h, 70 const u_char *p) 71{ 72 struct pktap_header *pktp_hdr; 73 uint32_t dlt; 74 if_ndo_printer ndo_printer; 75 if_printer printer; 76 struct pcap_pkthdr tmp_hdr; 77 78 pktp_hdr = (struct pktap_header *)p; 79 80 if (h->len < sizeof(struct pktap_header) || 81 h->caplen < sizeof(struct pktap_header) || 82 pktp_hdr->pth_length > h->caplen) { 83 ND_PRINT((ndo, "[|pktap]")); 84 return sizeof(struct pktap_header); 85 } 86 87#ifdef DEBUG 88 if (eflag > 1) 89 print_pktap_header(pktp_hdr); 90#endif 91 92 if (kflag != PRMD_NONE) { 93 const char *prsep = ""; 94 95 ND_PRINT((ndo, "(")); 96 97 if (kflag & PRMD_IF) { 98 ND_PRINT((ndo, "%s", pktp_hdr->pth_ifname)); 99 prsep = ", "; 100 } 101 if (pktp_hdr->pth_pid != -1) { 102 switch ((kflag & (PRMD_PNAME |PRMD_PID))) { 103 case (PRMD_PNAME |PRMD_PID): 104 ND_PRINT((ndo, "%sproc %s:%u", 105 prsep, 106 pktp_hdr->pth_comm, pktp_hdr->pth_pid)); 107 prsep = ", "; 108 if ((pktp_hdr->pth_flags & PTH_FLAG_PROC_DELEGATED)) { 109 ND_PRINT((ndo, "%seproc %s:%u", 110 prsep, 111 pktp_hdr->pth_ecomm, pktp_hdr->pth_epid)); 112 prsep = ", "; 113 } 114 break; 115 case PRMD_PNAME: 116 ND_PRINT((ndo, "%sproc %s", 117 prsep, 118 pktp_hdr->pth_comm)); 119 prsep = ", "; 120 if ((pktp_hdr->pth_flags & PTH_FLAG_PROC_DELEGATED)) { 121 ND_PRINT((ndo, "%seproc %s", 122 prsep, 123 pktp_hdr->pth_ecomm)); 124 prsep = ", "; 125 } 126 break; 127 128 case PRMD_PID: 129 ND_PRINT((ndo, "%sproc %u", 130 prsep, 131 pktp_hdr->pth_pid)); 132 prsep = ", "; 133 if ((pktp_hdr->pth_flags & PTH_FLAG_PROC_DELEGATED)) { 134 ND_PRINT((ndo, "%seproc %u", 135 prsep, 136 pktp_hdr->pth_epid)); 137 prsep = ", "; 138 } 139 break; 140 141 default: 142 break; 143 } 144 } 145 if ((kflag & PRMD_SVC) && pktp_hdr->pth_svc != -1) { 146 ND_PRINT((ndo, "%ssvc %s", 147 prsep, 148 svc2str(pktp_hdr->pth_svc))); 149 prsep = ", "; 150 } 151 if (kflag & PRMD_DIR) { 152 if ((pktp_hdr->pth_flags & PTH_FLAG_DIR_IN)) { 153 ND_PRINT((ndo, "%sin", 154 prsep)); 155 prsep = ", "; 156 } else if ((pktp_hdr->pth_flags & PTH_FLAG_DIR_OUT)) { 157 ND_PRINT((ndo, "%sout", 158 prsep)); 159 prsep = ", "; 160 } 161 } 162 ND_PRINT((ndo, ") ")); 163 } 164 165 /* 166 * Compensate for the pktap header 167 */ 168 bcopy(h, &tmp_hdr, sizeof(struct pcap_pkthdr)); 169 tmp_hdr.caplen -= pktp_hdr->pth_length; 170 tmp_hdr.len -= pktp_hdr->pth_length; 171 p += pktp_hdr->pth_length; 172 173 dlt = pktp_hdr->pth_dlt; 174 175 if ((printer = lookup_printer(dlt)) != NULL) { 176 printer(&tmp_hdr, p); 177 } else if ((ndo_printer = lookup_ndo_printer(dlt)) != NULL) { 178 ndo_printer(ndo, &tmp_hdr, p); 179 } else { 180 if (!ndo->ndo_suppress_default_print) 181 ndo->ndo_default_print(ndo, p,tmp_hdr.caplen); 182 } 183 184 return sizeof(struct pktap_header); 185} 186 187#endif /* DLT_PKTAP */ 188