static int net_conn_get_udp_listen(sigar_net_connection_walker_t *walker) { sigar_t *sigar = walker->sigar; int flags = walker->flags; int status, count, i; unsigned int len; mib_udpLsnEnt *entries; struct nmparms parms; len = sizeof(count); parms.objid = ID_udpLsnNumEnt; parms.buffer = &count; parms.len = &len; if ((status = sigar_get_mib_info(sigar, &parms)) != SIGAR_OK) { return status; } if (count <= 0) { return ENOENT; } len = count * sizeof(*entries); entries = malloc(len); parms.objid = ID_udpLsnTable; parms.buffer = entries; parms.len = &len; if ((status = sigar_get_mib_info(sigar, &parms)) != SIGAR_OK) { free(entries); return status; } for (i=0; i<count; i++) { sigar_net_connection_t conn; mib_udpLsnEnt *entry = &entries[i]; SIGAR_ZERO(&conn); conn.type = SIGAR_NETCONN_UDP; conn.local_port = (unsigned short)entry->LocalPort; conn.remote_port = 0; sigar_net_address_set(conn.local_address, entry->LocalAddress); sigar_net_address_set(conn.remote_address, 0); conn.send_queue = conn.receive_queue = SIGAR_FIELD_NOTIMPL; if (walker->add_connection(walker, &conn) != SIGAR_OK) { break; } } free(entries); return SIGAR_OK; }
static int udp_connection_get(sigar_net_connection_walker_t *walker, struct mib2_udpEntry *entry, int len) { int flags = walker->flags; int status; char *end = (char *)entry + len; while ((char *)entry < end) { int state = entry->udpEntryInfo.ue_state; /* XXX dunno if this state check is right */ if (((flags & SIGAR_NETCONN_SERVER) && (state == MIB2_UDP_idle)) || ((flags & SIGAR_NETCONN_CLIENT) && (state != MIB2_UDP_idle))) { sigar_net_connection_t conn; SIGAR_ZERO(&conn); sigar_net_address_set(conn.local_address, entry->udpLocalAddress); sigar_net_address_set(conn.remote_address, 0); conn.local_port = entry->udpLocalPort; conn.remote_port = 0; conn.type = SIGAR_NETCONN_UDP; status = walker->add_connection(walker, &conn); if (status != SIGAR_OK) { return status; } } entry++; } return SIGAR_OK; }
static int tcp_connection_get(sigar_net_connection_walker_t *walker, struct mib2_tcpConnEntry *entry, int len) { int flags = walker->flags; int status; char *end = (char *)entry + len; while ((char *)entry < end) { int state = entry->tcpConnEntryInfo.ce_state; if (((flags & SIGAR_NETCONN_SERVER) && (state == TCPS_LISTEN)) || ((flags & SIGAR_NETCONN_CLIENT) && (state != TCPS_LISTEN))) { sigar_net_connection_t conn; SIGAR_ZERO(&conn); sigar_net_address_set(conn.local_address, entry->tcpConnLocalAddress); sigar_net_address_set(conn.remote_address, entry->tcpConnRemAddress); conn.local_port = entry->tcpConnLocalPort; conn.remote_port = entry->tcpConnRemPort; conn.type = SIGAR_NETCONN_TCP; conn.send_queue = TCPQ_SIZE(entry->tcpConnEntryInfo.ce_snxt - entry->tcpConnEntryInfo.ce_suna - 1); conn.receive_queue = TCPQ_SIZE(entry->tcpConnEntryInfo.ce_rnxt - entry->tcpConnEntryInfo.ce_rack); switch (state) { case TCPS_CLOSED: conn.state = SIGAR_TCP_CLOSE; break; case TCPS_IDLE: conn.state = SIGAR_TCP_IDLE; break; case TCPS_BOUND: conn.state = SIGAR_TCP_BOUND; break; case TCPS_LISTEN: conn.state = SIGAR_TCP_LISTEN; break; case TCPS_SYN_SENT: conn.state = SIGAR_TCP_SYN_SENT; break; case TCPS_SYN_RCVD: conn.state = SIGAR_TCP_SYN_RECV; break; case TCPS_ESTABLISHED: conn.state = SIGAR_TCP_ESTABLISHED; break; case TCPS_CLOSE_WAIT: conn.state = SIGAR_TCP_CLOSE_WAIT; break; case TCPS_FIN_WAIT_1: conn.state = SIGAR_TCP_FIN_WAIT1; break; case TCPS_CLOSING: conn.state = SIGAR_TCP_CLOSING; break; case TCPS_LAST_ACK: conn.state = SIGAR_TCP_LAST_ACK; break; case TCPS_FIN_WAIT_2: conn.state = SIGAR_TCP_FIN_WAIT2; break; case TCPS_TIME_WAIT: conn.state = SIGAR_TCP_TIME_WAIT; break; default: conn.state = SIGAR_TCP_UNKNOWN; break; } status = walker->add_connection(walker, &conn); if (status != SIGAR_OK) { return status; } } entry++; } return SIGAR_OK; }
int sigar_net_interface_config_get(sigar_t *sigar, const char *name, sigar_net_interface_config_t *ifconfig) { int sock; struct ifreq ifr; if (!name) { return sigar_net_interface_config_primary_get(sigar, ifconfig); } SIGAR_ZERO(ifconfig); if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { return errno; } SIGAR_SSTRCPY(ifconfig->name, name); SIGAR_SSTRCPY(ifr.ifr_name, name); #define ifr_s_addr(ifr) \ ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr if (!ioctl(sock, SIOCGIFADDR, &ifr)) { sigar_net_address_set(ifconfig->address, ifr_s_addr(ifr)); } if (!ioctl(sock, SIOCGIFNETMASK, &ifr)) { sigar_net_address_set(ifconfig->netmask, ifr_s_addr(ifr)); } if (!ioctl(sock, SIOCGIFFLAGS, &ifr)) { sigar_uint64_t flags = ifr.ifr_flags; #ifdef __linux__ # ifndef IFF_DYNAMIC # define IFF_DYNAMIC 0x8000 /* not in 2.2 kernel */ # endif /* IFF_DYNAMIC */ int is_mcast = flags & IFF_MULTICAST; int is_slave = flags & IFF_SLAVE; int is_master = flags & IFF_MASTER; int is_dynamic = flags & IFF_DYNAMIC; /* * XXX: should just define SIGAR_IFF_* * and test IFF_* bits on given platform. * this is the only diff between solaris/hpux/linux * for the flags we care about. * */ flags &= ~(IFF_MULTICAST|IFF_SLAVE|IFF_MASTER); if (is_mcast) { flags |= SIGAR_IFF_MULTICAST; } if (is_slave) { flags |= SIGAR_IFF_SLAVE; } if (is_master) { flags |= SIGAR_IFF_MASTER; } if (is_dynamic) { flags |= SIGAR_IFF_DYNAMIC; } #endif ifconfig->flags = flags; } else { /* should always be able to get flags for existing device */ /* other ioctls may fail if device is not enabled: ok */ close(sock); return errno; } if (ifconfig->flags & IFF_LOOPBACK) { sigar_net_address_set(ifconfig->destination, ifconfig->address.addr.in); sigar_net_address_set(ifconfig->broadcast, 0); sigar_hwaddr_set_null(ifconfig); SIGAR_SSTRCPY(ifconfig->type, SIGAR_NIC_LOOPBACK); } else { if (!ioctl(sock, SIOCGIFDSTADDR, &ifr)) { sigar_net_address_set(ifconfig->destination, ifr_s_addr(ifr)); } if (!ioctl(sock, SIOCGIFBRDADDR, &ifr)) { sigar_net_address_set(ifconfig->broadcast, ifr_s_addr(ifr)); } #if defined(HAVE_LIBDLPI_H) hwaddr_libdlpi_lookup(sigar, ifconfig); #elif defined(SIOCGIFHWADDR) if (!ioctl(sock, SIOCGIFHWADDR, &ifr)) { get_interface_type(ifconfig, ifr.ifr_hwaddr.sa_family); sigar_net_address_mac_set(ifconfig->hwaddr, ifr.ifr_hwaddr.sa_data, IFHWADDRLEN); } #elif defined(_AIX) || defined(__osf__) hwaddr_aix_lookup(sigar, ifconfig); SIGAR_SSTRCPY(ifconfig->type, SIGAR_NIC_ETHERNET); #else hwaddr_arp_lookup(ifconfig, sock); SIGAR_SSTRCPY(ifconfig->type, SIGAR_NIC_ETHERNET); #endif } #if defined(SIOCGLIFMTU) && !defined(__hpux) { struct lifreq lifr; SIGAR_SSTRCPY(lifr.lifr_name, name); if(!ioctl(sock, SIOCGLIFMTU, &lifr)) { ifconfig->mtu = lifr.lifr_mtu; } } #elif defined(SIOCGIFMTU) if (!ioctl(sock, SIOCGIFMTU, &ifr)) { # if defined(__hpux) ifconfig->mtu = ifr.ifr_metric; # else ifconfig->mtu = ifr.ifr_mtu; #endif } #else ifconfig->mtu = 0; /*XXX*/ #endif if (!ioctl(sock, SIOCGIFMETRIC, &ifr)) { ifconfig->metric = ifr.ifr_metric ? ifr.ifr_metric : 1; } #if defined(SIOCGIFTXQLEN) if (!ioctl(sock, SIOCGIFTXQLEN, &ifr)) { ifconfig->tx_queue_len = ifr.ifr_qlen; } else { ifconfig->tx_queue_len = -1; /* net-tools behaviour */ } #else ifconfig->tx_queue_len = -1; #endif close(sock); /* XXX can we get a better description like win32? */ SIGAR_SSTRCPY(ifconfig->description, ifconfig->name); sigar_net_interface_ipv6_config_init(ifconfig); sigar_net_interface_ipv6_config_get(sigar, name, ifconfig); return SIGAR_OK; }
static int net_conn_get_tcp(sigar_net_connection_walker_t *walker) { sigar_t *sigar = walker->sigar; int flags = walker->flags; int status, count, i; unsigned int len; mib_tcpConnEnt *entries; struct nmparms parms; len = sizeof(count); parms.objid = ID_tcpConnNumEnt; parms.buffer = &count; parms.len = &len; if ((status = sigar_get_mib_info(sigar, &parms)) != SIGAR_OK) { return status; } if (count <= 0) { return ENOENT; } len = count * sizeof(*entries); entries = malloc(len); parms.objid = ID_tcpConnTable; parms.buffer = entries; parms.len = &len; if ((status = sigar_get_mib_info(sigar, &parms)) != SIGAR_OK) { free(entries); return status; } for (i=0; i<count; i++) { sigar_net_connection_t conn; mib_tcpConnEnt *entry = &entries[i]; int state = entry->State; if (!(IS_TCP_SERVER(state, flags) || IS_TCP_CLIENT(state, flags))) { continue; } SIGAR_ZERO(&conn); switch (state) { case TCCLOSED: conn.state = SIGAR_TCP_CLOSE; break; case TCLISTEN: conn.state = SIGAR_TCP_LISTEN; break; case TCSYNSENT: conn.state = SIGAR_TCP_SYN_SENT; break; case TCSYNRECEIVE: conn.state = SIGAR_TCP_SYN_RECV; break; case TCESTABLISED: conn.state = SIGAR_TCP_ESTABLISHED; break; case TCFINWAIT1: conn.state = SIGAR_TCP_FIN_WAIT1; break; case TCFINWAIT2: conn.state = SIGAR_TCP_FIN_WAIT2; break; case TCCLOSEWAIT: conn.state = SIGAR_TCP_CLOSE_WAIT; break; case TCCLOSING: conn.state = SIGAR_TCP_CLOSING; break; case TCLASTACK: conn.state = SIGAR_TCP_LAST_ACK; break; case TCTIMEWAIT: conn.state = SIGAR_TCP_TIME_WAIT; break; case TCDELETETCB: default: conn.state = SIGAR_TCP_UNKNOWN; break; } conn.local_port = (unsigned short)entry->LocalPort; conn.remote_port = (unsigned short)entry->RemPort; conn.type = SIGAR_NETCONN_TCP; sigar_net_address_set(conn.local_address, entry->LocalAddress); sigar_net_address_set(conn.remote_address, entry->RemAddress); conn.send_queue = conn.receive_queue = SIGAR_FIELD_NOTIMPL; if (walker->add_connection(walker, &conn) != SIGAR_OK) { break; } } free(entries); return SIGAR_OK; }
int sigar_net_route_list_get(sigar_t *sigar, sigar_net_route_list_t *routelist) { int status, count, i; unsigned int len; struct nmparms parms; mib_ipRouteEnt *routes; sigar_net_route_t *route; len = sizeof(count); parms.objid = ID_ipRouteNumEnt; parms.buffer = &count; parms.len = &len; if ((status = sigar_get_mib_info(sigar, &parms)) != SIGAR_OK) { return status; } len = count * sizeof(*routes); routes = malloc(len); parms.objid = ID_ipRouteTable; parms.buffer = routes; parms.len = &len; if ((status = sigar_get_mib_info(sigar, &parms)) != SIGAR_OK) { free(routes); return status; } routelist->size = routelist->number = 0; sigar_net_route_list_create(routelist); for (i=0; i<count; i++) { mib_ipRouteEnt *ent = &routes[i]; SIGAR_NET_ROUTE_LIST_GROW(routelist); route = &routelist->data[routelist->number++]; SIGAR_ZERO(route); /* XXX: other fields */ sigar_net_address_set(route->destination, ent->Dest); sigar_net_address_set(route->mask, ent->Mask); sigar_net_address_set(route->gateway, ent->NextHop); route->flags = SIGAR_RTF_UP; if ((ent->Dest == 0) && (ent->Mask == 0)) { route->flags |= SIGAR_RTF_GATEWAY; } } free(routes); return SIGAR_OK; }