Beispiel #1
0
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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
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;
}