1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This code is derived from code formerly in pcap-dlpi.c, originally 3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * contributed by Atanu Ghosh (atanu@cs.ucl.ac.uk), University College 4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * London, and subsequently modified by Guy Harris (guy@alum.mit.edu), 5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Mark Pizzolato <List-tcpdump-workers@subscriptions.pizzolato.net>, 6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Mark C. Brown (mbrown@hp.com), and Sagun Shakya <Sagun.Shakya@Sun.COM>. 7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This file contains dlpi/libdlpi related common functions used 11083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org * by pcap-[dlpi,libdlpi].c. 12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 133f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org#ifndef lint 14b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic const char rcsid[] _U_ = 15ea7b33ee032bd2d1528384e26ba079dee0d280fbwu@webrtc.org "@(#) $Header: /tcpdump/master/libpcap/dlpisubs.c,v 1.3 2008-12-02 16:40:19 guy Exp $ (LBL)"; 167e5dc8741fbd5f07a709e6fd4d2cd8b08b7cee94pbos@webrtc.org#endif 177e5dc8741fbd5f07a709e6fd4d2cd8b08b7cee94pbos@webrtc.org 187e5dc8741fbd5f07a709e6fd4d2cd8b08b7cee94pbos@webrtc.org#ifdef HAVE_CONFIG_H 19b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "config.h" 20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif 21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 22083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org#ifndef DL_IPATM 23e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org#define DL_IPATM 0x12 /* ATM Classical IP interface */ 24e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org#endif 25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef HAVE_SYS_BUFMOD_H 27083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org /* 28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Size of a bufmod chunk to pass upstream; that appears to be the 29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * biggest value to which you can set it, and setting it to that value 30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * (which is bigger than what appears to be the Solaris default of 8192) 31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * reduces the number of packet drops. 32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#define CHUNKSIZE 65536 34e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org 35e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org /* 36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Size of the buffer to allocate for packet data we read; it must be 37d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org * large enough to hold a chunk. 38d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org */ 39083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org#define PKTBUFSIZE CHUNKSIZE 40d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 41d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org#else /* HAVE_SYS_BUFMOD_H */ 42d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org 43d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org /* 4415bdfdfd464bfb1226ada48219890e3139d820afhclam@chromium.org * Size of the buffer to allocate for packet data we read; this is 45d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org * what the value used to be - there's no particular reason why it 46d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org * should be tied to MAXDLBUF, but we'll leave it as this for now. 47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#define MAXDLBUF 8192 49d60137ff1b936534b04396298b7d2f2ebbc1da82pbos@webrtc.org#define PKTBUFSIZE (MAXDLBUF * sizeof(bpf_u_int32)) 503bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org 51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif 5215bdfdfd464bfb1226ada48219890e3139d820afhclam@chromium.org 5315bdfdfd464bfb1226ada48219890e3139d820afhclam@chromium.org#include <sys/types.h> 54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <sys/time.h> 55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef HAVE_SYS_BUFMOD_H 56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <sys/bufmod.h> 57ea7b33ee032bd2d1528384e26ba079dee0d280fbwu@webrtc.org#endif 581bdf186e6ae8d2f1a7d055237a75c0d7fd189624wuchengli@chromium.org#include <sys/dlpi.h> 59083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org#include <sys/stream.h> 60ea7b33ee032bd2d1528384e26ba079dee0d280fbwu@webrtc.org 61ea7b33ee032bd2d1528384e26ba079dee0d280fbwu@webrtc.org#include <errno.h> 62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <memory.h> 633bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org#include <stdio.h> 64083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org#include <stdlib.h> 65083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org#include <string.h> 66083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org#include <stropts.h> 67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <unistd.h> 68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 69083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org#ifdef HAVE_LIBDLPI 70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <libdlpi.h> 71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif 72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 7315bdfdfd464bfb1226ada48219890e3139d820afhclam@chromium.org#include "pcap-int.h" 7415bdfdfd464bfb1226ada48219890e3139d820afhclam@chromium.org#include "dlpisubs.h" 75b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef HAVE_SYS_BUFMOD_H 77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic void pcap_stream_err(const char *, int, char *); 78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif 79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 81083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org * Get the packet statistics. 82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 833bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.orgint 84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgpcap_stats_dlpi(pcap_t *p, struct pcap_stat *ps) 85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org struct pcap_dlpi *pd = p->priv; 87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* 89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * "ps_recv" counts packets handed to the filter, not packets 90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * that passed the filter. As filtering is done in userland, 913bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org * this would not include packets dropped because we ran out 923bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org * of buffer space; in order to make this more like other 933bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org * platforms (Linux 2.4 and later, BSDs with BPF), where the 943bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org * "packets received" count includes packets received but dropped 95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * due to running out of buffer space, and to keep from confusing 96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * applications that, for example, compute packet drop percentages, 973bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org * we also make it count packets dropped by "bufmod" (otherwise we 98083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org * might run the risk of the packet drop count being bigger than 99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * the received-packet count). 100083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org * 101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * "ps_drop" counts packets dropped by "bufmod" because of 102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * flow control requirements or resource exhaustion; it doesn't 1033bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org * count packets dropped by the interface driver, or packets 1043bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org * dropped upstream. As filtering is done in userland, it counts 105083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org * packets regardless of whether they would've passed the filter. 106083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org * 107083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org * These statistics don't include packets not yet read from 108083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org * the kernel by libpcap, but they may include packets not 109083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org * yet read from libpcap by the application. 110083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org */ 111083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org *ps = pd->stat; 112083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org 113083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org /* 114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Add in the drop count, as per the above comment. 115083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org */ 116083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org ps->ps_recv += ps->ps_drop; 117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return (0); 118083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org} 119083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org 120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Loop through the packets and call the callback for each packet. 122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Return the number of packets read. 123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint 125e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.orgpcap_process_pkts(pcap_t *p, pcap_handler callback, u_char *user, 126ea7b33ee032bd2d1528384e26ba079dee0d280fbwu@webrtc.org int count, u_char *bufp, int len) 127ea7b33ee032bd2d1528384e26ba079dee0d280fbwu@webrtc.org{ 128ea7b33ee032bd2d1528384e26ba079dee0d280fbwu@webrtc.org struct pcap_dlpi *pd = p->priv; 129ea7b33ee032bd2d1528384e26ba079dee0d280fbwu@webrtc.org int n, caplen, origlen; 130ea7b33ee032bd2d1528384e26ba079dee0d280fbwu@webrtc.org u_char *ep, *pk; 131083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org struct pcap_pkthdr pkthdr; 132ea7b33ee032bd2d1528384e26ba079dee0d280fbwu@webrtc.org#ifdef HAVE_SYS_BUFMOD_H 133ea7b33ee032bd2d1528384e26ba079dee0d280fbwu@webrtc.org struct sb_hdr *sbp; 134ea7b33ee032bd2d1528384e26ba079dee0d280fbwu@webrtc.org#ifdef LBL_ALIGN 135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org struct sb_hdr sbhdr; 136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif 137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif 138e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org 139083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org /* Loop through packets */ 140083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org ep = bufp + len; 141083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org n = 0; 142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 143083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org#ifdef HAVE_SYS_BUFMOD_H 144083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org while (bufp < ep) { 145083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org /* 146083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org * Has "pcap_breakloop()" been called? 147083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org * If so, return immediately - if we haven't read any 148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * packets, clear the flag and return -2 to indicate 149083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org * that we were told to break out of the loop, otherwise 150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * leave the flag set, so that the *next* call will break 151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * out of the loop without having read any packets, and 152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * return the number of packets we've processed so far. 153e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org */ 154083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org if (p->break_loop) { 155083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org if (n == 0) { 156083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org p->break_loop = 0; 157083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org return (-2); 158083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org } else { 159083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org p->bp = bufp; 160083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org p->cc = ep - bufp; 161083049f2945b2924203b25c8428300d40d994f35henrike@webrtc.org return (n); 162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 163e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org } 164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef LBL_ALIGN 165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((long)bufp & 3) { 166e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org sbp = &sbhdr; 167e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org memcpy(sbp, bufp, sizeof(*sbp)); 168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } else 169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif 170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sbp = (struct sb_hdr *)bufp; 171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pd->stat.ps_drop = sbp->sbh_drops; 172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pk = bufp + sizeof(*sbp); 173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bufp += sbp->sbh_totlen; 174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org origlen = sbp->sbh_origlen; 175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org caplen = sbp->sbh_msglen; 176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#else 177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org origlen = len; 178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org caplen = min(p->snapshot, len); 179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pk = bufp; 180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bufp += caplen; 181#endif 182 ++pd->stat.ps_recv; 183 if (bpf_filter(p->fcode.bf_insns, pk, origlen, caplen)) { 184#ifdef HAVE_SYS_BUFMOD_H 185 pkthdr.ts.tv_sec = sbp->sbh_timestamp.tv_sec; 186 pkthdr.ts.tv_usec = sbp->sbh_timestamp.tv_usec; 187#else 188 (void) gettimeofday(&pkthdr.ts, NULL); 189#endif 190 pkthdr.len = origlen; 191 pkthdr.caplen = caplen; 192 /* Insure caplen does not exceed snapshot */ 193 if (pkthdr.caplen > p->snapshot) 194 pkthdr.caplen = p->snapshot; 195 (*callback)(user, &pkthdr, pk); 196 if (++n >= count && !PACKET_COUNT_IS_UNLIMITED(count)) { 197 p->cc = ep - bufp; 198 p->bp = bufp; 199 return (n); 200 } 201 } 202#ifdef HAVE_SYS_BUFMOD_H 203 } 204#endif 205 p->cc = 0; 206 return (n); 207} 208 209/* 210 * Process the mac type. Returns -1 if no matching mac type found, otherwise 0. 211 */ 212int 213pcap_process_mactype(pcap_t *p, u_int mactype) 214{ 215 int retv = 0; 216 217 switch (mactype) { 218 219 case DL_CSMACD: 220 case DL_ETHER: 221 p->linktype = DLT_EN10MB; 222 p->offset = 2; 223 /* 224 * This is (presumably) a real Ethernet capture; give it a 225 * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so 226 * that an application can let you choose it, in case you're 227 * capturing DOCSIS traffic that a Cisco Cable Modem 228 * Termination System is putting out onto an Ethernet (it 229 * doesn't put an Ethernet header onto the wire, it puts raw 230 * DOCSIS frames out on the wire inside the low-level 231 * Ethernet framing). 232 */ 233 p->dlt_list = (u_int *)malloc(sizeof(u_int) * 2); 234 /* 235 * If that fails, just leave the list empty. 236 */ 237 if (p->dlt_list != NULL) { 238 p->dlt_list[0] = DLT_EN10MB; 239 p->dlt_list[1] = DLT_DOCSIS; 240 p->dlt_count = 2; 241 } 242 break; 243 244 case DL_FDDI: 245 p->linktype = DLT_FDDI; 246 p->offset = 3; 247 break; 248 249 case DL_TPR: 250 /* XXX - what about DL_TPB? Is that Token Bus? */ 251 p->linktype = DLT_IEEE802; 252 p->offset = 2; 253 break; 254 255#ifdef HAVE_SOLARIS 256 case DL_IPATM: 257 p->linktype = DLT_SUNATM; 258 p->offset = 0; /* works for LANE and LLC encapsulation */ 259 break; 260#endif 261 262 default: 263 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "unknown mactype %u", 264 mactype); 265 retv = -1; 266 } 267 268 return (retv); 269} 270 271#ifdef HAVE_SYS_BUFMOD_H 272/* 273 * Push and configure the buffer module. Returns -1 for error, otherwise 0. 274 */ 275int 276pcap_conf_bufmod(pcap_t *p, int snaplen) 277{ 278 struct timeval to; 279 bpf_u_int32 ss, chunksize; 280 281 /* Non-standard call to get the data nicely buffered. */ 282 if (ioctl(p->fd, I_PUSH, "bufmod") != 0) { 283 pcap_stream_err("I_PUSH bufmod", errno, p->errbuf); 284 return (-1); 285 } 286 287 ss = snaplen; 288 if (ss > 0 && 289 strioctl(p->fd, SBIOCSSNAP, sizeof(ss), (char *)&ss) != 0) { 290 pcap_stream_err("SBIOCSSNAP", errno, p->errbuf); 291 return (-1); 292 } 293 294 if (p->opt.immediate) { 295 /* Set the timeout to zero, for immediate delivery. */ 296 to.tv_sec = 0; 297 to.tv_usec = 0; 298 if (strioctl(p->fd, SBIOCSTIME, sizeof(to), (char *)&to) != 0) { 299 pcap_stream_err("SBIOCSTIME", errno, p->errbuf); 300 return (-1); 301 } 302 } else { 303 /* Set up the bufmod timeout. */ 304 if (p->opt.timeout != 0) { 305 to.tv_sec = p->opt.timeout / 1000; 306 to.tv_usec = (p->opt.timeout * 1000) % 1000000; 307 if (strioctl(p->fd, SBIOCSTIME, sizeof(to), (char *)&to) != 0) { 308 pcap_stream_err("SBIOCSTIME", errno, p->errbuf); 309 return (-1); 310 } 311 } 312 313 /* Set the chunk length. */ 314 chunksize = CHUNKSIZE; 315 if (strioctl(p->fd, SBIOCSCHUNK, sizeof(chunksize), (char *)&chunksize) 316 != 0) { 317 pcap_stream_err("SBIOCSCHUNKP", errno, p->errbuf); 318 return (-1); 319 } 320 } 321 322 return (0); 323} 324#endif /* HAVE_SYS_BUFMOD_H */ 325 326/* 327 * Allocate data buffer. Returns -1 if memory allocation fails, else 0. 328 */ 329int 330pcap_alloc_databuf(pcap_t *p) 331{ 332 p->bufsize = PKTBUFSIZE; 333 p->buffer = (u_char *)malloc(p->bufsize + p->offset); 334 if (p->buffer == NULL) { 335 strlcpy(p->errbuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); 336 return (-1); 337 } 338 339 return (0); 340} 341 342/* 343 * Issue a STREAMS I_STR ioctl. Returns -1 on error, otherwise 344 * length of returned data on success. 345 */ 346int 347strioctl(int fd, int cmd, int len, char *dp) 348{ 349 struct strioctl str; 350 int retv; 351 352 str.ic_cmd = cmd; 353 str.ic_timout = -1; 354 str.ic_len = len; 355 str.ic_dp = dp; 356 if ((retv = ioctl(fd, I_STR, &str)) < 0) 357 return (retv); 358 359 return (str.ic_len); 360} 361 362#ifdef HAVE_SYS_BUFMOD_H 363/* 364 * Write stream error message to errbuf. 365 */ 366static void 367pcap_stream_err(const char *func, int err, char *errbuf) 368{ 369 snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", func, pcap_strerror(err)); 370} 371#endif 372