aboutsummaryrefslogtreecommitdiffstats
path: root/pcap-dlpi.c
diff options
context:
space:
mode:
authorguy <guy>2002-07-11 09:06:30 +0000
committerguy <guy>2002-07-11 09:06:30 +0000
commit243b20ec553e192599e5280f17703454b4420fe0 (patch)
tree8b56a1369d487e0ca62902e7bc2bf7999dac2d1e /pcap-dlpi.c
parent0d020002007bc5fc8b3c058f78c8d9456ee5acfd (diff)
Add SunATM support, based on code from Yen Yen Lim at North Dakota State
University.
Diffstat (limited to 'pcap-dlpi.c')
-rw-r--r--pcap-dlpi.c103
1 files changed, 98 insertions, 5 deletions
diff --git a/pcap-dlpi.c b/pcap-dlpi.c
index d945ea4..854aa2b 100644
--- a/pcap-dlpi.c
+++ b/pcap-dlpi.c
@@ -23,7 +23,7 @@
*/
/*
- * Packet capture routine for dlpi under SunOS 5
+ * Packet capture routine for DLPI under SunOS 5, HP-UX 9/10/11, and AIX.
*
* Notes:
*
@@ -33,12 +33,12 @@
* length results in data being left of the front of the packet.
*
* - It might be desirable to use pfmod(7) to filter packets in the
- * kernel.
+ * kernel when possible.
*/
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/libpcap/pcap-dlpi.c,v 1.78 2002-06-11 17:04:46 itojun Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-dlpi.c,v 1.79 2002-07-11 09:06:37 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@@ -247,12 +247,31 @@ pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
return (n);
}
+#ifndef DL_IPATM
+#define DL_IPATM 0x12 /* ATM Classical IP interface */
+#endif
+
+#ifdef HAVE_SOLARIS
+/*
+ * For SunATM.
+ */
+#ifndef A_GET_UNITS
+#define A_GET_UNITS (('A'<<8)|118)
+#endif /* A_GET_UNITS */
+#ifndef A_PROMISCON_REQ
+#define A_PROMISCON_REQ (('A'<<8)|121)
+#endif /* A_PROMISCON_REQ */
+#endif /* HAVE_SOLARIS */
+
pcap_t *
pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
{
register char *cp;
register pcap_t *p;
int ppa;
+#ifdef HAVE_SOLARIS
+ int isatm = 0;
+#endif
register dl_info_ack_t *infop;
#ifdef HAVE_SYS_BUFMOD_H
bpf_u_int32 ss, flag;
@@ -376,6 +395,10 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
dlinfoack(p->fd, (char *)buf, ebuf) < 0)
goto bad;
infop = &((union DL_primitives *)buf)->info_ack;
+#ifdef HAVE_SOLARIS
+ if (infop->dl_mac_type == DL_IPATM)
+ isatm = 1;
+#endif
if (infop->dl_provider_style == DL_STYLE2 &&
(dlattachreq(p->fd, ppa, ebuf) < 0 ||
dlokack(p->fd, "attach", (char *)buf, ebuf) < 0))
@@ -411,6 +434,21 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
goto bad;
#endif
+#ifdef HAVE_SOLARIS
+ if (isatm) {
+ /*
+ ** Have to turn on some special ATM promiscuous mode
+ ** for SunATM.
+ ** Do *NOT* turn regular promiscuous mode on; it doesn't
+ ** help, and may break things.
+ */
+ if (strioctl(p->fd, A_PROMISCON_REQ, 0, NULL) < 0) {
+ snprintf(ebuf, PCAP_ERRBUF_SIZE, "A_PROMISCON_REQ: %s",
+ pcap_strerror(errno));
+ goto bad;
+ }
+ } else
+#endif
if (promisc) {
/*
** Enable promiscuous
@@ -433,13 +471,17 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
}
/*
** Try to enable sap (when not in promiscuous mode when using
- ** using HP-UX and never under SINIX)
+ ** using HP-UX, when not doing SunATM on Solaris, and never
+ ** under SINIX)
*/
#ifndef sinix
if (
#ifdef __hpux
!promisc &&
#endif
+#ifdef HAVE_SOLARIS
+ !isatm &&
+#endif
(dlpromisconreq(p->fd, DL_PROMISC_SAP, ebuf) < 0 ||
dlokack(p->fd, "promisc_sap", (char *)buf, ebuf) < 0)) {
/* Not fatal if promisc since the DL_PROMISC_PHYS worked */
@@ -487,6 +529,13 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
p->offset = 2;
break;
+#ifdef HAVE_SOLARIS
+ case DL_IPATM:
+ p->linktype = DLT_SUNATM;
+ p->offset = 0; /* works for LANE and LLC encapsulation */
+ break;
+#endif
+
default:
snprintf(ebuf, PCAP_ERRBUF_SIZE, "unknown mac type %lu",
(unsigned long)infop->dl_mac_type);
@@ -495,7 +544,8 @@ pcap_open_live(char *device, int snaplen, int promisc, int to_ms, char *ebuf)
#ifdef DLIOCRAW
/*
- ** This is a non standard SunOS hack to get the ethernet header.
+ ** This is a non standard SunOS hack to get the full raw link-layer
+ ** header.
*/
if (strioctl(p->fd, DLIOCRAW, 0, NULL) < 0) {
snprintf(ebuf, PCAP_ERRBUF_SIZE, "DLIOCRAW: %s",
@@ -631,6 +681,49 @@ split_dname(char *device, int *unitp, char *ebuf)
}
int
+pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
+{
+#ifdef HAVE_SOLARIS
+ int fd;
+ union {
+ u_int nunits;
+ char pad[516]; /* XXX - must be at least 513; is 516
+ in "atmgetunits" */
+ } buf;
+ char baname[2+1+1];
+ u_int i;
+
+ /*
+ * We may have to do special magic to get ATM devices.
+ */
+ if ((fd = open("/dev/ba", O_RDWR)) < 0) {
+ /*
+ * We couldn't open the "ba" device.
+ * For now, just give up; perhaps we should
+ * return an error if the problem is neither
+ * a "that device doesn't exist" error (ENOENT,
+ * ENXIO, etc.) or a "you're not allowed to do
+ * that" error (EPERM, EACCES).
+ */
+ return (0);
+ }
+
+ if (strioctl(fd, A_GET_UNITS, sizeof(buf), (char *)&buf) < 0) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, "A_GET_UNITS: %s",
+ pcap_strerror(errno));
+ return (-1);
+ }
+ for (i = 0; i < buf.nunits; i++) {
+ snprintf(baname, sizeof baname, "ba%u", i);
+ if (pcap_add_if(alldevsp, baname, 0, NULL, errbuf) < 0)
+ return (-1);
+ }
+#endif
+
+ return (0);
+}
+
+int
pcap_setfilter(pcap_t *p, struct bpf_program *fp)
{