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