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.