xref: /freebsd/contrib/libpcap/pcap-dlpi.c (revision 8fc257994d0ce2396196d7a06d50d20c8015f4b7)
1 /*
2  * Copyright (c) 1993, 1994, 1995, 1996, 1997
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that: (1) source code distributions
7  * retain the above copyright notice and this paragraph in its entirety, (2)
8  * distributions including binary code include the above copyright notice and
9  * this paragraph in its entirety in the documentation or other materials
10  * provided with the distribution, and (3) all advertising materials mentioning
11  * features or use of this software display the following acknowledgement:
12  * ``This product includes software developed by the University of California,
13  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14  * the University nor the names of its contributors may be used to endorse
15  * or promote products derived from this software without specific prior
16  * written permission.
17  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20  *
21  * This code contributed by Atanu Ghosh (atanu@cs.ucl.ac.uk),
22  * University College London, and subsequently modified by
23  * Guy Harris (guy@alum.mit.edu), Mark Pizzolato
24  * <List-tcpdump-workers@subscriptions.pizzolato.net>,
25  * Mark C. Brown (mbrown@hp.com), and Sagun Shakya <Sagun.Shakya@Sun.COM>.
26  */
27 
28 /*
29  * Packet capture routine for DLPI under SunOS 5, HP-UX 9/10/11, and AIX.
30  *
31  * Notes:
32  *
33  *    - The DLIOCRAW ioctl() is specific to SunOS.
34  *
35  *    - There is a bug in bufmod(7) such that setting the snapshot
36  *      length results in data being left of the front of the packet.
37  *
38  *    - It might be desirable to use pfmod(7) to filter packets in the
39  *      kernel when possible.
40  *
41  *    - An older version of the HP-UX DLPI Programmer's Guide, which
42  *      I think was advertised as the 10.20 version, used to be available
43  *      at
44  *
45  *            http://docs.hp.com/hpux/onlinedocs/B2355-90093/B2355-90093.html
46  *
47  *      but is no longer available; it can still be found at
48  *
49  *            http://h21007.www2.hp.com/dspp/files/unprotected/Drivers/Docs/Refs/B2355-90093.pdf
50  *
51  *      in PDF form.
52  *
53  *    - The HP-UX 10.x, 11.0, and 11i v1.6 version of the HP-UX DLPI
54  *      Programmer's Guide, which I think was once advertised as the
55  *      11.00 version is available at
56  *
57  *            http://docs.hp.com/en/B2355-90139/index.html
58  *
59  *    - The HP-UX 11i v2 version of the HP-UX DLPI Programmer's Guide
60  *      is available at
61  *
62  *            http://docs.hp.com/en/B2355-90871/index.html
63  *
64  *    - All of the HP documents describe raw-mode services, which are
65  *      what we use if DL_HP_RAWDLS is defined.  XXX - we use __hpux
66  *      in some places to test for HP-UX, but use DL_HP_RAWDLS in
67  *      other places; do we support any versions of HP-UX without
68  *      DL_HP_RAWDLS?
69  */
70 
71 #ifndef lint
72 static const char rcsid[] _U_ =
73     "@(#) $Header: /tcpdump/master/libpcap/pcap-dlpi.c,v 1.116.2.11 2008-04-14 20:41:51 guy Exp $ (LBL)";
74 #endif
75 
76 #ifdef HAVE_CONFIG_H
77 #include "config.h"
78 #endif
79 
80 #include <sys/types.h>
81 #include <sys/time.h>
82 #ifdef HAVE_SYS_BUFMOD_H
83 #include <sys/bufmod.h>
84 #endif
85 #include <sys/dlpi.h>
86 #ifdef HAVE_SYS_DLPI_EXT_H
87 #include <sys/dlpi_ext.h>
88 #endif
89 #ifdef HAVE_HPUX9
90 #include <sys/socket.h>
91 #endif
92 #ifdef DL_HP_PPA_REQ
93 #include <sys/stat.h>
94 #endif
95 #include <sys/stream.h>
96 #if defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H)
97 #include <sys/systeminfo.h>
98 #endif
99 
100 #ifdef HAVE_HPUX9
101 #include <net/if.h>
102 #endif
103 
104 #include <ctype.h>
105 #ifdef HAVE_HPUX9
106 #include <nlist.h>
107 #endif
108 #include <errno.h>
109 #include <fcntl.h>
110 #include <memory.h>
111 #include <stdio.h>
112 #include <stdlib.h>
113 #include <string.h>
114 #include <stropts.h>
115 #include <unistd.h>
116 
117 #ifdef HAVE_LIMITS_H
118 #include <limits.h>
119 #else
120 #define INT_MAX		2147483647
121 #endif
122 
123 #include "pcap-int.h"
124 #include "dlpisubs.h"
125 
126 #ifdef HAVE_OS_PROTO_H
127 #include "os-proto.h"
128 #endif
129 
130 #ifndef PCAP_DEV_PREFIX
131 #ifdef _AIX
132 #define PCAP_DEV_PREFIX "/dev/dlpi"
133 #else
134 #define PCAP_DEV_PREFIX "/dev"
135 #endif
136 #endif
137 
138 #define	MAXDLBUF	8192
139 
140 /* Forwards */
141 static char *split_dname(char *, int *, char *);
142 static int dl_doattach(int, int, char *);
143 #ifdef DL_HP_RAWDLS
144 static int dl_dohpuxbind(int, char *);
145 #endif
146 static int dlattachreq(int, bpf_u_int32, char *);
147 static int dlbindreq(int, bpf_u_int32, char *);
148 static int dlbindack(int, char *, char *, int *);
149 static int dlpromisconreq(int, bpf_u_int32, char *);
150 static int dlokack(int, const char *, char *, char *);
151 static int dlinforeq(int, char *);
152 static int dlinfoack(int, char *, char *);
153 
154 #ifdef HAVE_DLPI_PASSIVE
155 static void dlpassive(int, char *);
156 #endif
157 
158 #ifdef DL_HP_RAWDLS
159 static int dlrawdatareq(int, const u_char *, int);
160 #endif
161 static int recv_ack(int, int, const char *, char *, char *, int *);
162 static char *dlstrerror(bpf_u_int32);
163 static char *dlprim(bpf_u_int32);
164 #if defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H)
165 static char *get_release(bpf_u_int32 *, bpf_u_int32 *, bpf_u_int32 *);
166 #endif
167 static int send_request(int, char *, int, char *, char *);
168 #ifdef HAVE_HPUX9
169 static int dlpi_kread(int, off_t, void *, u_int, char *);
170 #endif
171 #ifdef HAVE_DEV_DLPI
172 static int get_dlpi_ppa(int, const char *, int, char *);
173 #endif
174 
175 /* XXX Needed by HP-UX (at least) */
176 static bpf_u_int32 ctlbuf[MAXDLBUF];
177 static struct strbuf ctl = {
178 	MAXDLBUF,
179 	0,
180 	(char *)ctlbuf
181 };
182 
183 static int
184 pcap_read_dlpi(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
185 {
186 	int cc;
187 	u_char *bp;
188 	int flags;
189 	struct strbuf data;
190 
191 	flags = 0;
192 	cc = p->cc;
193 	if (cc == 0) {
194 		data.buf = (char *)p->buffer + p->offset;
195 		data.maxlen = p->bufsize;
196 		data.len = 0;
197 		do {
198 			/*
199 			 * Has "pcap_breakloop()" been called?
200 			 */
201 			if (p->break_loop) {
202 				/*
203 				 * Yes - clear the flag that indicates
204 				 * that it has, and return -2 to
205 				 * indicate that we were told to
206 				 * break out of the loop.
207 				 */
208 				p->break_loop = 0;
209 				return (-2);
210 			}
211 			/*
212 			 * XXX - check for the DLPI primitive, which
213 			 * would be DL_HP_RAWDATA_IND on HP-UX
214 			 * if we're in raw mode?
215 			 */
216 			if (getmsg(p->fd, &ctl, &data, &flags) < 0) {
217 				/* Don't choke when we get ptraced */
218 				switch (errno) {
219 
220 				case EINTR:
221 					cc = 0;
222 					continue;
223 
224 				case EAGAIN:
225 					return (0);
226 				}
227 				strlcpy(p->errbuf, pcap_strerror(errno),
228 				    sizeof(p->errbuf));
229 				return (-1);
230 			}
231 			cc = data.len;
232 		} while (cc == 0);
233 		bp = p->buffer + p->offset;
234 	} else
235 		bp = p->bp;
236 
237 	return (pcap_process_pkts(p, callback, user, cnt, bp, cc));
238 }
239 
240 static int
241 pcap_inject_dlpi(pcap_t *p, const void *buf, size_t size)
242 {
243 	int ret;
244 
245 #if defined(DLIOCRAW)
246 	ret = write(p->fd, buf, size);
247 	if (ret == -1) {
248 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
249 		    pcap_strerror(errno));
250 		return (-1);
251 	}
252 #elif defined(DL_HP_RAWDLS)
253 	if (p->send_fd < 0) {
254 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
255 		    "send: Output FD couldn't be opened");
256 		return (-1);
257 	}
258 	ret = dlrawdatareq(p->send_fd, buf, size);
259 	if (ret == -1) {
260 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
261 		    pcap_strerror(errno));
262 		return (-1);
263 	}
264 	/*
265 	 * putmsg() returns either 0 or -1; it doesn't indicate how
266 	 * many bytes were written (presumably they were all written
267 	 * or none of them were written).  OpenBSD's pcap_inject()
268 	 * returns the number of bytes written, so, for API compatibility,
269 	 * we return the number of bytes we were told to write.
270 	 */
271 	ret = size;
272 #else /* no raw mode */
273 	/*
274 	 * XXX - this is a pain, because you might have to extract
275 	 * the address from the packet and use it in a DL_UNITDATA_REQ
276 	 * request.  That would be dependent on the link-layer type.
277 	 *
278 	 * I also don't know what SAP you'd have to bind the descriptor
279 	 * to, or whether you'd need separate "receive" and "send" FDs,
280 	 * nor do I know whether you'd need different bindings for
281 	 * D/I/X Ethernet and 802.3, or for {FDDI,Token Ring} plus
282 	 * 802.2 and {FDDI,Token Ring} plus 802.2 plus SNAP.
283 	 *
284 	 * So, for now, we just return a "you can't send" indication,
285 	 * and leave it up to somebody with a DLPI-based system lacking
286 	 * both DLIOCRAW and DL_HP_RAWDLS to supply code to implement
287 	 * packet transmission on that system.  If they do, they should
288 	 * send it to us - but should not send us code that assumes
289 	 * Ethernet; if the code doesn't work on non-Ethernet interfaces,
290 	 * it should check "p->linktype" and reject the send request if
291 	 * it's anything other than DLT_EN10MB.
292 	 */
293 	strlcpy(p->errbuf, "send: Not supported on this version of this OS",
294 	    PCAP_ERRBUF_SIZE);
295 	ret = -1;
296 #endif /* raw mode */
297 	return (ret);
298 }
299 
300 #ifndef DL_IPATM
301 #define DL_IPATM	0x12	/* ATM Classical IP interface */
302 #endif
303 
304 #ifdef HAVE_SOLARIS
305 /*
306  * For SunATM.
307  */
308 #ifndef A_GET_UNITS
309 #define A_GET_UNITS	(('A'<<8)|118)
310 #endif /* A_GET_UNITS */
311 #ifndef A_PROMISCON_REQ
312 #define A_PROMISCON_REQ	(('A'<<8)|121)
313 #endif /* A_PROMISCON_REQ */
314 #endif /* HAVE_SOLARIS */
315 
316 static void
317 pcap_cleanup_dlpi(pcap_t *p)
318 {
319 	if (p->send_fd >= 0) {
320 		close(p->send_fd);
321 		p->send_fd = -1;
322 	}
323 	pcap_cleanup_live_common(p);
324 }
325 
326 static int
327 pcap_activate_dlpi(pcap_t *p)
328 {
329 	register char *cp;
330 	int ppa;
331 #ifdef HAVE_SOLARIS
332 	int isatm = 0;
333 #endif
334 	register dl_info_ack_t *infop;
335 #ifdef HAVE_SYS_BUFMOD_H
336 	bpf_u_int32 ss;
337 #ifdef HAVE_SOLARIS
338 	register char *release;
339 	bpf_u_int32 osmajor, osminor, osmicro;
340 #endif
341 #endif
342 	bpf_u_int32 buf[MAXDLBUF];
343 	char dname[100];
344 #ifndef HAVE_DEV_DLPI
345 	char dname2[100];
346 #endif
347 	int status = PCAP_ERROR;
348 
349 #ifdef HAVE_DEV_DLPI
350 	/*
351 	** Remove any "/dev/" on the front of the device.
352 	*/
353 	cp = strrchr(p->opt.source, '/');
354 	if (cp == NULL)
355 		strlcpy(dname, p->opt.source, sizeof(dname));
356 	else
357 		strlcpy(dname, cp + 1, sizeof(dname));
358 
359 	/*
360 	 * Split the device name into a device type name and a unit number;
361 	 * chop off the unit number, so "dname" is just a device type name.
362 	 */
363 	cp = split_dname(dname, &ppa, p->errbuf);
364 	if (cp == NULL) {
365 		status = PCAP_ERROR_NO_SUCH_DEVICE;
366 		goto bad;
367 	}
368 	*cp = '\0';
369 
370 	/*
371 	 * Use "/dev/dlpi" as the device.
372 	 *
373 	 * XXX - HP's DLPI Programmer's Guide for HP-UX 11.00 says that
374 	 * the "dl_mjr_num" field is for the "major number of interface
375 	 * driver"; that's the major of "/dev/dlpi" on the system on
376 	 * which I tried this, but there may be DLPI devices that
377 	 * use a different driver, in which case we may need to
378 	 * search "/dev" for the appropriate device with that major
379 	 * device number, rather than hardwiring "/dev/dlpi".
380 	 */
381 	cp = "/dev/dlpi";
382 	if ((p->fd = open(cp, O_RDWR)) < 0) {
383 		if (errno == EPERM || errno == EACCES)
384 			status = PCAP_ERROR_PERM_DENIED;
385 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
386 		    "%s: %s", cp, pcap_strerror(errno));
387 		goto bad;
388 	}
389 
390 #ifdef DL_HP_RAWDLS
391 	/*
392 	 * XXX - HP-UX 10.20 and 11.xx don't appear to support sending and
393 	 * receiving packets on the same descriptor - you need separate
394 	 * descriptors for sending and receiving, bound to different SAPs.
395 	 *
396 	 * If the open fails, we just leave -1 in "p->send_fd" and reject
397 	 * attempts to send packets, just as if, in pcap-bpf.c, we fail
398 	 * to open the BPF device for reading and writing, we just try
399 	 * to open it for reading only and, if that succeeds, just let
400 	 * the send attempts fail.
401 	 */
402 	p->send_fd = open(cp, O_RDWR);
403 #endif
404 
405 	/*
406 	 * Get a table of all PPAs for that device, and search that
407 	 * table for the specified device type name and unit number.
408 	 */
409 	ppa = get_dlpi_ppa(p->fd, dname, ppa, p->errbuf);
410 	if (ppa < 0) {
411 		status = ppa;
412 		goto bad;
413 	}
414 #else
415 	/*
416 	 * If the device name begins with "/", assume it begins with
417 	 * the pathname of the directory containing the device to open;
418 	 * otherwise, concatenate the device directory name and the
419 	 * device name.
420 	 */
421 	if (*p->opt.source == '/')
422 		strlcpy(dname, p->opt.source, sizeof(dname));
423 	else
424 		snprintf(dname, sizeof(dname), "%s/%s", PCAP_DEV_PREFIX,
425 		    p->opt.source);
426 
427 	/*
428 	 * Get the unit number, and a pointer to the end of the device
429 	 * type name.
430 	 */
431 	cp = split_dname(dname, &ppa, p->errbuf);
432 	if (cp == NULL) {
433 		status = PCAP_ERROR_NO_SUCH_DEVICE;
434 		goto bad;
435 	}
436 
437 	/*
438 	 * Make a copy of the device pathname, and then remove the unit
439 	 * number from the device pathname.
440 	 */
441 	strlcpy(dname2, dname, sizeof(dname));
442 	*cp = '\0';
443 
444 	/* Try device without unit number */
445 	if ((p->fd = open(dname, O_RDWR)) < 0) {
446 		if (errno != ENOENT) {
447 			if (errno == EACCES)
448 				status = PCAP_ERROR_PERM_DENIED;
449 			snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s", dname,
450 			    pcap_strerror(errno));
451 			goto bad;
452 		}
453 
454 		/* Try again with unit number */
455 		if ((p->fd = open(dname2, O_RDWR)) < 0) {
456 			if (errno == ENOENT) {
457 				status = PCAP_ERROR_NO_SUCH_DEVICE;
458 
459 				/*
460 				 * We provide an error message even
461 				 * for this error, for diagnostic
462 				 * purposes (so that, for example,
463 				 * the app can show the message if the
464 				 * user requests it).
465 				 *
466 				 * In it, we just report "No DLPI device
467 				 * found" with the device name, so people
468 				 * don't get confused and think, for example,
469 				 * that if they can't capture on "lo0"
470 				 * on Solaris the fix is to change libpcap
471 				 * (or the application that uses it) to
472 				 * look for something other than "/dev/lo0",
473 				 * as the fix is to look for an operating
474 				 * system other than Solaris - you just
475 				 * *can't* capture on a loopback interface
476 				 * on Solaris, the lack of a DLPI device
477 				 * for the loopback interface is just a
478 				 * symptom of that inability.
479 				 */
480 				snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
481 				    "%s: No DLPI device found", p->opt.source);
482 			} else {
483 				if (errno == EACCES)
484 					status = PCAP_ERROR_PERM_DENIED;
485 				snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
486 				    dname2, pcap_strerror(errno));
487 			}
488 			goto bad;
489 		}
490 		/* XXX Assume unit zero */
491 		ppa = 0;
492 	}
493 #endif
494 
495 	/*
496 	** Attach if "style 2" provider
497 	*/
498 	if (dlinforeq(p->fd, p->errbuf) < 0 ||
499 	    dlinfoack(p->fd, (char *)buf, p->errbuf) < 0)
500 		goto bad;
501 	infop = &((union DL_primitives *)buf)->info_ack;
502 #ifdef HAVE_SOLARIS
503 	if (infop->dl_mac_type == DL_IPATM)
504 		isatm = 1;
505 #endif
506 	if (infop->dl_provider_style == DL_STYLE2) {
507 		status = dl_doattach(p->fd, ppa, p->errbuf);
508 		if (status < 0)
509 			goto bad;
510 #ifdef DL_HP_RAWDLS
511 		if (p->send_fd >= 0) {
512 			if (dl_doattach(p->send_fd, ppa, p->errbuf) < 0)
513 				goto bad;
514 		}
515 #endif
516 	}
517 
518 	if (p->opt.rfmon) {
519 		/*
520 		 * This device exists, but we don't support monitor mode
521 		 * any platforms that support DLPI.
522 		 */
523 		status = PCAP_ERROR_RFMON_NOTSUP;
524 		goto bad;
525 	}
526 
527 #ifdef HAVE_DLPI_PASSIVE
528 	/*
529 	 * Enable Passive mode to be able to capture on aggregated link.
530 	 * Not supported in all Solaris versions.
531 	 */
532 	dlpassive(p->fd, p->errbuf);
533 #endif
534 	/*
535 	** Bind (defer if using HP-UX 9 or HP-UX 10.20 or later, totally
536 	** skip if using SINIX)
537 	*/
538 #if !defined(HAVE_HPUX9) && !defined(HAVE_HPUX10_20_OR_LATER) && !defined(sinix)
539 #ifdef _AIX
540 	/*
541 	** AIX.
542 	** According to IBM's AIX Support Line, the dl_sap value
543 	** should not be less than 0x600 (1536) for standard Ethernet.
544 	** However, we seem to get DL_BADADDR - "DLSAP addr in improper
545 	** format or invalid" - errors if we use 1537 on the "tr0"
546 	** device, which, given that its name starts with "tr" and that
547 	** it's IBM, probably means a Token Ring device.  (Perhaps we
548 	** need to use 1537 on "/dev/dlpi/en" because that device is for
549 	** D/I/X Ethernet, the "SAP" is actually an Ethernet type, and
550 	** it rejects invalid Ethernet types.)
551 	**
552 	** So if 1537 fails, we try 2, as Hyung Sik Yoon of IBM Korea
553 	** says that works on Token Ring (he says that 0 does *not*
554 	** work; perhaps that's considered an invalid LLC SAP value - I
555 	** assume the SAP value in a DLPI bind is an LLC SAP for network
556 	** types that use 802.2 LLC).
557 	*/
558 	if ((dlbindreq(p->fd, 1537, p->errbuf) < 0 &&
559 	     dlbindreq(p->fd, 2, p->errbuf) < 0) ||
560 	     dlbindack(p->fd, (char *)buf, p->errbuf, NULL) < 0)
561 		goto bad;
562 #elif defined(DL_HP_RAWDLS)
563 	/*
564 	** HP-UX 10.0x and 10.1x.
565 	*/
566 	if (dl_dohpuxbind(p->fd, p->errbuf) < 0)
567 		goto bad;
568 	if (p->send_fd >= 0) {
569 		/*
570 		** XXX - if this fails, just close send_fd and
571 		** set it to -1, so that you can't send but can
572 		** still receive?
573 		*/
574 		if (dl_dohpuxbind(p->send_fd, p->errbuf) < 0)
575 			goto bad;
576 	}
577 #else /* neither AIX nor HP-UX */
578 	/*
579 	** Not Sinix, and neither AIX nor HP-UX - Solaris, and any other
580 	** OS using DLPI.
581 	**/
582 	if (dlbindreq(p->fd, 0, p->errbuf) < 0 ||
583 	    dlbindack(p->fd, (char *)buf, p->errbuf, NULL) < 0)
584 		goto bad;
585 #endif /* AIX vs. HP-UX vs. other */
586 #endif /* !HP-UX 9 and !HP-UX 10.20 or later and !SINIX */
587 
588 #ifdef HAVE_SOLARIS
589 	if (isatm) {
590 		/*
591 		** Have to turn on some special ATM promiscuous mode
592 		** for SunATM.
593 		** Do *NOT* turn regular promiscuous mode on; it doesn't
594 		** help, and may break things.
595 		*/
596 		if (strioctl(p->fd, A_PROMISCON_REQ, 0, NULL) < 0) {
597 			snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
598 			    "A_PROMISCON_REQ: %s", pcap_strerror(errno));
599 			goto bad;
600 		}
601 	} else
602 #endif
603 	if (p->opt.promisc) {
604 		/*
605 		** Enable promiscuous (not necessary on send FD)
606 		*/
607 		if (dlpromisconreq(p->fd, DL_PROMISC_PHYS, p->errbuf) < 0 ||
608 		    dlokack(p->fd, "promisc_phys", (char *)buf, p->errbuf) < 0)
609 			goto bad;
610 
611 		/*
612 		** Try to enable multicast (you would have thought
613 		** promiscuous would be sufficient). (Skip if using
614 		** HP-UX or SINIX) (Not necessary on send FD)
615 		*/
616 #if !defined(__hpux) && !defined(sinix)
617 		if (dlpromisconreq(p->fd, DL_PROMISC_MULTI, p->errbuf) < 0 ||
618 		    dlokack(p->fd, "promisc_multi", (char *)buf, p->errbuf) < 0)
619 			status = PCAP_WARNING;
620 #endif
621 	}
622 	/*
623 	** Try to enable SAP promiscuity (when not in promiscuous mode
624 	** when using HP-UX, when not doing SunATM on Solaris, and never
625 	** under SINIX) (Not necessary on send FD)
626 	*/
627 #ifndef sinix
628 	if (
629 #ifdef __hpux
630 	    !p->opt.promisc &&
631 #endif
632 #ifdef HAVE_SOLARIS
633 	    !isatm &&
634 #endif
635 	    (dlpromisconreq(p->fd, DL_PROMISC_SAP, p->errbuf) < 0 ||
636 	    dlokack(p->fd, "promisc_sap", (char *)buf, p->errbuf) < 0)) {
637 		/* Not fatal if promisc since the DL_PROMISC_PHYS worked */
638 		if (p->opt.promisc)
639 			status = PCAP_WARNING;
640 		else
641 			goto bad;
642 	}
643 #endif /* sinix */
644 
645 	/*
646 	** HP-UX 9, and HP-UX 10.20 or later, must bind after setting
647 	** promiscuous options.
648 	*/
649 #if defined(HAVE_HPUX9) || defined(HAVE_HPUX10_20_OR_LATER)
650 	if (dl_dohpuxbind(p->fd, p->errbuf) < 0)
651 		goto bad;
652 	/*
653 	** We don't set promiscuous mode on the send FD, but we'll defer
654 	** binding it anyway, just to keep the HP-UX 9/10.20 or later
655 	** code together.
656 	*/
657 	if (p->send_fd >= 0) {
658 		/*
659 		** XXX - if this fails, just close send_fd and
660 		** set it to -1, so that you can't send but can
661 		** still receive?
662 		*/
663 		if (dl_dohpuxbind(p->send_fd, p->errbuf) < 0)
664 			goto bad;
665 	}
666 #endif
667 
668 	/*
669 	** Determine link type
670 	** XXX - get SAP length and address length as well, for use
671 	** when sending packets.
672 	*/
673 	if (dlinforeq(p->fd, p->errbuf) < 0 ||
674 	    dlinfoack(p->fd, (char *)buf, p->errbuf) < 0)
675 		goto bad;
676 
677 	infop = &((union DL_primitives *)buf)->info_ack;
678 	if (pcap_process_mactype(p, infop->dl_mac_type) != 0)
679 		goto bad;
680 
681 #ifdef	DLIOCRAW
682 	/*
683 	** This is a non standard SunOS hack to get the full raw link-layer
684 	** header.
685 	*/
686 	if (strioctl(p->fd, DLIOCRAW, 0, NULL) < 0) {
687 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "DLIOCRAW: %s",
688 		    pcap_strerror(errno));
689 		goto bad;
690 	}
691 #endif
692 
693 	ss = p->snapshot;
694 
695 	/*
696 	** There is a bug in bufmod(7). When dealing with messages of
697 	** less than snaplen size it strips data from the beginning not
698 	** the end.
699 	**
700 	** This bug is fixed in 5.3.2. Also, there is a patch available.
701 	** Ask for bugid 1149065.
702 	*/
703 #ifdef HAVE_SOLARIS
704 	release = get_release(&osmajor, &osminor, &osmicro);
705 	if (osmajor == 5 && (osminor <= 2 || (osminor == 3 && osmicro < 2)) &&
706 	    getenv("BUFMOD_FIXED") == NULL) {
707 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
708 		"WARNING: bufmod is broken in SunOS %s; ignoring snaplen.",
709 		    release);
710 		ss = 0;
711 		status = PCAP_WARNING;
712 	}
713 #endif
714 
715 #ifdef HAVE_SYS_BUFMOD_H
716 	/* Push and configure bufmod. */
717 	if (pcap_conf_bufmod(p, ss, p->md.timeout) != 0)
718 		goto bad;
719 #endif
720 
721 	/*
722 	** As the last operation flush the read side.
723 	*/
724 	if (ioctl(p->fd, I_FLUSH, FLUSHR) != 0) {
725 		snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "FLUSHR: %s",
726 		    pcap_strerror(errno));
727 		goto bad;
728 	}
729 
730 	/* Allocate data buffer. */
731 	if (pcap_alloc_databuf(p) != 0)
732 		goto bad;
733 
734 	/* Success - but perhaps with a warning */
735 	if (status < 0)
736 		status = 0;
737 
738 	/*
739 	 * "p->fd" is an FD for a STREAMS device, so "select()" and
740 	 * "poll()" should work on it.
741 	 */
742 	p->selectable_fd = p->fd;
743 
744 	p->read_op = pcap_read_dlpi;
745 	p->inject_op = pcap_inject_dlpi;
746 	p->setfilter_op = install_bpf_program;	/* no kernel filtering */
747 	p->setdirection_op = NULL;	/* Not implemented.*/
748 	p->set_datalink_op = NULL;	/* can't change data link type */
749 	p->getnonblock_op = pcap_getnonblock_fd;
750 	p->setnonblock_op = pcap_setnonblock_fd;
751 	p->stats_op = pcap_stats_dlpi;
752 	p->cleanup_op = pcap_cleanup_dlpi;
753 
754 	return (status);
755 bad:
756 	pcap_cleanup_dlpi(p);
757 	return (status);
758 }
759 
760 /*
761  * Split a device name into a device type name and a unit number;
762  * return the a pointer to the beginning of the unit number, which
763  * is the end of the device type name, and set "*unitp" to the unit
764  * number.
765  *
766  * Returns NULL on error, and fills "ebuf" with an error message.
767  */
768 static char *
769 split_dname(char *device, int *unitp, char *ebuf)
770 {
771 	char *cp;
772 	char *eos;
773 	long unit;
774 
775 	/*
776 	 * Look for a number at the end of the device name string.
777 	 */
778 	cp = device + strlen(device) - 1;
779 	if (*cp < '0' || *cp > '9') {
780 		snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s missing unit number",
781 		    device);
782 		return (NULL);
783 	}
784 
785 	/* Digits at end of string are unit number */
786 	while (cp-1 >= device && *(cp-1) >= '0' && *(cp-1) <= '9')
787 		cp--;
788 
789 	errno = 0;
790 	unit = strtol(cp, &eos, 10);
791 	if (*eos != '\0') {
792 		snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s bad unit number", device);
793 		return (NULL);
794 	}
795 	if (errno == ERANGE || unit > INT_MAX) {
796 		snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s unit number too large",
797 		    device);
798 		return (NULL);
799 	}
800 	if (unit < 0) {
801 		snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s unit number is negative",
802 		    device);
803 		return (NULL);
804 	}
805 	*unitp = (int)unit;
806 	return (cp);
807 }
808 
809 static int
810 dl_doattach(int fd, int ppa, char *ebuf)
811 {
812 	bpf_u_int32 buf[MAXDLBUF];
813 	int err;
814 
815 	if (dlattachreq(fd, ppa, ebuf) < 0)
816 		return (PCAP_ERROR);
817 	err = dlokack(fd, "attach", (char *)buf, ebuf);
818 	if (err < 0)
819 		return (err);
820 	return (0);
821 }
822 
823 #ifdef DL_HP_RAWDLS
824 static int
825 dl_dohpuxbind(int fd, char *ebuf)
826 {
827 	int hpsap;
828 	int uerror;
829 	bpf_u_int32 buf[MAXDLBUF];
830 
831 	/*
832 	 * XXX - we start at 22 because we used to use only 22, but
833 	 * that was just because that was the value used in some
834 	 * sample code from HP.  With what value *should* we start?
835 	 * Does it matter, given that we're enabling SAP promiscuity
836 	 * on the input FD?
837 	 */
838 	hpsap = 22;
839 	for (;;) {
840 		if (dlbindreq(fd, hpsap, ebuf) < 0)
841 			return (-1);
842 		if (dlbindack(fd, (char *)buf, ebuf, &uerror) >= 0)
843 			break;
844 		/*
845 		 * For any error other than a UNIX EBUSY, give up.
846 		 */
847 		if (uerror != EBUSY) {
848 			/*
849 			 * dlbindack() has already filled in ebuf for
850 			 * this error.
851 			 */
852 			return (-1);
853 		}
854 
855 		/*
856 		 * For EBUSY, try the next SAP value; that means that
857 		 * somebody else is using that SAP.  Clear ebuf so
858 		 * that application doesn't report the "Device busy"
859 		 * error as a warning.
860 		 */
861 		*ebuf = '\0';
862 		hpsap++;
863 		if (hpsap > 100) {
864 			strlcpy(ebuf,
865 			    "All SAPs from 22 through 100 are in use",
866 			    PCAP_ERRBUF_SIZE);
867 			return (-1);
868 		}
869 	}
870 	return (0);
871 }
872 #endif
873 
874 int
875 pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
876 {
877 #ifdef HAVE_SOLARIS
878 	int fd;
879 	union {
880 		u_int nunits;
881 		char pad[516];	/* XXX - must be at least 513; is 516
882 				   in "atmgetunits" */
883 	} buf;
884 	char baname[2+1+1];
885 	u_int i;
886 
887 	/*
888 	 * We may have to do special magic to get ATM devices.
889 	 */
890 	if ((fd = open("/dev/ba", O_RDWR)) < 0) {
891 		/*
892 		 * We couldn't open the "ba" device.
893 		 * For now, just give up; perhaps we should
894 		 * return an error if the problem is neither
895 		 * a "that device doesn't exist" error (ENOENT,
896 		 * ENXIO, etc.) or a "you're not allowed to do
897 		 * that" error (EPERM, EACCES).
898 		 */
899 		return (0);
900 	}
901 
902 	if (strioctl(fd, A_GET_UNITS, sizeof(buf), (char *)&buf) < 0) {
903 		snprintf(errbuf, PCAP_ERRBUF_SIZE, "A_GET_UNITS: %s",
904 		    pcap_strerror(errno));
905 		return (-1);
906 	}
907 	for (i = 0; i < buf.nunits; i++) {
908 		snprintf(baname, sizeof baname, "ba%u", i);
909 		if (pcap_add_if(alldevsp, baname, 0, NULL, errbuf) < 0)
910 			return (-1);
911 	}
912 #endif
913 
914 	return (0);
915 }
916 
917 static int
918 send_request(int fd, char *ptr, int len, char *what, char *ebuf)
919 {
920 	struct	strbuf	ctl;
921 	int	flags;
922 
923 	ctl.maxlen = 0;
924 	ctl.len = len;
925 	ctl.buf = ptr;
926 
927 	flags = 0;
928 	if (putmsg(fd, &ctl, (struct strbuf *) NULL, flags) < 0) {
929 		snprintf(ebuf, PCAP_ERRBUF_SIZE,
930 		    "send_request: putmsg \"%s\": %s",
931 		    what, pcap_strerror(errno));
932 		return (-1);
933 	}
934 	return (0);
935 }
936 
937 static int
938 recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf, int *uerror)
939 {
940 	union	DL_primitives	*dlp;
941 	struct	strbuf	ctl;
942 	int	flags;
943 
944 	/*
945 	 * Clear out "*uerror", so it's only set for DL_ERROR_ACK/DL_SYSERR,
946 	 * making that the only place where EBUSY is treated specially.
947 	 */
948 	if (uerror != NULL)
949 		*uerror = 0;
950 
951 	ctl.maxlen = MAXDLBUF;
952 	ctl.len = 0;
953 	ctl.buf = bufp;
954 
955 	flags = 0;
956 	if (getmsg(fd, &ctl, (struct strbuf*)NULL, &flags) < 0) {
957 		snprintf(ebuf, PCAP_ERRBUF_SIZE, "recv_ack: %s getmsg: %s",
958 		    what, pcap_strerror(errno));
959 		return (PCAP_ERROR);
960 	}
961 
962 	dlp = (union DL_primitives *) ctl.buf;
963 	switch (dlp->dl_primitive) {
964 
965 	case DL_INFO_ACK:
966 	case DL_BIND_ACK:
967 	case DL_OK_ACK:
968 #ifdef DL_HP_PPA_ACK
969 	case DL_HP_PPA_ACK:
970 #endif
971 		/* These are OK */
972 		break;
973 
974 	case DL_ERROR_ACK:
975 		switch (dlp->error_ack.dl_errno) {
976 
977 		case DL_SYSERR:
978 			if (uerror != NULL)
979 				*uerror = dlp->error_ack.dl_unix_errno;
980 			snprintf(ebuf, PCAP_ERRBUF_SIZE,
981 			    "recv_ack: %s: UNIX error - %s",
982 			    what, pcap_strerror(dlp->error_ack.dl_unix_errno));
983 			if (dlp->error_ack.dl_unix_errno == EACCES)
984 				return (PCAP_ERROR_PERM_DENIED);
985 			break;
986 
987 		default:
988 			snprintf(ebuf, PCAP_ERRBUF_SIZE, "recv_ack: %s: %s",
989 			    what, dlstrerror(dlp->error_ack.dl_errno));
990 			if (dlp->error_ack.dl_errno == DL_BADPPA)
991 				return (PCAP_ERROR_NO_SUCH_DEVICE);
992 			else if (dlp->error_ack.dl_errno == DL_ACCESS)
993 				return (PCAP_ERROR_PERM_DENIED);
994 			break;
995 		}
996 		return (PCAP_ERROR);
997 
998 	default:
999 		snprintf(ebuf, PCAP_ERRBUF_SIZE,
1000 		    "recv_ack: %s: Unexpected primitive ack %s",
1001 		    what, dlprim(dlp->dl_primitive));
1002 		return (PCAP_ERROR);
1003 	}
1004 
1005 	if (ctl.len < size) {
1006 		snprintf(ebuf, PCAP_ERRBUF_SIZE,
1007 		    "recv_ack: %s: Ack too small (%d < %d)",
1008 		    what, ctl.len, size);
1009 		return (PCAP_ERROR);
1010 	}
1011 	return (ctl.len);
1012 }
1013 
1014 static char *
1015 dlstrerror(bpf_u_int32 dl_errno)
1016 {
1017 	static char errstring[6+2+8+1];
1018 
1019 	switch (dl_errno) {
1020 
1021 	case DL_ACCESS:
1022 		return ("Improper permissions for request");
1023 
1024 	case DL_BADADDR:
1025 		return ("DLSAP addr in improper format or invalid");
1026 
1027 	case DL_BADCORR:
1028 		return ("Seq number not from outstand DL_CONN_IND");
1029 
1030 	case DL_BADDATA:
1031 		return ("User data exceeded provider limit");
1032 
1033 	case DL_BADPPA:
1034 #ifdef HAVE_DEV_DLPI
1035 		/*
1036 		 * With a single "/dev/dlpi" device used for all
1037 		 * DLPI providers, PPAs have nothing to do with
1038 		 * unit numbers.
1039 		 */
1040 		return ("Specified PPA was invalid");
1041 #else
1042 		/*
1043 		 * We have separate devices for separate devices;
1044 		 * the PPA is just the unit number.
1045 		 */
1046 		return ("Specified PPA (device unit) was invalid");
1047 #endif
1048 
1049 	case DL_BADPRIM:
1050 		return ("Primitive received not known by provider");
1051 
1052 	case DL_BADQOSPARAM:
1053 		return ("QOS parameters contained invalid values");
1054 
1055 	case DL_BADQOSTYPE:
1056 		return ("QOS structure type is unknown/unsupported");
1057 
1058 	case DL_BADSAP:
1059 		return ("Bad LSAP selector");
1060 
1061 	case DL_BADTOKEN:
1062 		return ("Token used not an active stream");
1063 
1064 	case DL_BOUND:
1065 		return ("Attempted second bind with dl_max_conind");
1066 
1067 	case DL_INITFAILED:
1068 		return ("Physical link initialization failed");
1069 
1070 	case DL_NOADDR:
1071 		return ("Provider couldn't allocate alternate address");
1072 
1073 	case DL_NOTINIT:
1074 		return ("Physical link not initialized");
1075 
1076 	case DL_OUTSTATE:
1077 		return ("Primitive issued in improper state");
1078 
1079 	case DL_SYSERR:
1080 		return ("UNIX system error occurred");
1081 
1082 	case DL_UNSUPPORTED:
1083 		return ("Requested service not supplied by provider");
1084 
1085 	case DL_UNDELIVERABLE:
1086 		return ("Previous data unit could not be delivered");
1087 
1088 	case DL_NOTSUPPORTED:
1089 		return ("Primitive is known but not supported");
1090 
1091 	case DL_TOOMANY:
1092 		return ("Limit exceeded");
1093 
1094 	case DL_NOTENAB:
1095 		return ("Promiscuous mode not enabled");
1096 
1097 	case DL_BUSY:
1098 		return ("Other streams for PPA in post-attached");
1099 
1100 	case DL_NOAUTO:
1101 		return ("Automatic handling XID&TEST not supported");
1102 
1103 	case DL_NOXIDAUTO:
1104 		return ("Automatic handling of XID not supported");
1105 
1106 	case DL_NOTESTAUTO:
1107 		return ("Automatic handling of TEST not supported");
1108 
1109 	case DL_XIDAUTO:
1110 		return ("Automatic handling of XID response");
1111 
1112 	case DL_TESTAUTO:
1113 		return ("Automatic handling of TEST response");
1114 
1115 	case DL_PENDING:
1116 		return ("Pending outstanding connect indications");
1117 
1118 	default:
1119 		sprintf(errstring, "Error %02x", dl_errno);
1120 		return (errstring);
1121 	}
1122 }
1123 
1124 static char *
1125 dlprim(bpf_u_int32 prim)
1126 {
1127 	static char primbuf[80];
1128 
1129 	switch (prim) {
1130 
1131 	case DL_INFO_REQ:
1132 		return ("DL_INFO_REQ");
1133 
1134 	case DL_INFO_ACK:
1135 		return ("DL_INFO_ACK");
1136 
1137 	case DL_ATTACH_REQ:
1138 		return ("DL_ATTACH_REQ");
1139 
1140 	case DL_DETACH_REQ:
1141 		return ("DL_DETACH_REQ");
1142 
1143 	case DL_BIND_REQ:
1144 		return ("DL_BIND_REQ");
1145 
1146 	case DL_BIND_ACK:
1147 		return ("DL_BIND_ACK");
1148 
1149 	case DL_UNBIND_REQ:
1150 		return ("DL_UNBIND_REQ");
1151 
1152 	case DL_OK_ACK:
1153 		return ("DL_OK_ACK");
1154 
1155 	case DL_ERROR_ACK:
1156 		return ("DL_ERROR_ACK");
1157 
1158 	case DL_SUBS_BIND_REQ:
1159 		return ("DL_SUBS_BIND_REQ");
1160 
1161 	case DL_SUBS_BIND_ACK:
1162 		return ("DL_SUBS_BIND_ACK");
1163 
1164 	case DL_UNITDATA_REQ:
1165 		return ("DL_UNITDATA_REQ");
1166 
1167 	case DL_UNITDATA_IND:
1168 		return ("DL_UNITDATA_IND");
1169 
1170 	case DL_UDERROR_IND:
1171 		return ("DL_UDERROR_IND");
1172 
1173 	case DL_UDQOS_REQ:
1174 		return ("DL_UDQOS_REQ");
1175 
1176 	case DL_CONNECT_REQ:
1177 		return ("DL_CONNECT_REQ");
1178 
1179 	case DL_CONNECT_IND:
1180 		return ("DL_CONNECT_IND");
1181 
1182 	case DL_CONNECT_RES:
1183 		return ("DL_CONNECT_RES");
1184 
1185 	case DL_CONNECT_CON:
1186 		return ("DL_CONNECT_CON");
1187 
1188 	case DL_TOKEN_REQ:
1189 		return ("DL_TOKEN_REQ");
1190 
1191 	case DL_TOKEN_ACK:
1192 		return ("DL_TOKEN_ACK");
1193 
1194 	case DL_DISCONNECT_REQ:
1195 		return ("DL_DISCONNECT_REQ");
1196 
1197 	case DL_DISCONNECT_IND:
1198 		return ("DL_DISCONNECT_IND");
1199 
1200 	case DL_RESET_REQ:
1201 		return ("DL_RESET_REQ");
1202 
1203 	case DL_RESET_IND:
1204 		return ("DL_RESET_IND");
1205 
1206 	case DL_RESET_RES:
1207 		return ("DL_RESET_RES");
1208 
1209 	case DL_RESET_CON:
1210 		return ("DL_RESET_CON");
1211 
1212 	default:
1213 		(void) sprintf(primbuf, "unknown primitive 0x%x", prim);
1214 		return (primbuf);
1215 	}
1216 }
1217 
1218 static int
1219 dlattachreq(int fd, bpf_u_int32 ppa, char *ebuf)
1220 {
1221 	dl_attach_req_t	req;
1222 
1223 	req.dl_primitive = DL_ATTACH_REQ;
1224 	req.dl_ppa = ppa;
1225 
1226 	return (send_request(fd, (char *)&req, sizeof(req), "attach", ebuf));
1227 }
1228 
1229 static int
1230 dlbindreq(int fd, bpf_u_int32 sap, char *ebuf)
1231 {
1232 
1233 	dl_bind_req_t	req;
1234 
1235 	memset((char *)&req, 0, sizeof(req));
1236 	req.dl_primitive = DL_BIND_REQ;
1237 	/* XXX - what if neither of these are defined? */
1238 #if defined(DL_HP_RAWDLS)
1239 	req.dl_max_conind = 1;			/* XXX magic number */
1240 	req.dl_service_mode = DL_HP_RAWDLS;
1241 #elif defined(DL_CLDLS)
1242 	req.dl_service_mode = DL_CLDLS;
1243 #endif
1244 	req.dl_sap = sap;
1245 
1246 	return (send_request(fd, (char *)&req, sizeof(req), "bind", ebuf));
1247 }
1248 
1249 static int
1250 dlbindack(int fd, char *bufp, char *ebuf, int *uerror)
1251 {
1252 
1253 	return (recv_ack(fd, DL_BIND_ACK_SIZE, "bind", bufp, ebuf, uerror));
1254 }
1255 
1256 static int
1257 dlpromisconreq(int fd, bpf_u_int32 level, char *ebuf)
1258 {
1259 	dl_promiscon_req_t req;
1260 
1261 	req.dl_primitive = DL_PROMISCON_REQ;
1262 	req.dl_level = level;
1263 
1264 	return (send_request(fd, (char *)&req, sizeof(req), "promiscon", ebuf));
1265 }
1266 
1267 static int
1268 dlokack(int fd, const char *what, char *bufp, char *ebuf)
1269 {
1270 
1271 	return (recv_ack(fd, DL_OK_ACK_SIZE, what, bufp, ebuf, NULL));
1272 }
1273 
1274 
1275 static int
1276 dlinforeq(int fd, char *ebuf)
1277 {
1278 	dl_info_req_t req;
1279 
1280 	req.dl_primitive = DL_INFO_REQ;
1281 
1282 	return (send_request(fd, (char *)&req, sizeof(req), "info", ebuf));
1283 }
1284 
1285 static int
1286 dlinfoack(int fd, char *bufp, char *ebuf)
1287 {
1288 
1289 	return (recv_ack(fd, DL_INFO_ACK_SIZE, "info", bufp, ebuf, NULL));
1290 }
1291 
1292 #ifdef HAVE_DLPI_PASSIVE
1293 /*
1294  * Enable DLPI passive mode. We do not care if this request fails, as this
1295  * indicates the underlying DLPI device does not support link aggregation.
1296  */
1297 static void
1298 dlpassive(int fd, char *ebuf)
1299 {
1300 	dl_passive_req_t req;
1301 	bpf_u_int32 buf[MAXDLBUF];
1302 
1303 	req.dl_primitive = DL_PASSIVE_REQ;
1304 
1305 	if (send_request(fd, (char *)&req, sizeof(req), "dlpassive", ebuf) == 0)
1306 	    (void) dlokack(fd, "dlpassive", (char *)buf, ebuf);
1307 }
1308 #endif
1309 
1310 #ifdef DL_HP_RAWDLS
1311 /*
1312  * There's an ack *if* there's an error.
1313  */
1314 static int
1315 dlrawdatareq(int fd, const u_char *datap, int datalen)
1316 {
1317 	struct strbuf ctl, data;
1318 	long buf[MAXDLBUF];	/* XXX - char? */
1319 	union DL_primitives *dlp;
1320 	int dlen;
1321 
1322 	dlp = (union DL_primitives*) buf;
1323 
1324 	dlp->dl_primitive = DL_HP_RAWDATA_REQ;
1325 	dlen = DL_HP_RAWDATA_REQ_SIZE;
1326 
1327 	/*
1328 	 * HP's documentation doesn't appear to show us supplying any
1329 	 * address pointed to by the control part of the message.
1330 	 * I think that's what raw mode means - you just send the raw
1331 	 * packet, you don't specify where to send it to, as that's
1332 	 * implied by the destination address.
1333 	 */
1334 	ctl.maxlen = 0;
1335 	ctl.len = dlen;
1336 	ctl.buf = (void *)buf;
1337 
1338 	data.maxlen = 0;
1339 	data.len = datalen;
1340 	data.buf = (void *)datap;
1341 
1342 	return (putmsg(fd, &ctl, &data, 0));
1343 }
1344 #endif /* DL_HP_RAWDLS */
1345 
1346 #if defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H)
1347 static char *
1348 get_release(bpf_u_int32 *majorp, bpf_u_int32 *minorp, bpf_u_int32 *microp)
1349 {
1350 	char *cp;
1351 	static char buf[32];
1352 
1353 	*majorp = 0;
1354 	*minorp = 0;
1355 	*microp = 0;
1356 	if (sysinfo(SI_RELEASE, buf, sizeof(buf)) < 0)
1357 		return ("?");
1358 	cp = buf;
1359 	if (!isdigit((unsigned char)*cp))
1360 		return (buf);
1361 	*majorp = strtol(cp, &cp, 10);
1362 	if (*cp++ != '.')
1363 		return (buf);
1364 	*minorp =  strtol(cp, &cp, 10);
1365 	if (*cp++ != '.')
1366 		return (buf);
1367 	*microp =  strtol(cp, &cp, 10);
1368 	return (buf);
1369 }
1370 #endif
1371 
1372 #ifdef DL_HP_PPA_REQ
1373 /*
1374  * Under HP-UX 10 and HP-UX 11, we can ask for the ppa
1375  */
1376 
1377 
1378 /*
1379  * Determine ppa number that specifies ifname.
1380  *
1381  * If the "dl_hp_ppa_info_t" doesn't have a "dl_module_id_1" member,
1382  * the code that's used here is the old code for HP-UX 10.x.
1383  *
1384  * However, HP-UX 10.20, at least, appears to have such a member
1385  * in its "dl_hp_ppa_info_t" structure, so the new code is used.
1386  * The new code didn't work on an old 10.20 system on which Rick
1387  * Jones of HP tried it, but with later patches installed, it
1388  * worked - it appears that the older system had those members but
1389  * didn't put anything in them, so, if the search by name fails, we
1390  * do the old search.
1391  *
1392  * Rick suggests that making sure your system is "up on the latest
1393  * lancommon/DLPI/driver patches" is probably a good idea; it'd fix
1394  * that problem, as well as allowing libpcap to see packets sent
1395  * from the system on which the libpcap application is being run.
1396  * (On 10.20, in addition to getting the latest patches, you need
1397  * to turn the kernel "lanc_outbound_promisc_flag" flag on with ADB;
1398  * a posting to "comp.sys.hp.hpux" at
1399  *
1400  *	http://www.deja.com/[ST_rn=ps]/getdoc.xp?AN=558092266
1401  *
1402  * says that, to see the machine's outgoing traffic, you'd need to
1403  * apply the right patches to your system, and also set that variable
1404  * with:
1405 
1406 echo 'lanc_outbound_promisc_flag/W1' | /usr/bin/adb -w /stand/vmunix /dev/kmem
1407 
1408  * which could be put in, for example, "/sbin/init.d/lan".
1409  *
1410  * Setting the variable is not necessary on HP-UX 11.x.
1411  */
1412 static int
1413 get_dlpi_ppa(register int fd, register const char *device, register int unit,
1414     register char *ebuf)
1415 {
1416 	register dl_hp_ppa_ack_t *ap;
1417 	register dl_hp_ppa_info_t *ipstart, *ip;
1418 	register int i;
1419 	char dname[100];
1420 	register u_long majdev;
1421 	struct stat statbuf;
1422 	dl_hp_ppa_req_t	req;
1423 	char buf[MAXDLBUF];
1424 	char *ppa_data_buf;
1425 	dl_hp_ppa_ack_t	*dlp;
1426 	struct strbuf ctl;
1427 	int flags;
1428 	int ppa;
1429 
1430 	memset((char *)&req, 0, sizeof(req));
1431 	req.dl_primitive = DL_HP_PPA_REQ;
1432 
1433 	memset((char *)buf, 0, sizeof(buf));
1434 	if (send_request(fd, (char *)&req, sizeof(req), "hpppa", ebuf) < 0)
1435 		return (PCAP_ERROR);
1436 
1437 	ctl.maxlen = DL_HP_PPA_ACK_SIZE;
1438 	ctl.len = 0;
1439 	ctl.buf = (char *)buf;
1440 
1441 	flags = 0;
1442 	/*
1443 	 * DLPI may return a big chunk of data for a DL_HP_PPA_REQ. The normal
1444 	 * recv_ack will fail because it set the maxlen to MAXDLBUF (8192)
1445 	 * which is NOT big enough for a DL_HP_PPA_REQ.
1446 	 *
1447 	 * This causes libpcap applications to fail on a system with HP-APA
1448 	 * installed.
1449 	 *
1450 	 * To figure out how big the returned data is, we first call getmsg
1451 	 * to get the small head and peek at the head to get the actual data
1452 	 * length, and  then issue another getmsg to get the actual PPA data.
1453 	 */
1454 	/* get the head first */
1455 	if (getmsg(fd, &ctl, (struct strbuf *)NULL, &flags) < 0) {
1456 		snprintf(ebuf, PCAP_ERRBUF_SIZE,
1457 		    "get_dlpi_ppa: hpppa getmsg: %s", pcap_strerror(errno));
1458 		return (PCAP_ERROR);
1459 	}
1460 
1461 	dlp = (dl_hp_ppa_ack_t *)ctl.buf;
1462 	if (dlp->dl_primitive != DL_HP_PPA_ACK) {
1463 		snprintf(ebuf, PCAP_ERRBUF_SIZE,
1464 		    "get_dlpi_ppa: hpppa unexpected primitive ack 0x%x",
1465 		    (bpf_u_int32)dlp->dl_primitive);
1466 		return (PCAP_ERROR);
1467 	}
1468 
1469 	if (ctl.len < DL_HP_PPA_ACK_SIZE) {
1470 		snprintf(ebuf, PCAP_ERRBUF_SIZE,
1471 		    "get_dlpi_ppa: hpppa ack too small (%d < %lu)",
1472 		     ctl.len, (unsigned long)DL_HP_PPA_ACK_SIZE);
1473 		return (PCAP_ERROR);
1474 	}
1475 
1476 	/* allocate buffer */
1477 	if ((ppa_data_buf = (char *)malloc(dlp->dl_length)) == NULL) {
1478 		snprintf(ebuf, PCAP_ERRBUF_SIZE,
1479 		    "get_dlpi_ppa: hpppa malloc: %s", pcap_strerror(errno));
1480 		return (PCAP_ERROR);
1481 	}
1482 	ctl.maxlen = dlp->dl_length;
1483 	ctl.len = 0;
1484 	ctl.buf = (char *)ppa_data_buf;
1485 	/* get the data */
1486 	if (getmsg(fd, &ctl, (struct strbuf *)NULL, &flags) < 0) {
1487 		snprintf(ebuf, PCAP_ERRBUF_SIZE,
1488 		    "get_dlpi_ppa: hpppa getmsg: %s", pcap_strerror(errno));
1489 		free(ppa_data_buf);
1490 		return (PCAP_ERROR);
1491 	}
1492 	if (ctl.len < dlp->dl_length) {
1493 		snprintf(ebuf, PCAP_ERRBUF_SIZE,
1494 		    "get_dlpi_ppa: hpppa ack too small (%d < %d)",
1495 		    ctl.len, dlp->dl_length);
1496 		free(ppa_data_buf);
1497 		return (PCAP_ERROR);
1498 	}
1499 
1500 	ap = (dl_hp_ppa_ack_t *)buf;
1501 	ipstart = (dl_hp_ppa_info_t *)ppa_data_buf;
1502 	ip = ipstart;
1503 
1504 #ifdef HAVE_HP_PPA_INFO_T_DL_MODULE_ID_1
1505 	/*
1506 	 * The "dl_hp_ppa_info_t" structure has a "dl_module_id_1"
1507 	 * member that should, in theory, contain the part of the
1508 	 * name for the device that comes before the unit number,
1509 	 * and should also have a "dl_module_id_2" member that may
1510 	 * contain an alternate name (e.g., I think Ethernet devices
1511 	 * have both "lan", for "lanN", and "snap", for "snapN", with
1512 	 * the former being for Ethernet packets and the latter being
1513 	 * for 802.3/802.2 packets).
1514 	 *
1515 	 * Search for the device that has the specified name and
1516 	 * instance number.
1517 	 */
1518 	for (i = 0; i < ap->dl_count; i++) {
1519 		if ((strcmp((const char *)ip->dl_module_id_1, device) == 0 ||
1520 		     strcmp((const char *)ip->dl_module_id_2, device) == 0) &&
1521 		    ip->dl_instance_num == unit)
1522 			break;
1523 
1524 		ip = (dl_hp_ppa_info_t *)((u_char *)ipstart + ip->dl_next_offset);
1525 	}
1526 #else
1527 	/*
1528 	 * We don't have that member, so the search is impossible; make it
1529 	 * look as if the search failed.
1530 	 */
1531 	i = ap->dl_count;
1532 #endif
1533 
1534 	if (i == ap->dl_count) {
1535 		/*
1536 		 * Well, we didn't, or can't, find the device by name.
1537 		 *
1538 		 * HP-UX 10.20, whilst it has "dl_module_id_1" and
1539 		 * "dl_module_id_2" fields in the "dl_hp_ppa_info_t",
1540 		 * doesn't seem to fill them in unless the system is
1541 		 * at a reasonably up-to-date patch level.
1542 		 *
1543 		 * Older HP-UX 10.x systems might not have those fields
1544 		 * at all.
1545 		 *
1546 		 * Therefore, we'll search for the entry with the major
1547 		 * device number of a device with the name "/dev/<dev><unit>",
1548 		 * if such a device exists, as the old code did.
1549 		 */
1550 		snprintf(dname, sizeof(dname), "/dev/%s%d", device, unit);
1551 		if (stat(dname, &statbuf) < 0) {
1552 			snprintf(ebuf, PCAP_ERRBUF_SIZE, "stat: %s: %s",
1553 			    dname, pcap_strerror(errno));
1554 			return (PCAP_ERROR);
1555 		}
1556 		majdev = major(statbuf.st_rdev);
1557 
1558 		ip = ipstart;
1559 
1560 		for (i = 0; i < ap->dl_count; i++) {
1561 			if (ip->dl_mjr_num == majdev &&
1562 			    ip->dl_instance_num == unit)
1563 				break;
1564 
1565 			ip = (dl_hp_ppa_info_t *)((u_char *)ipstart + ip->dl_next_offset);
1566 		}
1567 	}
1568 	if (i == ap->dl_count) {
1569 		snprintf(ebuf, PCAP_ERRBUF_SIZE,
1570 		    "can't find /dev/dlpi PPA for %s%d", device, unit);
1571 		return (PCAP_ERROR_NO_SUCH_DEVICE);
1572 	}
1573 	if (ip->dl_hdw_state == HDW_DEAD) {
1574 		snprintf(ebuf, PCAP_ERRBUF_SIZE,
1575 		    "%s%d: hardware state: DOWN\n", device, unit);
1576 		free(ppa_data_buf);
1577 		return (PCAP_ERROR);
1578 	}
1579 	ppa = ip->dl_ppa;
1580 	free(ppa_data_buf);
1581 	return (ppa);
1582 }
1583 #endif
1584 
1585 #ifdef HAVE_HPUX9
1586 /*
1587  * Under HP-UX 9, there is no good way to determine the ppa.
1588  * So punt and read it from /dev/kmem.
1589  */
1590 static struct nlist nl[] = {
1591 #define NL_IFNET 0
1592 	{ "ifnet" },
1593 	{ "" }
1594 };
1595 
1596 static char path_vmunix[] = "/hp-ux";
1597 
1598 /* Determine ppa number that specifies ifname */
1599 static int
1600 get_dlpi_ppa(register int fd, register const char *ifname, register int unit,
1601     register char *ebuf)
1602 {
1603 	register const char *cp;
1604 	register int kd;
1605 	void *addr;
1606 	struct ifnet ifnet;
1607 	char if_name[sizeof(ifnet.if_name) + 1];
1608 
1609 	cp = strrchr(ifname, '/');
1610 	if (cp != NULL)
1611 		ifname = cp + 1;
1612 	if (nlist(path_vmunix, &nl) < 0) {
1613 		snprintf(ebuf, PCAP_ERRBUF_SIZE, "nlist %s failed",
1614 		    path_vmunix);
1615 		return (-1);
1616 	}
1617 	if (nl[NL_IFNET].n_value == 0) {
1618 		snprintf(ebuf, PCAP_ERRBUF_SIZE,
1619 		    "could't find %s kernel symbol",
1620 		    nl[NL_IFNET].n_name);
1621 		return (-1);
1622 	}
1623 	kd = open("/dev/kmem", O_RDONLY);
1624 	if (kd < 0) {
1625 		snprintf(ebuf, PCAP_ERRBUF_SIZE, "kmem open: %s",
1626 		    pcap_strerror(errno));
1627 		return (-1);
1628 	}
1629 	if (dlpi_kread(kd, nl[NL_IFNET].n_value,
1630 	    &addr, sizeof(addr), ebuf) < 0) {
1631 		close(kd);
1632 		return (-1);
1633 	}
1634 	for (; addr != NULL; addr = ifnet.if_next) {
1635 		if (dlpi_kread(kd, (off_t)addr,
1636 		    &ifnet, sizeof(ifnet), ebuf) < 0 ||
1637 		    dlpi_kread(kd, (off_t)ifnet.if_name,
1638 		    if_name, sizeof(ifnet.if_name), ebuf) < 0) {
1639 			(void)close(kd);
1640 			return (-1);
1641 		}
1642 		if_name[sizeof(ifnet.if_name)] = '\0';
1643 		if (strcmp(if_name, ifname) == 0 && ifnet.if_unit == unit)
1644 			return (ifnet.if_index);
1645 	}
1646 
1647 	snprintf(ebuf, PCAP_ERRBUF_SIZE, "Can't find %s", ifname);
1648 	return (-1);
1649 }
1650 
1651 static int
1652 dlpi_kread(register int fd, register off_t addr,
1653     register void *buf, register u_int len, register char *ebuf)
1654 {
1655 	register int cc;
1656 
1657 	if (lseek(fd, addr, SEEK_SET) < 0) {
1658 		snprintf(ebuf, PCAP_ERRBUF_SIZE, "lseek: %s",
1659 		    pcap_strerror(errno));
1660 		return (-1);
1661 	}
1662 	cc = read(fd, buf, len);
1663 	if (cc < 0) {
1664 		snprintf(ebuf, PCAP_ERRBUF_SIZE, "read: %s",
1665 		    pcap_strerror(errno));
1666 		return (-1);
1667 	} else if (cc != len) {
1668 		snprintf(ebuf, PCAP_ERRBUF_SIZE, "short read (%d != %d)", cc,
1669 		    len);
1670 		return (-1);
1671 	}
1672 	return (cc);
1673 }
1674 #endif
1675 
1676 pcap_t *
1677 pcap_create(const char *device, char *ebuf)
1678 {
1679 	pcap_t *p;
1680 
1681 	p = pcap_create_common(device, ebuf);
1682 	if (p == NULL)
1683 		return (NULL);
1684 
1685 	p->send_fd = -1;	/* it hasn't been opened yet */
1686 
1687 	p->activate_op = pcap_activate_dlpi;
1688 	return (p);
1689 }
1690