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.

Reply via email to