Brown, Mark C (GSE GCSM) wrote:
I tested SAP values 0 to 100 and they all worked on 11.11 and 11.23. Here's a new patch that tries SAP values 22 to 100. I didn't want to change libpcap's default behavior which is why I start with 22.
OK, here's a modified version of the patch, which centralizes the bind loop in a dl_dohpuxbind() routine, continues the loop only if the bind attempt fails with EBUSY, cleans up a bit of the DL_HP_RAWDLS stuff (it does the "send FD" binding at the same time it does the other binding for HP-UX, and doesn't do it at all for HP-UX prior to 9.0 (I don't even have 9.0 documentation, so I don't even know whether it works in 9.0, and I'm not sure we support pre-9.0 at all - and I'm not sure there's anybody using it on any pre-10.20 release in any case), and fixes up some comments and white space.
Give it a try and make sure it still works. (I'll check whether it builds on Solaris, i.e. that my modifications don't break anything there.)
Index: pcap-dlpi.c
===================================================================
RCS file: /tcpdump/master/libpcap/pcap-dlpi.c,v
retrieving revision 1.110
diff -c -r1.110 pcap-dlpi.c
*** pcap-dlpi.c 8 Apr 2005 03:08:00 -0000 1.110
--- pcap-dlpi.c 13 Apr 2005 08:42:50 -0000
***************
*** 20,27 ****
*
* This code contributed by Atanu Ghosh ([EMAIL PROTECTED]),
* University College London, and subsequently modified by
! * Guy Harris ([EMAIL PROTECTED]) and Mark Pizzolato
! * <[EMAIL PROTECTED]>.
*/
/*
--- 20,28 ----
*
* This code contributed by Atanu Ghosh ([EMAIL PROTECTED]),
* University College London, and subsequently modified by
! * Guy Harris ([EMAIL PROTECTED]), Mark Pizzolato
! * <[EMAIL PROTECTED]>,
! * and Mark C. Brown ([EMAIL PROTECTED]).
*/
/*
***************
*** 162,170 ****
/* Forwards */
static char *split_dname(char *, int *, char *);
static int dl_doattach(int, int, char *);
static int dlattachreq(int, bpf_u_int32, char *);
static int dlbindreq(int, bpf_u_int32, char *);
! static int dlbindack(int, char *, char *);
static int dlpromisconreq(int, bpf_u_int32, char *);
static int dlokack(int, const char *, char *, char *);
static int dlinforeq(int, char *);
--- 163,174 ----
/* Forwards */
static char *split_dname(char *, int *, char *);
static int dl_doattach(int, int, char *);
+ #if defined(HAVE_HPUX9) || defined(HAVE_HPUX10_20_OR_LATER)
+ static int dl_dohpuxbind(int, char *);
+ #endif
static int dlattachreq(int, bpf_u_int32, char *);
static int dlbindreq(int, bpf_u_int32, char *);
! static int dlbindack(int, char *, char *, int *);
static int dlpromisconreq(int, bpf_u_int32, char *);
static int dlokack(int, const char *, char *, char *);
static int dlinforeq(int, char *);
***************
*** 172,178 ****
#ifdef DL_HP_RAWDLS
static int dlrawdatareq(int, const u_char *, int);
#endif
! static int recv_ack(int, int, const char *, char *, char *);
static char *dlstrerror(bpf_u_int32);
static char *dlprim(bpf_u_int32);
#if defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H)
--- 176,182 ----
#ifdef DL_HP_RAWDLS
static int dlrawdatareq(int, const u_char *, int);
#endif
! static int recv_ack(int, int, const char *, char *, char *, int *);
static char *dlstrerror(bpf_u_int32);
static char *dlprim(bpf_u_int32);
#if defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H)
***************
*** 514,522 ****
#ifdef DL_HP_RAWDLS
/*
* XXX - HP-UX 10.20 and 11.xx don't appear to support sending and
! * receiving packets on the same descriptor - you have to bind the
! * descriptor on which you receive to a SAP of 22 and bind the
! * descriptor on which you send to a SAP of 24.
*
* If the open fails, we just leave -1 in "p->send_fd" and reject
* attempts to send packets, just as if, in pcap-bpf.c, we fail
--- 518,525 ----
#ifdef DL_HP_RAWDLS
/*
* XXX - HP-UX 10.20 and 11.xx don't appear to support sending and
! * receiving packets on the same descriptor - you need separate
! * descriptors for sending and receiving, bound to different SAPs.
*
* If the open fails, we just leave -1 in "p->send_fd" and reject
* attempts to send packets, just as if, in pcap-bpf.c, we fail
***************
*** 649,689 ****
*/
if ((dlbindreq(p->fd, 1537, ebuf) < 0 &&
dlbindreq(p->fd, 2, ebuf) < 0) ||
! dlbindack(p->fd, (char *)buf, ebuf) < 0)
! goto bad;
! #elif defined(DL_HP_RAWDLS)
! /*
! ** This is the descriptor on which we receive packets; we
! ** bind it to 22, as that's INSAP, as per the HP-UX DLPI
! ** Programmer's Guide.
! **
! ** XXX - is the SAP relevant? Apparently, if some application
! ** is already bound to that SAP, this fails with a DL_ERROR_ACK
! ** message of type DL_SYSERR with an errno of EBUSY, and
! ** the primitives we use already imply raw mode. Should we,
! ** instead, just keep trying SAPs from some set of SAPs until
! ** we don't fail with EBUSY?
! */
! if (dlbindreq(p->fd, 22, ebuf) < 0 ||
! dlbindack(p->fd, (char *)buf, ebuf) < 0)
! goto bad;
!
! if (p->send_fd >= 0) {
! /*
! ** This is the descriptor on which we send packets; we
! ** bind it to 24, as that's OUTSAP, as per the HP-UX
! ** DLPI Programmer's Guide.
! */
! if (dlbindreq(p->send_fd, 24, ebuf) < 0 ||
! dlbindack(p->send_fd, (char *)buf, ebuf) < 0)
! goto bad;
! }
! #else /* neither AIX nor HP-UX */
if (dlbindreq(p->fd, 0, ebuf) < 0 ||
! dlbindack(p->fd, (char *)buf, ebuf) < 0)
goto bad;
! #endif /* SAP to bind to */
! #endif /* HP-UX 9 or 10.20 or SINIX */
#ifdef HAVE_SOLARIS
if (isatm) {
--- 652,663 ----
*/
if ((dlbindreq(p->fd, 1537, ebuf) < 0 &&
dlbindreq(p->fd, 2, ebuf) < 0) ||
! #else
if (dlbindreq(p->fd, 0, ebuf) < 0 ||
! #endif
! dlbindack(p->fd, (char *)buf, ebuf, NULL) < 0)
goto bad;
! #endif
#ifdef HAVE_SOLARIS
if (isatm) {
***************
*** 721,728 ****
#endif
}
/*
! ** Try to enable sap (when not in promiscuous mode when using
! ** using HP-UX, when not doing SunATM on Solaris, and never
** under SINIX) (Not necessary on send FD)
*/
#ifndef sinix
--- 695,702 ----
#endif
}
/*
! ** Try to enable SAP promiscuity (when not in promiscuous mode
! ** when using HP-UX, when not doing SunATM on Solaris, and never
** under SINIX) (Not necessary on send FD)
*/
#ifndef sinix
***************
*** 742,758 ****
else
goto bad;
}
! #endif
/*
** HP-UX 9, and HP-UX 10.20 or later, must bind after setting
! ** promiscuous options)
*/
#if defined(HAVE_HPUX9) || defined(HAVE_HPUX10_20_OR_LATER)
! if (dlbindreq(p->fd, 0, ebuf) < 0 ||
! dlbindack(p->fd, (char *)buf, ebuf) < 0)
goto bad;
! #endif
/*
** Determine link type
--- 716,742 ----
else
goto bad;
}
! #endif /* sinix */
/*
** HP-UX 9, and HP-UX 10.20 or later, must bind after setting
! ** promiscuous options.
*/
#if defined(HAVE_HPUX9) || defined(HAVE_HPUX10_20_OR_LATER)
! if (dl_dohpuxbind(p->fd, ebuf) < 0)
goto bad;
! #ifdef DL_HP_RAWDLS
! /*
! ** We don't set promiscuous mode on the send FD, but we'll defer
! ** binding it anyway, just to keep the HP-UX 9/10.20 or later
! ** code together.
! */
! if (p->send_fd >= 0) {
! if (dl_dohpuxbind(p->send_fd, ebuf) < 0)
! goto bad;
! }
! #endif /* DL_HP_RAWDLS */
! #endif /* HP-UX 9 or 10.20 or later, or SINIX */
/*
** Determine link type
***************
*** 1001,1006 ****
--- 985,1021 ----
return (0);
}
+ #if defined(HAVE_HPUX9) || defined(HAVE_HPUX10_20_OR_LATER)
+ static int
+ dl_dohpuxbind(int fd, char *ebuf)
+ {
+ int hpsap;
+ int uerror;
+ bpf_u_int32 buf[MAXDLBUF];
+
+ hpsap = 22;
+ for (;;) {
+ if (dlbindreq(fd, hpsap, ebuf) < 0)
+ return (-1);
+ if (dlbindack(fd, (char *)buf, ebuf, &uerror) >= 0)
+ break;
+ /*
+ * For any error other than EBUSY, give up.
+ */
+ if (uerror != EBUSY)
+ return (-1);
+
+ /*
+ * For EBUSY, try the next SAP value; that means that
+ * somebody else is using that SAP.
+ */
+ hpsap++;
+ if (hpsap > 100)
+ return (-1);
+ }
+ }
+ #endif /* HP-UX 9 or HP-UX 10.20 or later */
+
int
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
{
***************
*** 1065,1071 ****
}
static int
! recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf)
{
union DL_primitives *dlp;
struct strbuf ctl;
--- 1080,1086 ----
}
static int
! recv_ack(int fd, int size, const char *what, char *bufp, char *ebuf, int
*uerr)
{
union DL_primitives *dlp;
struct strbuf ctl;
***************
*** 1098,1109 ****
--- 1113,1128 ----
switch (dlp->error_ack.dl_errno) {
case DL_SYSERR:
+ if (uerror != NULL)
+ *uerror = dlp->error_ack.dl_unix_errno;
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"recv_ack: %s: UNIX error - %s",
what, pcap_strerror(dlp->error_ack.dl_unix_errno));
break;
default:
+ if (uerror != NULL)
+ *uerror = 0;
snprintf(ebuf, PCAP_ERRBUF_SIZE, "recv_ack: %s: %s",
what, dlstrerror(dlp->error_ack.dl_errno));
break;
***************
*** 1111,1116 ****
--- 1130,1137 ----
return (-1);
default:
+ if (uerror != NULL)
+ *uerror = 0;
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"recv_ack: %s: Unexpected primitive ack %s",
what, dlprim(dlp->dl_primitive));
***************
*** 1118,1123 ****
--- 1139,1146 ----
}
if (ctl.len < size) {
+ if (uerror != NULL)
+ *uerror = 0;
snprintf(ebuf, PCAP_ERRBUF_SIZE,
"recv_ack: %s: Ack too small (%d < %d)",
what, ctl.len, size);
***************
*** 1351,1358 ****
req.dl_primitive = DL_BIND_REQ;
#ifdef DL_HP_RAWDLS
req.dl_max_conind = 1; /* XXX magic number */
! /* 22 is INSAP as per the HP-UX DLPI Programmer's Guide */
! req.dl_sap = 22;
req.dl_service_mode = DL_HP_RAWDLS;
#else
req.dl_sap = sap;
--- 1374,1380 ----
req.dl_primitive = DL_BIND_REQ;
#ifdef DL_HP_RAWDLS
req.dl_max_conind = 1; /* XXX magic number */
! req.dl_sap = sap;
req.dl_service_mode = DL_HP_RAWDLS;
#else
req.dl_sap = sap;
***************
*** 1365,1374 ****
}
static int
! dlbindack(int fd, char *bufp, char *ebuf)
{
! return (recv_ack(fd, DL_BIND_ACK_SIZE, "bind", bufp, ebuf));
}
static int
--- 1387,1396 ----
}
static int
! dlbindack(int fd, char *bufp, char *ebuf, int *uerror)
{
! return (recv_ack(fd, DL_BIND_ACK_SIZE, "bind", bufp, ebuf, uerror));
}
static int
***************
*** 1386,1392 ****
dlokack(int fd, const char *what, char *bufp, char *ebuf)
{
! return (recv_ack(fd, DL_OK_ACK_SIZE, what, bufp, ebuf));
}
--- 1408,1414 ----
dlokack(int fd, const char *what, char *bufp, char *ebuf)
{
! return (recv_ack(fd, DL_OK_ACK_SIZE, what, bufp, ebuf, NULL));
}
***************
*** 1404,1410 ****
dlinfoack(int fd, char *bufp, char *ebuf)
{
! return (recv_ack(fd, DL_INFO_ACK_SIZE, "info", bufp, ebuf));
}
#ifdef DL_HP_RAWDLS
--- 1426,1432 ----
dlinfoack(int fd, char *bufp, char *ebuf)
{
! return (recv_ack(fd, DL_INFO_ACK_SIZE, "info", bufp, ebuf, NULL));
}
#ifdef DL_HP_RAWDLS
***************
*** 1685,1704 ****
ip = (dl_hp_ppa_info_t *)((u_char *)ipstart +
ip->dl_next_offset);
}
}
! if (i == ap->dl_count) {
! snprintf(ebuf, PCAP_ERRBUF_SIZE,
"can't find /dev/dlpi PPA for %s%d", device, unit);
return (-1);
! }
! if (ip->dl_hdw_state == HDW_DEAD) {
! snprintf(ebuf, PCAP_ERRBUF_SIZE,
"%s%d: hardware state: DOWN\n", device, unit);
free(ppa_data_buf);
return (-1);
! }
! ppa = ip->dl_ppa;
! free(ppa_data_buf);
! return (ppa);
}
#endif
--- 1707,1726 ----
ip = (dl_hp_ppa_info_t *)((u_char *)ipstart +
ip->dl_next_offset);
}
}
! if (i == ap->dl_count) {
! snprintf(ebuf, PCAP_ERRBUF_SIZE,
"can't find /dev/dlpi PPA for %s%d", device, unit);
return (-1);
! }
! if (ip->dl_hdw_state == HDW_DEAD) {
! snprintf(ebuf, PCAP_ERRBUF_SIZE,
"%s%d: hardware state: DOWN\n", device, unit);
free(ppa_data_buf);
return (-1);
! }
! ppa = ip->dl_ppa;
! free(ppa_data_buf);
! return (ppa);
}
#endif
- This is the tcpdump-workers list. Visit https://lists.sandelman.ca/ to unsubscribe.
