components/net-snmp/patches/005.16736.patch
changeset 1679 51291a5fd692
parent 252 ee0fb1eabcbf
equal deleted inserted replaced
1678:68d1cdc71760 1679:51291a5fd692
       
     1 Index: net-snmp/agent/mibgroup/kernel_sunos5.h
       
     2 ===================================================================
       
     3 --- net-snmp/agent/mibgroup/kernel_sunos5.h	(revision 16735)
       
     4 +++ net-snmp/agent/mibgroup/kernel_sunos5.h	(revision 16736)
       
     5 @@ -193,6 +193,8 @@
       
     6      int             getKstatString(const char *statname, const char *varname,
       
     7                                     char *value, size_t value_len);
       
     8  
       
     9 +    int             solaris2_if_nametoindex(const char *, int);
       
    10 +
       
    11  #ifdef _STDC_COMPAT
       
    12  #ifdef __cplusplus
       
    13  }
       
    14 Index: net-snmp/agent/mibgroup/if-mib/data_access/interface_solaris2.c
       
    15 ===================================================================
       
    16 --- net-snmp/agent/mibgroup/if-mib/data_access/interface_solaris2.c	(revision 16735)
       
    17 +++ net-snmp/agent/mibgroup/if-mib/data_access/interface_solaris2.c	(revision 16736)
       
    18 @@ -14,6 +14,7 @@
       
    19  #include <sys/ioctl.h>
       
    20  #include <sys/sockio.h>
       
    21  #include <strings.h>
       
    22 +#include <string.h>
       
    23  
       
    24  static int _set_ip_flags_v4(netsnmp_interface_entry *, mib2_ifEntry_t *);
       
    25  static int _match_ifname_v4addr(void *ifname, void *ipaddr);
       
    26 @@ -43,25 +44,7 @@
       
    27  #if defined(HAVE_IF_NAMETOINDEX)
       
    28      return if_nametoindex(name);
       
    29  #else /* use GIFINDEX */
       
    30 -    int             sd;
       
    31 -    struct ifreq    ifr;
       
    32 -
       
    33 -    if (name == 0) {
       
    34 -        return (0);
       
    35 -    }
       
    36 -
       
    37 -    if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
       
    38 -        return (0);
       
    39 -    }
       
    40 -
       
    41 -    strncpy(ifr.ifr_name, name, IFNAMSIZ);
       
    42 -    if (ioctl(sd, SIOCGIFINDEX, (char *) &ifr) < 0) {
       
    43 -        close(sd);
       
    44 -        return (0);
       
    45 -    }
       
    46 -
       
    47 -    close(sd);
       
    48 -    return (ifr.ifr_index);
       
    49 +    return solaris2_if_nametoindex(name, strlen(name));
       
    50  #endif /* defined(HAVE_IF_NAMETOINDEX) */
       
    51  }
       
    52  
       
    53 Index: net-snmp/agent/mibgroup/mibII/interfaces.c
       
    54 ===================================================================
       
    55 --- net-snmp/agent/mibgroup/mibII/interfaces.c	(revision 16735)
       
    56 +++ net-snmp/agent/mibgroup/mibII/interfaces.c	(revision 16736)
       
    57 @@ -2245,71 +2245,7 @@
       
    58  int
       
    59  Interface_Index_By_Name(char *Name, int Len)
       
    60  {
       
    61 -    int             i, sd, lastlen = 0, interfaces = 0;
       
    62 -    struct ifconf   ifc;
       
    63 -    struct ifreq   *ifrp = NULL;
       
    64 -    char           *buf = NULL;
       
    65 -
       
    66 -    if (Name == 0) {
       
    67 -        return 0;
       
    68 -    }
       
    69 -    if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
       
    70 -        return 0;
       
    71 -    }
       
    72 -
       
    73 -    /*
       
    74 -     * Cope with lots of interfaces and brokenness of ioctl SIOCGIFCONF
       
    75 -     * on some platforms; see W. R. Stevens, ``Unix Network Programming
       
    76 -     * Volume I'', p.435.  
       
    77 -     */
       
    78 -
       
    79 -    for (i = 8;; i += 8) {
       
    80 -        buf = calloc(i, sizeof(struct ifreq));
       
    81 -        if (buf == NULL) {
       
    82 -            close(sd);
       
    83 -            return 0;
       
    84 -        }
       
    85 -        ifc.ifc_len = i * sizeof(struct ifreq);
       
    86 -        ifc.ifc_buf = (caddr_t) buf;
       
    87 -
       
    88 -        if (ioctl(sd, SIOCGIFCONF, (char *) &ifc) < 0) {
       
    89 -            if (errno != EINVAL || lastlen != 0) {
       
    90 -                /*
       
    91 -                 * Something has gone genuinely wrong.  
       
    92 -                 */
       
    93 -                free(buf);
       
    94 -                close(sd);
       
    95 -                return 0;
       
    96 -            }
       
    97 -            /*
       
    98 -             * Otherwise, it could just be that the buffer is too small.  
       
    99 -             */
       
   100 -        } else {
       
   101 -            if (ifc.ifc_len == lastlen) {
       
   102 -                /*
       
   103 -                 * The length is the same as the last time; we're done.  
       
   104 -                 */
       
   105 -                break;
       
   106 -            }
       
   107 -            lastlen = ifc.ifc_len;
       
   108 -        }
       
   109 -        free(buf);
       
   110 -    }
       
   111 -
       
   112 -    ifrp = ifc.ifc_req;
       
   113 -    interfaces = (ifc.ifc_len / sizeof(struct ifreq)) + 1;
       
   114 -
       
   115 -    for (i = 1; i < interfaces; i++, ifrp++) {
       
   116 -        if (strncmp(ifrp->ifr_name, Name, Len) == 0) {
       
   117 -            free(buf);
       
   118 -            close(sd);
       
   119 -            return i;
       
   120 -        }
       
   121 -    }
       
   122 -
       
   123 -    free(buf);
       
   124 -    close(sd);
       
   125 -    return 0;
       
   126 +    return (solaris2_if_nametoindex(Name, Len));
       
   127  }
       
   128  
       
   129  #endif                          /* solaris2 */
       
   130 Index: net-snmp/agent/mibgroup/kernel_sunos5.c
       
   131 ===================================================================
       
   132 --- net-snmp/agent/mibgroup/kernel_sunos5.c	(revision 16735)
       
   133 +++ net-snmp/agent/mibgroup/kernel_sunos5.c	(revision 16736)
       
   134 @@ -169,11 +169,14 @@
       
   135  getif(mib2_ifEntry_t *ifbuf, size_t size, req_e req_type, mib2_ifEntry_t *resp,
       
   136        size_t *length, int (*comp)(void *, void *), void *arg);
       
   137  static void 
       
   138 -set_if_info(mib2_ifEntry_t *ifp, unsigned index, char *name, uint64_t flags,int mtu);
       
   139 +set_if_info(mib2_ifEntry_t *ifp, unsigned index, char *name, uint64_t flags,
       
   140 +            int mtu);
       
   141  static int get_if_stats(mib2_ifEntry_t *ifp);
       
   142  
       
   143 -static int get_phys_address(mib2_ifEntry_t *ifp);
       
   144 -static int _dlpi_phys_address(int fd, char *paddr, int maxlen, int *paddrlen);
       
   145 +static int _dlpi_open(const char *devname);
       
   146 +static int _dlpi_get_phys_address(int fd, char *paddr, int maxlen,
       
   147 +                                  int *paddrlen);
       
   148 +static int _dlpi_get_iftype(int fd, unsigned int *iftype);
       
   149  static int _dlpi_attach(int fd, int ppa);
       
   150  static int _dlpi_parse_devname(char *devname, int *ppap);
       
   151  
       
   152 @@ -1047,7 +1050,7 @@
       
   153        mib2_ifEntry_t *resp,  size_t *length, int (*comp)(void *, void *),
       
   154        void *arg)
       
   155  {
       
   156 -    int             i, ret;
       
   157 +    int             fd, i, ret;
       
   158      int             ifsd, ifsd6 = -1;
       
   159      struct lifreq   lifreq, *lifrp;
       
   160      mib2_ifEntry_t *ifp;
       
   161 @@ -1109,6 +1112,15 @@
       
   162  
       
   163          memset(ifp, 0, sizeof(mib2_ifEntry_t));
       
   164  
       
   165 +        if ((fd = _dlpi_open(ifnp->if_name)) != -1) {
       
   166 +            /* Could open DLPI... now try to grab some info */
       
   167 +            (void) _dlpi_get_phys_address(fd, ifp->ifPhysAddress.o_bytes,
       
   168 +                                sizeof(ifp->ifPhysAddress.o_bytes),
       
   169 +                                &ifp->ifPhysAddress.o_length);
       
   170 +            (void) _dlpi_get_iftype(fd, &ifp->ifType);
       
   171 +            close(fd);
       
   172 +        }
       
   173 +
       
   174          set_if_info(ifp, ifnp->if_index, ifnp->if_name, if_flags, 
       
   175                      lifrp->lifr_metric);
       
   176  
       
   177 @@ -1117,9 +1129,6 @@
       
   178              continue;
       
   179          }
       
   180  
       
   181 -        /* try to obtain the physical address */
       
   182 -        (void) get_phys_address(ifp);
       
   183 -
       
   184          /*
       
   185           * Once we reach here we know that all went well, so move to
       
   186           * the next ifEntry. 
       
   187 @@ -1294,8 +1303,11 @@
       
   188  #endif /*defined(HAVE_IF_NAMEINDEX)&&defined(NETSNMP_INCLUDE_IFTABLE_REWRITES)*/
       
   189  
       
   190  static void
       
   191 -set_if_info(mib2_ifEntry_t *ifp, unsigned index, char *name, uint64_t flags, int mtu)
       
   192 +set_if_info(mib2_ifEntry_t *ifp, unsigned index, char *name, uint64_t flags,
       
   193 +            int mtu)
       
   194  { 
       
   195 +    boolean_t havespeed = B_FALSE;
       
   196 +
       
   197      /*
       
   198       * Set basic information 
       
   199       */
       
   200 @@ -1307,101 +1319,122 @@
       
   201      ifp->ifLastChange = 0;      /* Who knows ...  */
       
   202      ifp->flags = flags;
       
   203      ifp->ifMtu = mtu;
       
   204 +    ifp->ifSpeed = 0;
       
   205  
       
   206 -    /* make ifOperStatus depend on link status if available */
       
   207 -    if (ifp->ifAdminStatus == 1) {
       
   208 -        int i_tmp;
       
   209 -        /* only UPed interfaces get correct link status - if any */
       
   210 -        if (getKstatInt(NULL, name,"link_up",&i_tmp) == 0) {
       
   211 -            ifp->ifOperStatus = i_tmp ? 1 : 2;
       
   212 -        }
       
   213 -    }
       
   214 -
       
   215      /*
       
   216 -     * Set link Type and Speed
       
   217 +     * Get link speed
       
   218       */
       
   219 -    ifp->ifType = 1;
       
   220 -    ifp->ifSpeed = 0;
       
   221 -
       
   222 -    if ((getKstatInt(NULL, name, "ifspeed", &ifp->ifSpeed) == 0) &&
       
   223 -        (ifp->ifSpeed != 0)) {
       
   224 +    if ((getKstatInt(NULL, name, "ifspeed", &ifp->ifSpeed) == 0)) {
       
   225          /*
       
   226           * check for SunOS patch with half implemented ifSpeed 
       
   227           */
       
   228 -        if (ifp->ifSpeed < 10000) {
       
   229 +        if (ifp->ifSpeed > 0 && ifp->ifSpeed < 10000) {
       
   230              ifp->ifSpeed *= 1000000;
       
   231          }
       
   232 +	havespeed = B_TRUE;
       
   233      } else if (getKstatInt(NULL, name, "ifSpeed", &ifp->ifSpeed) == 0) {
       
   234          /*
       
   235           * this is good 
       
   236           */
       
   237 +	havespeed = B_TRUE;
       
   238      }
       
   239  
       
   240 -    switch (name[0]) {
       
   241 -    case 'a':          /* ath (802.11) */
       
   242 -        if (name[1] == 't' && name[2] == 'h')
       
   243 -            ifp->ifType = 71;
       
   244 -        break;
       
   245 -    case 'l':          /* le / lo / lane (ATM LAN Emulation) */
       
   246 -        if (name[1] == 'o') {
       
   247 -        if (!ifp->ifSpeed)
       
   248 -            ifp->ifSpeed = 127000000;
       
   249 -        ifp->ifType = 24;
       
   250 -        } else if (name[1] == 'e') {
       
   251 -        if (!ifp->ifSpeed)
       
   252 -            ifp->ifSpeed = 10000000;
       
   253 -        ifp->ifType = 6;
       
   254 -        } else if (name[1] == 'a') {
       
   255 -        if (!ifp->ifSpeed)
       
   256 -            ifp->ifSpeed = 155000000;
       
   257 -        ifp->ifType = 37;
       
   258 -        }
       
   259 -        break;
       
   260 +    /* make ifOperStatus depend on link status if available */
       
   261 +    if (ifp->ifAdminStatus == 1) {
       
   262 +        int i_tmp;
       
   263 +        /* only UPed interfaces get correct link status - if any */
       
   264 +        if (getKstatInt(NULL, name,"link_up",&i_tmp) == 0) {
       
   265 +            ifp->ifOperStatus = i_tmp ? 1 : 2;
       
   266 +#ifdef IFF_FAILED
       
   267 +        } else if (flags & IFF_FAILED) {
       
   268 +            /*
       
   269 +	     * If IPMP is used, and if the daemon marks the interface
       
   270 +	     * as 'failed', then we know for sure something is amiss.
       
   271 +             */
       
   272 +            ifp->ifOperStatus = 2;
       
   273 +#endif
       
   274 +	} else if (havespeed == B_TRUE && ifp->ifSpeed == 0) {
       
   275 +	    /* Heuristic */
       
   276 +	    ifp->ifOperStatus = 2;
       
   277 +	}
       
   278 +    }
       
   279  
       
   280 -    case 'g':          /* ge (gigabit ethernet card)  */
       
   281 -    case 'c':          /* ce (Cassini Gigabit-Ethernet (PCI) */
       
   282 -        if (!ifp->ifSpeed)
       
   283 -        ifp->ifSpeed = 1000000000;
       
   284 -        ifp->ifType = 6;
       
   285 -        break;
       
   286 -
       
   287 -    case 'h':          /* hme (SBus card) */
       
   288 -    case 'e':          /* eri (PCI card) */
       
   289 -    case 'b':          /* be */
       
   290 -    case 'd':          /* dmfe -- found on netra X1 */
       
   291 -        if (!ifp->ifSpeed)
       
   292 -        ifp->ifSpeed = 100000000;
       
   293 -        ifp->ifType = 6;
       
   294 -        break;
       
   295 -
       
   296 -    case 'f':          /* fa (Fore ATM) */
       
   297 -        if (!ifp->ifSpeed)
       
   298 -        ifp->ifSpeed = 155000000;
       
   299 -        ifp->ifType = 37;
       
   300 -        break;
       
   301 -
       
   302 -    case 'q':         /* qe (QuadEther)/qa (Fore ATM)/qfe (QuadFastEther) */
       
   303 -        if (name[1] == 'a') {
       
   304 -        if (!ifp->ifSpeed)
       
   305 -            ifp->ifSpeed = 155000000;
       
   306 -        ifp->ifType = 37;
       
   307 -        } else if (name[1] == 'e') {
       
   308 +    /*
       
   309 +     * Set link Type and Speed (if it could not be determined from kstat)
       
   310 +     */
       
   311 +    if (ifp->ifType == 24) {
       
   312 +        ifp->ifSpeed = 127000000;
       
   313 +    } else if (ifp->ifType == 1 || ifp->ifType == 0) {
       
   314 +        /*
       
   315 +	 * Could not get the type from DLPI, so lets fall back to the hardcoded
       
   316 +	 * values.
       
   317 +	 */
       
   318 +        switch (name[0]) {
       
   319 +        case 'a':          /* ath (802.11) */
       
   320 +            if (name[1] == 't' && name[2] == 'h')
       
   321 +                ifp->ifType = 71;
       
   322 +            break;
       
   323 +        case 'l':          /* le / lo / lane (ATM LAN Emulation) */
       
   324 +            if (name[1] == 'o') {
       
   325              if (!ifp->ifSpeed)
       
   326 +                ifp->ifSpeed = 127000000;
       
   327 +            ifp->ifType = 24;
       
   328 +            } else if (name[1] == 'e') {
       
   329 +            if (!ifp->ifSpeed)
       
   330                  ifp->ifSpeed = 10000000;
       
   331              ifp->ifType = 6;
       
   332 -        } else if (name[1] == 'f') {
       
   333 +            } else if (name[1] == 'a') {
       
   334              if (!ifp->ifSpeed)
       
   335 -                ifp->ifSpeed = 100000000;
       
   336 +                ifp->ifSpeed = 155000000;
       
   337 +            ifp->ifType = 37;
       
   338 +            }
       
   339 +            break;
       
   340 +    
       
   341 +        case 'g':          /* ge (gigabit ethernet card)  */
       
   342 +        case 'c':          /* ce (Cassini Gigabit-Ethernet (PCI) */
       
   343 +            if (!ifp->ifSpeed)
       
   344 +            ifp->ifSpeed = 1000000000;
       
   345              ifp->ifType = 6;
       
   346 +            break;
       
   347 +    
       
   348 +        case 'h':          /* hme (SBus card) */
       
   349 +        case 'e':          /* eri (PCI card) */
       
   350 +        case 'b':          /* be */
       
   351 +        case 'd':          /* dmfe -- found on netra X1 */
       
   352 +            if (!ifp->ifSpeed)
       
   353 +            ifp->ifSpeed = 100000000;
       
   354 +            ifp->ifType = 6;
       
   355 +            break;
       
   356 +    
       
   357 +        case 'f':          /* fa (Fore ATM) */
       
   358 +            if (!ifp->ifSpeed)
       
   359 +            ifp->ifSpeed = 155000000;
       
   360 +            ifp->ifType = 37;
       
   361 +            break;
       
   362 +    
       
   363 +        case 'q':         /* qe (QuadEther)/qa (Fore ATM)/qfe (QuadFastEther) */
       
   364 +            if (name[1] == 'a') {
       
   365 +            if (!ifp->ifSpeed)
       
   366 +                ifp->ifSpeed = 155000000;
       
   367 +            ifp->ifType = 37;
       
   368 +            } else if (name[1] == 'e') {
       
   369 +                if (!ifp->ifSpeed)
       
   370 +                    ifp->ifSpeed = 10000000;
       
   371 +                ifp->ifType = 6;
       
   372 +            } else if (name[1] == 'f') {
       
   373 +                if (!ifp->ifSpeed)
       
   374 +                    ifp->ifSpeed = 100000000;
       
   375 +                ifp->ifType = 6;
       
   376 +            }
       
   377 +            break;
       
   378 +    
       
   379 +        case 'i':          /* ibd (Infiniband)/ip.tun (IP tunnel) */
       
   380 +            if (name[1] == 'b')
       
   381 +                ifp->ifType = 199;
       
   382 +            else if (name[1] == 'p')
       
   383 +                ifp->ifType = 131;
       
   384 +            break;
       
   385          }
       
   386 -        break;
       
   387 -
       
   388 -    case 'i':          /* ibd (Infiniband)/ip.tun (IP tunnel) */
       
   389 -        if (name[1] == 'b')
       
   390 -            ifp->ifType = 199;
       
   391 -        else if (name[1] == 'p')
       
   392 -            ifp->ifType = 131;
       
   393 -        break;
       
   394      }
       
   395  }
       
   396  
       
   397 @@ -1491,68 +1524,69 @@
       
   398  }
       
   399  
       
   400  /*
       
   401 - * Obtain the physical address using DLPI. Pieces of this code is directly
       
   402 - * taken from libdlpi, which unfortunately is not yet commonly available. 
       
   403 + * Open a DLPI device.
       
   404 + *
       
   405 + * On success the file descriptor is returned.
       
   406 + * On error -1 is returned.
       
   407   */
       
   408 -
       
   409 -static int 
       
   410 -get_phys_address(mib2_ifEntry_t *ifp)
       
   411 +static int
       
   412 +_dlpi_open(const char *devname)
       
   413  {
       
   414 -    char                  *devstr;
       
   415 -    int                   fd;
       
   416 -    int                   ppa = -1;
       
   417 -    int                   rc = -1;
       
   418 +    char *devstr;
       
   419 +    int fd = -1;
       
   420 +    int ppa = -1;
       
   421  
       
   422 -    DEBUGMSGTL(("kernel_sunos5", "get_phys_address called\n"));
       
   423 +    DEBUGMSGTL(("kernel_sunos5", "_dlpi_open called\n"));
       
   424  
       
   425 -    if ((devstr = malloc(5 + ifp->ifDescr.o_length + 1)) == NULL)
       
   426 +    if (devname == NULL)
       
   427          return (-1);
       
   428 -    (void) sprintf(devstr, "/dev/%s", ifp->ifDescr.o_bytes);
       
   429 +
       
   430 +    if ((devstr = malloc(5 + strlen(devname) + 1)) == NULL)
       
   431 +        return (-1);
       
   432 +    (void) sprintf(devstr, "/dev/%s", devname);
       
   433      DEBUGMSGTL(("kernel_sunos5:dlpi", "devstr(%s)\n", devstr));
       
   434      /*
       
   435       * First try opening the device using style 1, if the device does not
       
   436       * exist we try style 2. Modules will not be pushed, so something like
       
   437       * ip tunnels will not work. 
       
   438       */
       
   439 -    if ((fd = open(devstr, O_RDWR | O_NONBLOCK)) != -1) {
       
   440 -        DEBUGMSGTL(("kernel_sunos5:dlpi", "style1 open(%s)\n", devstr));
       
   441 -        rc = _dlpi_phys_address(fd, ifp->ifPhysAddress.o_bytes,
       
   442 -                                sizeof(ifp->ifPhysAddress.o_bytes),
       
   443 -                                &ifp->ifPhysAddress.o_length);
       
   444 -    } else if (_dlpi_parse_devname(devstr, &ppa) == 0) {
       
   445 -        DEBUGMSGTL(("kernel_sunos5:dlpi", "style2 parse: %s, %d\n", 
       
   446 -                    devstr, ppa));
       
   447 -        /* try style 2 */
       
   448 -        if ((fd = open(devstr, O_RDWR | O_NONBLOCK)) != -1) {
       
   449 -             DEBUGMSGTL(("kernel_sunos5:dlpi", "style2 open(%s)\n", devstr));
       
   450 -             if (_dlpi_attach(fd, ppa) == 0) {
       
   451 -                 DEBUGMSGTL(("kernel_sunos5:dlpi", "attached\n"));
       
   452 -                 rc = _dlpi_phys_address(fd, ifp->ifPhysAddress.o_bytes,
       
   453 -                                         sizeof(ifp->ifPhysAddress.o_bytes),
       
   454 -                                         &ifp->ifPhysAddress.o_length);
       
   455 -             }
       
   456 -         } 
       
   457 -     }
       
   458 +   
       
   459 +    DEBUGMSGTL(("kernel_sunos5:dlpi", "style1 open(%s)\n", devstr));
       
   460 +    if ((fd = open(devstr, O_RDWR | O_NONBLOCK)) < 0) {
       
   461 +        DEBUGMSGTL(("kernel_sunos5:dlpi", "style1 open failed\n"));
       
   462 +        if (_dlpi_parse_devname(devstr, &ppa) == 0) {
       
   463 +            DEBUGMSGTL(("kernel_sunos5:dlpi", "style2 parse: %s, %d\n", 
       
   464 +                       devstr, ppa));
       
   465 +            /* try style 2 */
       
   466 +            DEBUGMSGTL(("kernel_sunos5:dlpi", "style2 open(%s)\n", devstr));
       
   467  
       
   468 -     free(devstr);
       
   469 -     if (fd != -1)
       
   470 -         close(fd);
       
   471 +            if ((fd = open(devstr, O_RDWR | O_NONBLOCK)) != -1) {
       
   472 +                if (_dlpi_attach(fd, ppa) == 0) {
       
   473 +                    DEBUGMSGTL(("kernel_sunos5:dlpi", "attached\n"));
       
   474 +                } else {
       
   475 +                    DEBUGMSGTL(("kernel_sunos5:dlpi", "attached failed\n"));
       
   476 +                    close(fd);
       
   477 +                    fd = -1;
       
   478 +                }
       
   479 +            } else {
       
   480 +                DEBUGMSGTL(("kernel_sunos5:dlpi", "style2 open failed\n"));
       
   481 +            }
       
   482 +        } 
       
   483 +    } else {
       
   484 +        DEBUGMSGTL(("kernel_sunos5:dlpi", "style1 open succeeded\n"));
       
   485 +    }
       
   486  
       
   487 -     if (rc == 0) {
       
   488 -         /* successful */        
       
   489 -         DEBUGMSGTL(("kernel_sunos5:dlpi", "got phys addr using DLPI\n"));
       
   490 -         return (0);
       
   491 -     } else {
       
   492 -         DEBUGMSGTL(("kernel_sunos5:dlpi", "unable to get phys address\n"));
       
   493 -         return (-1);
       
   494 -     }
       
   495 +    /* clean up */
       
   496 +    free(devstr);
       
   497 +
       
   498 +    return (fd);
       
   499  }
       
   500  
       
   501  /*
       
   502 - *
       
   503 + * Obtain the physical address of the interface using DLPI
       
   504   */
       
   505  static int
       
   506 -_dlpi_phys_address(int fd, char *addr, int maxlen, int *addrlen)
       
   507 +_dlpi_get_phys_address(int fd, char *addr, int maxlen, int *addrlen)
       
   508  {
       
   509      dl_phys_addr_req_t  paddr_req;
       
   510      union DL_primitives *dlp;
       
   511 @@ -1560,6 +1594,8 @@
       
   512      char                buf[MAX(DL_PHYS_ADDR_ACK_SIZE+64, DL_ERROR_ACK_SIZE)];
       
   513      int                 flag = 0;
       
   514  
       
   515 +    DEBUGMSGTL(("kernel_sunos5:dlpi", "_dlpi_get_phys_address\n"));
       
   516 +
       
   517      paddr_req.dl_primitive = DL_PHYS_ADDR_REQ;
       
   518      paddr_req.dl_addr_type = DL_CURR_PHYS_ADDR;
       
   519      ctlbuf.buf = (char *)&paddr_req;
       
   520 @@ -1570,7 +1606,7 @@
       
   521      ctlbuf.maxlen = sizeof(buf);
       
   522      ctlbuf.len = 0;
       
   523      ctlbuf.buf = buf;
       
   524 -    if (getmsg(fd, &ctlbuf, NULL, &flag) != 0)
       
   525 +    if (getmsg(fd, &ctlbuf, NULL, &flag) < 0)
       
   526          return (-1);
       
   527  
       
   528      if (ctlbuf.len < sizeof(uint32_t))
       
   529 @@ -1580,6 +1616,7 @@
       
   530      case DL_PHYS_ADDR_ACK: {
       
   531          dl_phys_addr_ack_t *phyp = (dl_phys_addr_ack_t *)buf;
       
   532  
       
   533 +        DEBUGMSGTL(("kernel_sunos5:dlpi", "got ACK\n"));
       
   534          if (ctlbuf.len < DL_PHYS_ADDR_ACK_SIZE || phyp->dl_addr_length > maxlen)
       
   535              return (-1); 
       
   536          (void) memcpy(addr, buf+phyp->dl_addr_offset, phyp->dl_addr_length);
       
   537 @@ -1589,16 +1626,137 @@
       
   538      case DL_ERROR_ACK: {
       
   539          dl_error_ack_t *errp = (dl_error_ack_t *)buf;
       
   540  
       
   541 +        DEBUGMSGTL(("kernel_sunos5:dlpi", "got ERROR ACK\n"));
       
   542          if (ctlbuf.len < DL_ERROR_ACK_SIZE)
       
   543              return (-1);
       
   544          return (errp->dl_errno);
       
   545      }
       
   546      default:
       
   547 +        DEBUGMSGTL(("kernel_sunos5:dlpi", "got type: %x\n", dlp->dl_primitive));
       
   548          return (-1);
       
   549      }
       
   550  }
       
   551  
       
   552 +/*
       
   553 + * Query the interface about it's type.
       
   554 + */
       
   555  static int
       
   556 +_dlpi_get_iftype(int fd, unsigned int *iftype)
       
   557 +{
       
   558 +    dl_info_req_t info_req;
       
   559 +    union DL_primitives *dlp;
       
   560 +    struct strbuf       ctlbuf;
       
   561 +    char                buf[MAX(DL_INFO_ACK_SIZE, DL_ERROR_ACK_SIZE)];
       
   562 +    int                 flag = 0;
       
   563 +
       
   564 +    DEBUGMSGTL(("kernel_sunos5:dlpi", "_dlpi_get_iftype\n"));
       
   565 +
       
   566 +    info_req.dl_primitive = DL_INFO_REQ;
       
   567 +    ctlbuf.buf = (char *)&info_req;
       
   568 +    ctlbuf.len = DL_INFO_REQ_SIZE;
       
   569 +    if (putmsg(fd, &ctlbuf, NULL, 0) < 0) {
       
   570 +        DEBUGMSGTL(("kernel_sunos5:dlpi", "putmsg failed: %d\nn", errno));
       
   571 +        return (-1);
       
   572 +    }
       
   573 +    
       
   574 +    ctlbuf.maxlen = sizeof(buf);
       
   575 +    ctlbuf.len = 0;
       
   576 +    ctlbuf.buf = buf;
       
   577 +    if (getmsg(fd, &ctlbuf, NULL, &flag) < 0) {
       
   578 +        DEBUGMSGTL(("kernel_sunos5:dlpi", "getmsg failed: %d\n", errno));
       
   579 +        return (-1);
       
   580 +    }
       
   581 +
       
   582 +    if (ctlbuf.len < sizeof(uint32_t))
       
   583 +        return (-1);
       
   584 +    dlp = (union DL_primitives *)buf;
       
   585 +    switch (dlp->dl_primitive) {
       
   586 +    case DL_INFO_ACK: {
       
   587 +        dl_info_ack_t *info = (dl_info_ack_t *)buf;
       
   588 +
       
   589 +        if (ctlbuf.len < DL_INFO_ACK_SIZE)
       
   590 +            return (-1); 
       
   591 +
       
   592 +        DEBUGMSGTL(("kernel_sunos5:dlpi", "dl_mac_type: %x\n",
       
   593 +	           info->dl_mac_type));
       
   594 +	switch (info->dl_mac_type) {
       
   595 +	case DL_CSMACD:
       
   596 +	case DL_ETHER:
       
   597 +	case DL_ETH_CSMA:
       
   598 +		*iftype = 6;
       
   599 +		break;
       
   600 +	case DL_TPB:	/* Token Passing Bus */
       
   601 +		*iftype = 8;
       
   602 +		break;
       
   603 +	case DL_TPR:	/* Token Passing Ring */
       
   604 +		*iftype = 9;
       
   605 +		break;
       
   606 +	case DL_HDLC:
       
   607 +		*iftype = 118;
       
   608 +		break;
       
   609 +	case DL_FDDI:
       
   610 +		*iftype = 15;
       
   611 +		break;
       
   612 +	case DL_FC:	/* Fibre channel */
       
   613 +		*iftype = 56;
       
   614 +		break;
       
   615 +	case DL_ATM:
       
   616 +		*iftype = 37;
       
   617 +		break;
       
   618 +	case DL_X25:
       
   619 +	case DL_ISDN:
       
   620 +		*iftype = 63;
       
   621 +		break;
       
   622 +	case DL_HIPPI:
       
   623 +		*iftype = 47;
       
   624 +		break;
       
   625 +#ifdef DL_IB
       
   626 +	case DL_IB:
       
   627 +		*iftype = 199;
       
   628 +		break;
       
   629 +#endif
       
   630 +	case DL_FRAME:	/* Frame Relay */
       
   631 +		*iftype = 32;
       
   632 +		break;
       
   633 +	case DL_LOOP:
       
   634 +		*iftype = 24;
       
   635 +		break;
       
   636 +#ifdef DL_WIFI
       
   637 +	case DL_WIFI:
       
   638 +		*iftype = 71;
       
   639 +		break;
       
   640 +#endif
       
   641 +#ifdef DL_IPV4	/* then IPv6 is also defined */
       
   642 +	case DL_IPV4:	/* IPv4 Tunnel */
       
   643 +	case DL_IPV6:	/* IPv6 Tunnel */
       
   644 +		*iftype = 131;
       
   645 +		break;
       
   646 +#endif
       
   647 +	default:
       
   648 +		*iftype = 1;	/* Other */
       
   649 +		break;
       
   650 +	}
       
   651 +	
       
   652 +        return (0);
       
   653 +    }
       
   654 +    case DL_ERROR_ACK: {
       
   655 +        dl_error_ack_t *errp = (dl_error_ack_t *)buf;
       
   656 +
       
   657 +        DEBUGMSGTL(("kernel_sunos5:dlpi",
       
   658 +                    "got DL_ERROR_ACK: dlpi %d, error %d\n", errp->dl_errno,
       
   659 +                    errp->dl_unix_errno));
       
   660 +
       
   661 +        if (ctlbuf.len < DL_ERROR_ACK_SIZE)
       
   662 +            return (-1);
       
   663 +        return (errp->dl_errno);
       
   664 +    }
       
   665 +    default:
       
   666 +        DEBUGMSGTL(("kernel_sunos5:dlpi", "got type %x\n", dlp->dl_primitive));
       
   667 +        return (-1);
       
   668 +    }
       
   669 +}
       
   670 +
       
   671 +static int
       
   672  _dlpi_attach(int fd, int ppa)
       
   673  {
       
   674      dl_attach_req_t     attach_req;
       
   675 @@ -1680,8 +1838,83 @@
       
   676      } else {
       
   677  	return 1;
       
   678      }
       
   679 -}	
       
   680 +}
       
   681  
       
   682 +/*
       
   683 + * Try to determine the index of a particular interface. If mfd-rewrites is
       
   684 + * specified, then this function would only be used when the system does not
       
   685 + * have if_nametoindex(3SOCKET).
       
   686 + */
       
   687 +int
       
   688 +solaris2_if_nametoindex(const char *Name, int Len)
       
   689 +{
       
   690 +    int             i, sd, lastlen = 0, interfaces = 0;
       
   691 +    struct ifconf   ifc;
       
   692 +    struct ifreq   *ifrp = NULL;
       
   693 +    char           *buf = NULL;
       
   694 +
       
   695 +    if (Name == 0) {
       
   696 +        return 0;
       
   697 +    }
       
   698 +    if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
       
   699 +        return 0;
       
   700 +    }
       
   701 +
       
   702 +    /*
       
   703 +     * Cope with lots of interfaces and brokenness of ioctl SIOCGIFCONF
       
   704 +     * on some platforms; see W. R. Stevens, ``Unix Network Programming
       
   705 +     * Volume I'', p.435.  
       
   706 +     */
       
   707 +
       
   708 +    for (i = 8;; i += 8) {
       
   709 +        buf = calloc(i, sizeof(struct ifreq));
       
   710 +        if (buf == NULL) {
       
   711 +            close(sd);
       
   712 +            return 0;
       
   713 +        }
       
   714 +        ifc.ifc_len = i * sizeof(struct ifreq);
       
   715 +        ifc.ifc_buf = (caddr_t) buf;
       
   716 +
       
   717 +        if (ioctl(sd, SIOCGIFCONF, (char *) &ifc) < 0) {
       
   718 +            if (errno != EINVAL || lastlen != 0) {
       
   719 +                /*
       
   720 +                 * Something has gone genuinely wrong.  
       
   721 +                 */
       
   722 +                free(buf);
       
   723 +                close(sd);
       
   724 +                return 0;
       
   725 +            }
       
   726 +            /*
       
   727 +             * Otherwise, it could just be that the buffer is too small.  
       
   728 +             */
       
   729 +        } else {
       
   730 +            if (ifc.ifc_len == lastlen) {
       
   731 +                /*
       
   732 +                 * The length is the same as the last time; we're done.  
       
   733 +                 */
       
   734 +                break;
       
   735 +            }
       
   736 +            lastlen = ifc.ifc_len;
       
   737 +        }
       
   738 +        free(buf);
       
   739 +    }
       
   740 +
       
   741 +    ifrp = ifc.ifc_req;
       
   742 +    interfaces = (ifc.ifc_len / sizeof(struct ifreq)) + 1;
       
   743 +
       
   744 +    for (i = 1; i < interfaces; i++, ifrp++) {
       
   745 +        if (strncmp(ifrp->ifr_name, Name, Len) == 0) {
       
   746 +            free(buf);
       
   747 +            close(sd);
       
   748 +            return i;
       
   749 +        }
       
   750 +    }
       
   751 +
       
   752 +    free(buf);
       
   753 +    close(sd);
       
   754 +    return 0;
       
   755 +}
       
   756 +
       
   757  #ifdef _STDC_COMPAT
       
   758  #ifdef __cplusplus
       
   759  }