1511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 2511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * This code is derived from code formerly in pcap-dlpi.c, originally 3511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * contributed by Atanu Ghosh (atanu@cs.ucl.ac.uk), University College 4511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * London, and subsequently modified by Guy Harris (guy@alum.mit.edu), 5511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Mark Pizzolato <List-tcpdump-workers@subscriptions.pizzolato.net>, 6511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Mark C. Brown (mbrown@hp.com), and Sagun Shakya <Sagun.Shakya@Sun.COM>. 7511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 8511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 9511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 10511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * This file contains dlpi/libdlpi related common functions used 11511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * by pcap-[dlpi,libdlpi].c. 12511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 13511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 14511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef HAVE_CONFIG_H 15511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include "config.h" 16511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 17511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 18511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifndef DL_IPATM 19511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define DL_IPATM 0x12 /* ATM Classical IP interface */ 20511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 21511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 22511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef HAVE_SYS_BUFMOD_H 23511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 24511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Size of a bufmod chunk to pass upstream; that appears to be the 25511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * biggest value to which you can set it, and setting it to that value 26511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * (which is bigger than what appears to be the Solaris default of 8192) 27511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * reduces the number of packet drops. 28511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 29511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define CHUNKSIZE 65536 30511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 31511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 32511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Size of the buffer to allocate for packet data we read; it must be 33511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * large enough to hold a chunk. 34511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 35511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define PKTBUFSIZE CHUNKSIZE 36511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 37511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#else /* HAVE_SYS_BUFMOD_H */ 38511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 39511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 40511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Size of the buffer to allocate for packet data we read; this is 41511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * what the value used to be - there's no particular reason why it 42511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * should be tied to MAXDLBUF, but we'll leave it as this for now. 43511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 44511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define MAXDLBUF 8192 45511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define PKTBUFSIZE (MAXDLBUF * sizeof(bpf_u_int32)) 46511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 47511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 48511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 49511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <sys/types.h> 50511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <sys/time.h> 51511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef HAVE_SYS_BUFMOD_H 52511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <sys/bufmod.h> 53511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 54511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <sys/dlpi.h> 55511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <sys/stream.h> 56511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 57511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <errno.h> 58511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <memory.h> 59511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <stdio.h> 60511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <stdlib.h> 61511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <string.h> 62511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <stropts.h> 63511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <unistd.h> 64511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 65511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef HAVE_LIBDLPI 66511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <libdlpi.h> 67511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 68511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 69511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include "pcap-int.h" 70511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include "dlpisubs.h" 71511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 72511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef HAVE_SYS_BUFMOD_H 73511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void pcap_stream_err(const char *, int, char *); 74511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 75511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 76511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 77511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Get the packet statistics. 78511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 79511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallint 80511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallpcap_stats_dlpi(pcap_t *p, struct pcap_stat *ps) 81511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 82511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct pcap_dlpi *pd = p->priv; 83511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 84511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 85511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * "ps_recv" counts packets handed to the filter, not packets 86511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * that passed the filter. As filtering is done in userland, 87511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * this would not include packets dropped because we ran out 88511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * of buffer space; in order to make this more like other 89511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * platforms (Linux 2.4 and later, BSDs with BPF), where the 90511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * "packets received" count includes packets received but dropped 91511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * due to running out of buffer space, and to keep from confusing 92511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * applications that, for example, compute packet drop percentages, 93511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * we also make it count packets dropped by "bufmod" (otherwise we 94511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * might run the risk of the packet drop count being bigger than 95511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * the received-packet count). 96511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 97511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * "ps_drop" counts packets dropped by "bufmod" because of 98511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * flow control requirements or resource exhaustion; it doesn't 99511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * count packets dropped by the interface driver, or packets 100511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * dropped upstream. As filtering is done in userland, it counts 101511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * packets regardless of whether they would've passed the filter. 102511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 103511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * These statistics don't include packets not yet read from 104511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * the kernel by libpcap, but they may include packets not 105511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * yet read from libpcap by the application. 106511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 107511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall *ps = pd->stat; 108511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 109511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 110511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Add in the drop count, as per the above comment. 111511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 112511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ps->ps_recv += ps->ps_drop; 113511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (0); 114511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 115511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 116511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 117511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Loop through the packets and call the callback for each packet. 118511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Return the number of packets read. 119511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 120511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallint 121511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallpcap_process_pkts(pcap_t *p, pcap_handler callback, u_char *user, 122511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int count, u_char *bufp, int len) 123511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 124511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct pcap_dlpi *pd = p->priv; 125511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int n, caplen, origlen; 126511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall u_char *ep, *pk; 127511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct pcap_pkthdr pkthdr; 128511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef HAVE_SYS_BUFMOD_H 129511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct sb_hdr *sbp; 130511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef LBL_ALIGN 131511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct sb_hdr sbhdr; 132511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 133511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 134511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 135511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* Loop through packets */ 136511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ep = bufp + len; 137511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall n = 0; 138511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 139511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef HAVE_SYS_BUFMOD_H 140511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall while (bufp < ep) { 141511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 142511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Has "pcap_breakloop()" been called? 143511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If so, return immediately - if we haven't read any 144511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * packets, clear the flag and return -2 to indicate 145511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * that we were told to break out of the loop, otherwise 146511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * leave the flag set, so that the *next* call will break 147511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * out of the loop without having read any packets, and 148511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * return the number of packets we've processed so far. 149511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 150511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (p->break_loop) { 151511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (n == 0) { 152511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->break_loop = 0; 153511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (-2); 154511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } else { 155511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->bp = bufp; 156511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->cc = ep - bufp; 157511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (n); 158511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 159511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 160511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef LBL_ALIGN 161511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if ((long)bufp & 3) { 162511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sbp = &sbhdr; 163511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall memcpy(sbp, bufp, sizeof(*sbp)); 164511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } else 165511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 166511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall sbp = (struct sb_hdr *)bufp; 167511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pd->stat.ps_drop = sbp->sbh_drops; 168511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pk = bufp + sizeof(*sbp); 169511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bufp += sbp->sbh_totlen; 170511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall origlen = sbp->sbh_origlen; 171511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall caplen = sbp->sbh_msglen; 172511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#else 173511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall origlen = len; 174511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall caplen = min(p->snapshot, len); 175511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pk = bufp; 176511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bufp += caplen; 177511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 178511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ++pd->stat.ps_recv; 179511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (bpf_filter(p->fcode.bf_insns, pk, origlen, caplen)) { 180511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef HAVE_SYS_BUFMOD_H 181511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pkthdr.ts.tv_sec = sbp->sbh_timestamp.tv_sec; 182511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pkthdr.ts.tv_usec = sbp->sbh_timestamp.tv_usec; 183511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#else 184511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (void) gettimeofday(&pkthdr.ts, NULL); 185511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 186511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pkthdr.len = origlen; 187511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pkthdr.caplen = caplen; 188511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* Insure caplen does not exceed snapshot */ 189965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes if (pkthdr.caplen > (bpf_u_int32)p->snapshot) 190965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes pkthdr.caplen = (bpf_u_int32)p->snapshot; 191511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall (*callback)(user, &pkthdr, pk); 192511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (++n >= count && !PACKET_COUNT_IS_UNLIMITED(count)) { 193511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->cc = ep - bufp; 194511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->bp = bufp; 195511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (n); 196511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 197511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 198511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef HAVE_SYS_BUFMOD_H 199511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 200511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 201511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->cc = 0; 202511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (n); 203511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 204511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 205511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 206511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Process the mac type. Returns -1 if no matching mac type found, otherwise 0. 207511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 208511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallint 209511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallpcap_process_mactype(pcap_t *p, u_int mactype) 210511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 211511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int retv = 0; 212511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 213511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall switch (mactype) { 214511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 215511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DL_CSMACD: 216511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DL_ETHER: 217511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->linktype = DLT_EN10MB; 218511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->offset = 2; 219511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 220511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * This is (presumably) a real Ethernet capture; give it a 221511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so 222511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * that an application can let you choose it, in case you're 223511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * capturing DOCSIS traffic that a Cisco Cable Modem 224511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Termination System is putting out onto an Ethernet (it 225511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * doesn't put an Ethernet header onto the wire, it puts raw 226511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * DOCSIS frames out on the wire inside the low-level 227511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Ethernet framing). 228511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 229511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->dlt_list = (u_int *)malloc(sizeof(u_int) * 2); 230511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* 231511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * If that fails, just leave the list empty. 232511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 233511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (p->dlt_list != NULL) { 234511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->dlt_list[0] = DLT_EN10MB; 235511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->dlt_list[1] = DLT_DOCSIS; 236511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->dlt_count = 2; 237511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 238511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 239511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 240511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DL_FDDI: 241511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->linktype = DLT_FDDI; 242511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->offset = 3; 243511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 244511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 245511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DL_TPR: 246511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* XXX - what about DL_TPB? Is that Token Bus? */ 247511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->linktype = DLT_IEEE802; 248511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->offset = 2; 249511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 250511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 251511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef HAVE_SOLARIS 252511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall case DL_IPATM: 253511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->linktype = DLT_SUNATM; 254511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->offset = 0; /* works for LANE and LLC encapsulation */ 255511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall break; 256511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 257511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 258965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#ifdef DL_IPV4 259965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes case DL_IPV4: 260965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes p->linktype = DLT_IPV4; 261965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes p->offset = 0; 262965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes break; 263965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#endif 264965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 265965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#ifdef DL_IPV6 266965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes case DL_IPV6: 267965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes p->linktype = DLT_IPV6; 268965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes p->offset = 0; 269965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes break; 270965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#endif 271965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 272965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#ifdef DL_IPNET 273965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes case DL_IPNET: 274965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes p->linktype = DLT_IPNET; 275965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes p->offset = 0; 276965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes break; 277965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes#endif 278965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes 279511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall default: 280965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "unknown mactype 0x%x", 281511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall mactype); 282511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall retv = -1; 283511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 284511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 285511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (retv); 286511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 287511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 288511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef HAVE_SYS_BUFMOD_H 289511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 290511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Push and configure the buffer module. Returns -1 for error, otherwise 0. 291511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 292511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallint 293511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallpcap_conf_bufmod(pcap_t *p, int snaplen) 294511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 295511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct timeval to; 296511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall bpf_u_int32 ss, chunksize; 297511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 298511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* Non-standard call to get the data nicely buffered. */ 299511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (ioctl(p->fd, I_PUSH, "bufmod") != 0) { 300511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pcap_stream_err("I_PUSH bufmod", errno, p->errbuf); 301511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (-1); 302511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 303511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 304511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall ss = snaplen; 305511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (ss > 0 && 306511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall strioctl(p->fd, SBIOCSSNAP, sizeof(ss), (char *)&ss) != 0) { 307511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pcap_stream_err("SBIOCSSNAP", errno, p->errbuf); 308511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (-1); 309511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 310511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 311511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (p->opt.immediate) { 312511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* Set the timeout to zero, for immediate delivery. */ 313511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall to.tv_sec = 0; 314511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall to.tv_usec = 0; 315511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (strioctl(p->fd, SBIOCSTIME, sizeof(to), (char *)&to) != 0) { 316511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pcap_stream_err("SBIOCSTIME", errno, p->errbuf); 317511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (-1); 318511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 319511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } else { 320511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* Set up the bufmod timeout. */ 321511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (p->opt.timeout != 0) { 322511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall to.tv_sec = p->opt.timeout / 1000; 323511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall to.tv_usec = (p->opt.timeout * 1000) % 1000000; 324511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (strioctl(p->fd, SBIOCSTIME, sizeof(to), (char *)&to) != 0) { 325511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pcap_stream_err("SBIOCSTIME", errno, p->errbuf); 326511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (-1); 327511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 328511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 329511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 330511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall /* Set the chunk length. */ 331511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall chunksize = CHUNKSIZE; 332511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (strioctl(p->fd, SBIOCSCHUNK, sizeof(chunksize), (char *)&chunksize) 333511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall != 0) { 334511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall pcap_stream_err("SBIOCSCHUNKP", errno, p->errbuf); 335511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (-1); 336511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 337511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 338511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 339511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (0); 340511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 341511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif /* HAVE_SYS_BUFMOD_H */ 342511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 343511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 344511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Allocate data buffer. Returns -1 if memory allocation fails, else 0. 345511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 346511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallint 347511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallpcap_alloc_databuf(pcap_t *p) 348511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 349511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall p->bufsize = PKTBUFSIZE; 350965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes p->buffer = malloc(p->bufsize + p->offset); 351511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if (p->buffer == NULL) { 352511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); 353511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (-1); 354511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall } 355511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 356511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (0); 357511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 358511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 359511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 360511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Issue a STREAMS I_STR ioctl. Returns -1 on error, otherwise 361511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * length of returned data on success. 362511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 363511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallint 364511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstrioctl(int fd, int cmd, int len, char *dp) 365511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 366511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall struct strioctl str; 367511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall int retv; 368511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 369511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall str.ic_cmd = cmd; 370511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall str.ic_timout = -1; 371511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall str.ic_len = len; 372511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall str.ic_dp = dp; 373511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall if ((retv = ioctl(fd, I_STR, &str)) < 0) 374511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (retv); 375511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 376511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall return (str.ic_len); 377511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 378511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall 379511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef HAVE_SYS_BUFMOD_H 380511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* 381511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Write stream error message to errbuf. 382511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */ 383511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void 384511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallpcap_stream_err(const char *func, int err, char *errbuf) 385511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{ 386965a4b5291eead2d8f826d2c87e58a12bb56a214Elliott Hughes pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", func, pcap_strerror(err)); 387511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall} 388511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif 389