/** * interface entry ifIndex ioctl wrapper * * @param fd : socket fd to use w/ioctl, or -1 to open/close one * @param name : ifentry to update * * @retval 0 : not found * @retval !0 : ifIndex */ oid netsnmp_access_interface_ioctl_ifindex_get(int fd, const char *name) { #ifndef SIOCGIFINDEX return 0; #else struct ifreq ifrq; int rc = 0; DEBUGMSGTL(("access:interface:ioctl", "ifindex_get\n")); rc = _ioctl_get(fd, SIOCGIFINDEX, &ifrq, name); if (rc < 0) { DEBUGMSGTL(("access:interface:ioctl", "ifindex_get error on inerface '%s'\n", name)); return 0; } #if defined(__FreeBSD__) /* ? Should use HAVE_STRUCT_IFREQ_IFR_INDEX */ return ifrq.ifr_index; #else return ifrq.ifr_ifindex; #endif #endif /* SIOCGIFINDEX */ }
/** * interface entry flags ioctl wrapper * * @param fd : socket fd to use w/ioctl, or -1 to open/close one * @param ifentry : ifentry to update * * @retval 0 : success * @retval -1 : invalid parameters * @retval -2 : couldn't create socket * @retval -3 : ioctl call failed */ int netsnmp_access_interface_ioctl_flags_get(int fd, netsnmp_interface_entry *ifentry) { struct ifreq ifrq; int rc = 0; DEBUGMSGTL(("access:interface:ioctl", "flags_get\n")); rc = _ioctl_get(fd, SIOCGIFFLAGS, &ifrq, ifentry->name); if (rc < 0) { ifentry->ns_flags &= ~NETSNMP_INTERFACE_FLAGS_HAS_IF_FLAGS; return rc; /* msg already logged */ } else { ifentry->ns_flags |= NETSNMP_INTERFACE_FLAGS_HAS_IF_FLAGS; ifentry->os_flags = ifrq.ifr_flags; /* * ifOperStatus description: * If ifAdminStatus is down(2) then ifOperStatus should be down(2). */ if(ifentry->os_flags & IFF_UP) { ifentry->admin_status = IFADMINSTATUS_UP; if(ifentry->os_flags & IFF_RUNNING) ifentry->oper_status = IFOPERSTATUS_UP; else ifentry->oper_status = IFOPERSTATUS_DOWN; } else { ifentry->admin_status = IFADMINSTATUS_DOWN; ifentry->oper_status = IFOPERSTATUS_DOWN; } /* * ifConnectorPresent description: * This object has the value 'true(1)' if the interface sublayer has a * physical connector and the value 'false(2)' otherwise." * So, at very least, false(2) should be returned for loopback devices. */ if(ifentry->os_flags & IFF_LOOPBACK) { ifentry->connector_present = 0; } else { ifentry->connector_present = 1; } } return rc; }
/** * interface entry ifIndex ioctl wrapper * * @param fd : socket fd to use w/ioctl, or -1 to open/close one * @param ifentry : ifentry to update * * @retval 0 : not found * @retval !0 : ifIndex */ oid netsnmp_access_interface_ioctl_ifindex_get(int fd, const char *name) { #ifndef SIOCGIFINDEX return 0; #else struct ifreq ifrq; int rc = 0; DEBUGMSGTL(("access:interface:ioctl", "mtu_get\n")); rc = _ioctl_get(fd, SIOCGIFINDEX, &ifrq, name); if (rc < 0) return 0; return ifrq.ifr_ifindex; #endif /* SIOCGIFINDEX */ }
/** * interface entry mtu ioctl wrapper * * @param fd : socket fd to use w/ioctl, or -1 to open/close one * @param ifentry : ifentry to update * * @retval 0 : success * @retval -1 : invalid parameters * @retval -2 : couldn't create socket * @retval -3 : ioctl call failed */ int netsnmp_access_interface_ioctl_mtu_get(int fd, netsnmp_interface_entry *ifentry) { struct ifreq ifrq; int rc = 0; DEBUGMSGTL(("access:interface:ioctl", "mtu_get\n")); rc = _ioctl_get(fd, SIOCGIFMTU, &ifrq, ifentry->name); if (rc < 0) { ifentry->mtu = 0; return rc; /* msg already logged */ } else { ifentry->mtu = ifrq.ifr_mtu; } return rc; }
/** * interface entry flags ioctl wrapper * * @param fd : socket fd to use w/ioctl, or -1 to open/close one * @param ifentry : ifentry to update * * @retval 0 : success * @retval -1 : invalid parameters * @retval -2 : couldn't create socket * @retval -3 : ioctl call failed */ int netsnmp_access_interface_ioctl_flags_get(int fd, netsnmp_interface_entry *ifentry) { struct ifreq ifrq; int rc = 0; DEBUGMSGTL(("access:interface:ioctl", "flags_get\n")); rc = _ioctl_get(fd, SIOCGIFFLAGS, &ifrq, ifentry->name); if (rc < 0) { ifentry->ns_flags &= ~NETSNMP_INTERFACE_FLAGS_HAS_IF_FLAGS; return rc; /* msg already logged */ } else { ifentry->ns_flags |= NETSNMP_INTERFACE_FLAGS_HAS_IF_FLAGS; ifentry->os_flags = ifrq.ifr_flags; /* * ifOperStatus description: * If ifAdminStatus is down(2) then ifOperStatus should be down(2). */ if(ifentry->os_flags & IFF_UP) { ifentry->admin_status = IFADMINSTATUS_UP; if(ifentry->os_flags & IFF_RUNNING) ifentry->oper_status = IFOPERSTATUS_UP; else ifentry->oper_status = IFOPERSTATUS_DOWN; } else { ifentry->admin_status = IFADMINSTATUS_DOWN; ifentry->oper_status = IFOPERSTATUS_DOWN; } } return rc; }
/** * interface entry physaddr ioctl wrapper * * @param fd : socket fd to use w/ioctl, or -1 to open/close one * @param ifentry : ifentry to update * * @retval 0 : success * @retval -1 : invalid parameters * @retval -2 : couldn't create socket * @retval -3 : ioctl call failed * @retval -4 : malloc error */ int netsnmp_access_interface_ioctl_physaddr_get(int fd, netsnmp_interface_entry *ifentry) { struct ifreq ifrq; int rc = 0; DEBUGMSGTL(("access:interface:ioctl", "physaddr_get\n")); if((NULL != ifentry->paddr) && (ifentry->paddr_len != IFHWADDRLEN)) { SNMP_FREE(ifentry->paddr); } if(NULL == ifentry->paddr) ifentry->paddr = (char*)malloc(IFHWADDRLEN); if(NULL == ifentry->paddr) { rc = -4; } else { /* * NOTE: this ioctl does not guarantee 6 bytes of a physaddr. * In particular, a 'sit0' interface only appears to get back * 4 bytes of sa_data. Uncomment this memset, and suddenly * the sit interface will be 0:0:0:0:?:? where ? is whatever was * in the memory before. Not sure if this memset should be done * for every ioctl, as the rest seem to work ok... */ memset(ifrq.ifr_hwaddr.sa_data, (0), IFHWADDRLEN); ifentry->paddr_len = IFHWADDRLEN; rc = _ioctl_get(fd, SIOCGIFHWADDR, &ifrq, ifentry->name); if (rc < 0) { memset(ifentry->paddr, (0), IFHWADDRLEN); rc = -3; /* msg already logged */ } else { memcpy(ifentry->paddr, ifrq.ifr_hwaddr.sa_data, IFHWADDRLEN); /* * arphrd defines vary greatly. ETHER seems to be the only common one */ #ifdef ARPHRD_ETHER switch (ifrq.ifr_hwaddr.sa_family) { case ARPHRD_ETHER: ifentry->type = IANAIFTYPE_ETHERNETCSMACD; break; #if defined(ARPHRD_TUNNEL) || defined(ARPHRD_IPGRE) || defined(ARPHRD_SIT) #ifdef ARPHRD_TUNNEL case ARPHRD_TUNNEL: case ARPHRD_TUNNEL6: #endif #ifdef ARPHRD_IPGRE case ARPHRD_IPGRE: #endif #ifdef ARPHRD_SIT case ARPHRD_SIT: #endif ifentry->type = IANAIFTYPE_TUNNEL; break; /* tunnel */ #endif #ifdef ARPHRD_SLIP case ARPHRD_SLIP: case ARPHRD_CSLIP: case ARPHRD_SLIP6: case ARPHRD_CSLIP6: ifentry->type = IANAIFTYPE_SLIP; break; /* slip */ #endif #ifdef ARPHRD_PPP case ARPHRD_PPP: ifentry->type = IANAIFTYPE_PPP; break; /* ppp */ #endif #ifdef ARPHRD_LOOPBACK case ARPHRD_LOOPBACK: ifentry->type = IANAIFTYPE_SOFTWARELOOPBACK; break; /* softwareLoopback */ #endif #ifdef ARPHRD_FDDI case ARPHRD_FDDI: ifentry->type = IANAIFTYPE_FDDI; break; #endif #ifdef ARPHRD_ARCNET case ARPHRD_ARCNET: ifentry->type = IANAIFTYPE_ARCNET; break; #endif #ifdef ARPHRD_LOCALTLK case ARPHRD_LOCALTLK: ifentry->type = IANAIFTYPE_LOCALTALK; break; #endif #ifdef ARPHRD_HIPPI case ARPHRD_HIPPI: ifentry->type = IANAIFTYPE_HIPPI; break; #endif #ifdef ARPHRD_ATM case ARPHRD_ATM: ifentry->type = IANAIFTYPE_ATM; break; #endif /* * XXX: more if_arp.h:ARPHRD_xxx to IANAifType mappings... */ default: DEBUGMSGTL(("access:interface:ioctl", "unknown entry type %d\n", ifrq.ifr_hwaddr.sa_family)); ifentry->type = IANAIFTYPE_OTHER; } /* switch */ #endif /* ARPHRD_LOOPBACK */ } } return rc; }