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 __APPLE__ 30 31#define NETDISSECT_REWORKED 32#ifdef HAVE_CONFIG_H 33#include "config.h" 34#endif 35 36#include <tcpdump-stdinc.h> 37 38#define __APPLE_PCAP_NG_API 39#include <net/pktap.h> 40#include <pcap.h> 41 42#ifdef DLT_PCAPNG 43#include <pcap/pcap-ng.h> 44#include <pcap/pcap-util.h> 45#endif /* DLT_PCAPNG */ 46 47#include <stdio.h> 48#include <string.h> 49#include <stdlib.h> 50#include <sys/queue.h> 51 52#include "netdissect.h" 53#include "interface.h" 54#include "pktmetadatafilter.h" 55 56extern node_t *pkt_meta_data_expression; 57 58extern netdissect_options *gndo; 59 60extern char *filter_src_buf; 61 62extern int pktap_if_count; 63 64extern u_int packets_mtdt_fltr_drop; 65 66extern char *svc2str(uint32_t); 67 68 69/* 70 * Returns zero if the packet doesn't match, non-zero if it matches 71 */ 72int 73pktap_filter_packet(pcap_t *pcap, struct pcap_if_info *if_info, 74 const struct pcap_pkthdr *h, const u_char *sp) 75{ 76 struct pktap_header *pktp_hdr; 77 const u_char *pkt_data; 78 int match = 0; 79 80 pktp_hdr = (struct pktap_header *)sp; 81 82 if (h->len < sizeof(struct pktap_header) || 83 h->caplen < sizeof(struct pktap_header) || 84 pktp_hdr->pth_length > h->caplen) { 85 error("%s: Packet too short", __func__); 86 return (0); 87 } 88 89 if (if_info == NULL) { 90 if_info = pcap_find_if_info_by_name(pcap, pktp_hdr->pth_ifname); 91 /* 92 * New interface 93 */ 94 if (if_info == NULL) { 95 if_info = pcap_add_if_info(pcap, pktp_hdr->pth_ifname, 96 -1, pktp_hdr->pth_dlt, gndo->ndo_snaplen); 97 if (if_info == NULL) { 98 error("%s: pcap_add_if_info(%s, %u) failed: %s", 99 __func__, pktp_hdr->pth_ifname, pktp_hdr->pth_dlt, pcap_geterr(pcap)); 100 return (0); 101 } 102 } 103 } 104 105 if (if_info->if_filter_program.bf_insns == NULL) 106 match = 1; 107 else { 108 /* 109 * The actual data packet is past the packet tap header 110 */ 111 struct pcap_pkthdr tmp_hdr; 112 113 bcopy(h, &tmp_hdr, sizeof(struct pcap_pkthdr)); 114 115 tmp_hdr.caplen -= pktp_hdr->pth_length; 116 tmp_hdr.len -= pktp_hdr->pth_length; 117 118 pkt_data = sp + pktp_hdr->pth_length; 119 120 match = pcap_offline_filter(&if_info->if_filter_program, &tmp_hdr, pkt_data); 121 } 122 /* 123 * Filter on packet metadata 124 */ 125 if (match && pkt_meta_data_expression != NULL) { 126 struct pkt_meta_data pmd; 127 128 pmd.itf = &pktp_hdr->pth_ifname[0]; 129 pmd.proc = &pktp_hdr->pth_comm[0]; 130 pmd.eproc = &pktp_hdr->pth_ecomm[0]; 131 pmd.pid = pktp_hdr->pth_pid; 132 pmd.epid = pktp_hdr->pth_epid; 133 pmd.svc = svc2str(pktp_hdr->pth_svc); 134 pmd.dir = (pktp_hdr->pth_flags & PTH_FLAG_DIR_IN) ? "in" : 135 (pktp_hdr->pth_flags & PTH_FLAG_DIR_OUT) ? "out" : ""; 136 137 match = evaluate_expression(pkt_meta_data_expression, &pmd); 138 if (match == 0) 139 packets_mtdt_fltr_drop++; 140 } 141 142 return (match); 143} 144 145#endif /* __APPLE__ */ 146