static void proc_read(void) { FILE * fd; char buf[512], *p, *s; int w; intf_t *i; if (!(fd = fopen(c_path, "r"))) quit("Unable to open file %s: %s\n", c_path, strerror(errno)); fgets(buf, sizeof(buf), fd); fgets(buf, sizeof(buf), fd); for (; fgets(buf, sizeof(buf), fd);) { b_cnt_t rx_errors, rx_drop, rx_fifo, rx_frame, rx_compressed; b_cnt_t rx_multicast, tx_errors, tx_drop, tx_fifo, tx_frame; b_cnt_t tx_compressed, tx_multicast; if (buf[0] == '\r' || buf[0] == '\n') continue; if (!(p = strchr(buf, ':'))) continue; *p = '\0'; s = (p + 1); for (p = &buf[0]; *p == ' '; p++); /* * XXX: get_show_only_running */ if ((i = lookup_intf(get_local_node(), p, 0, 0)) == NULL) continue; w = sscanf(s, "%llu %llu %llu %llu %llu %llu %llu %llu %llu %llu " "%llu %llu %llu %llu %llu %llu\n", &i->i_rx_bytes.r_total, &i->i_rx_packets.r_total, &rx_errors, &rx_drop, &rx_fifo, &rx_frame, &rx_compressed, &rx_multicast, &i->i_tx_bytes.r_total, &i->i_tx_packets.r_total, &tx_errors, &tx_drop, &tx_fifo, &tx_frame, &tx_compressed, &tx_multicast); if (w != 16) continue; update_attr(i, ERRORS, rx_errors, tx_errors, RX_PROVIDED|TX_PROVIDED); update_attr(i, DROP, rx_drop, tx_drop, RX_PROVIDED|TX_PROVIDED); update_attr(i, FIFO, rx_fifo, tx_fifo, RX_PROVIDED|TX_PROVIDED); update_attr(i, FRAME, rx_frame, tx_frame, RX_PROVIDED|TX_PROVIDED); update_attr(i, COMPRESSED, rx_compressed, tx_compressed, RX_PROVIDED|TX_PROVIDED); update_attr(i, MULTICAST, rx_multicast, tx_multicast, RX_PROVIDED|TX_PROVIDED); notify_update(i); increase_lifetime(i, 1); } fclose(fd); }
static void sysctl_read(void) { int mib[] = {CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0}; size_t n; char *buf, *next, *lim; if (sysctl(mib, 6, NULL, &n, NULL, 0) < 0) quit("sysctl() failed"); if (c_debug) fprintf(stderr, "sysctl 1-pass n=%d\n", (int) n); buf = xcalloc(1, n); if (sysctl(mib, 6, buf, &n, NULL, 0) < 0) quit("sysctl() failed"); if (c_debug) fprintf(stderr, "sysctl 2-pass n=%d\n", (int) n); lim = buf + n; next = buf; while (next < lim) { char ifname[IFNAME_MAX]; int iflen = sizeof(ifname) - 1; struct if_msghdr *ifm, *nextifm; struct sockaddr_dl *sdl; struct item *it; memset(ifname, 0, sizeof(ifname)); ifm = (struct if_msghdr *) next; if (ifm->ifm_type != RTM_IFINFO) break; next += ifm->ifm_msglen; while (next < lim) { nextifm = (struct if_msghdr *) next; if (nextifm->ifm_type != RTM_NEWADDR) break; next += nextifm->ifm_msglen; } sdl = (struct sockaddr_dl *) (ifm + 1); if (sdl->sdl_family != AF_LINK) continue; if (cfg_show_only_running && !(ifm->ifm_flags & IFF_UP)) continue; if (iflen > sd->sdl_nlen) iflen = sdl->sdl_nlen; memcpy(ifname, sdl->sdl_data, iflen); if (c_debug) fprintf(stderr, "Processing %s\n", ifname); it = lookup_item(get_local_node(), ifname, 0, 0); if (it == NULL) continue; set_item_attrs(it, ATTR(BYTES), ATTR(PACKETS), ATTR(BYTES)); update_attr(it, ATTR(PACKETS), ifm->ifm_data.ifi_ipackets, ifm->ifm_data.ifi_opackets, RX_PROVIDED | TX_PROVIDED); update_attr(it, ATTR(BYTES), ifm->ifm_data.ifi_ibytes, ifm->ifm_data.ifi_obytes, RX_PROVIDED | TX_PROVIDED); update_attr(it, ATTR(ERRORS), ifm->ifm_data.ifi_ierrors, ifm->ifm_data.ifi_oerrors, RX_PROVIDED | TX_PROVIDED); update_attr(it, ATTR(COLLISIONS), 0, ifm->ifm_data.ifi_collisions, TX_PROVIDED); update_attr(it, ATTR(MULTICAST), ifm->ifm_data.ifi_imcasts, 0, RX_PROVIDED); update_attr(it, ATTR(DROP), 0, ifm->ifm_data.ifi_iqdrops, TX_PROVIDED); notify_update(it, NULL); increase_lifetime(it, 1); } xfree(buf); }
static int process_intf(struct distr_msg_hdr *hdr, const char *nodename, struct distr_msg_intf *intf, char *from) { char *intfname; int remaining, offset; uint32_t handle = 0; int parent = 0, level = 0, link = 0, index = 0; intf_t *local_intf; node_t *remote_node; intfname = ((char *) intf) + sizeof(*intf); if (c_debug) fprintf(stderr, "Processing interface %s (offset: %d " \ "optslen: %d namelen: %d hdrsize: %d)\n", intfname ? intfname : "null", ntohs(intf->i_offset), intf->i_optslen, intf->i_namelen, sizeof(*intf)); if (intf->i_namelen < 4 || intf->i_namelen > IFNAME_MAX) { if (c_debug) fprintf(stderr, "Discarding malformed packet (invalid namelen %d)\n", intf->i_namelen); return -1; } if ('\0' == *intfname) { if (c_debug) fprintf(stderr, "Discarding malformed packet (empty linkname)\n"); return -1; } index = ntohs(intf->i_index); if (intf->i_optslen) { offset = sizeof(*intf) + intf->i_namelen; remaining = intf->i_optslen; while (remaining > 0) { struct distr_msg_ifopt *opt; opt = (struct distr_msg_ifopt *) (((char *) intf) + offset); if (opt->io_len > (remaining - sizeof(*opt))) { if (c_debug) fprintf(stderr, "Discarding malformed packet (invalid opt len)\n"); return -1; } switch (opt->io_type) { case IFOPT_HANDLE: if (opt->io_len != sizeof(uint32_t)) { if (c_debug) fprintf(stderr, "Discarding malformed packet " \ "(invalid opt len for handle)\n"); return -1; } handle = ntohl(*(uint32_t *) (((char *) opt) + sizeof (*opt))); break; case IFOPT_PARENT: parent = ntohs(opt->io_pad); break; case IFOPT_LEVEL: level = ntohs(opt->io_pad); break; case IFOPT_LINK: link = ntohs(opt->io_pad); break; } remaining -= (sizeof(*opt) + opt->io_len); offset += (sizeof(*opt) + opt->io_len); } if (remaining < 0) if (c_debug) fprintf(stderr, "Leftover from options: %d\n", abs(remaining)); } remote_node = lookup_node(nodename, 1); if (NULL == remote_node) { if (c_debug) fprintf(stderr, "Could not create node entry for remote node\n"); return -1; } if (remote_node->n_from) xfree((void *) remote_node->n_from); remote_node->n_from = strdup(from); local_intf = lookup_intf(remote_node, intfname, handle, parent); if (NULL == local_intf) { if (c_debug) fprintf(stderr, "Could not crate interface for remote interface\n"); return -1; } offset = sizeof(*intf) + intf->i_optslen + intf->i_namelen; remaining = ntohs(intf->i_offset) - offset; while (remaining > 0) { struct distr_msg_attr *attr; attr = (struct distr_msg_attr *) (((char *) intf) + offset); if (c_debug) fprintf(stderr, "Attribute type %d %llu %llu\n", attr->a_type, attr->a_rx, attr->a_tx); if (attr->a_type >= ATTR_MAX) goto skip; if (attr->a_type == BYTES) { local_intf->i_rx_bytes.r_total = attr->a_rx; local_intf->i_tx_bytes.r_total = attr->a_tx; local_intf->i_rx_bytes.r_overflows = attr->a_rx_overflows; local_intf->i_tx_bytes.r_overflows = attr->a_tx_overflows; } else if (attr->a_type == PACKETS) { local_intf->i_rx_packets.r_total = attr->a_rx; local_intf->i_tx_packets.r_total = attr->a_tx; local_intf->i_rx_packets.r_overflows = attr->a_rx_overflows; local_intf->i_tx_packets.r_overflows = attr->a_tx_overflows; } else { int flags = (attr->a_flags & ATTR_RX_PROVIDED ? RX_PROVIDED : 0) | (attr->a_flags & ATTR_TX_PROVIDED ? TX_PROVIDED : 0); update_attr(local_intf, attr->a_type, attr->a_rx, attr->a_tx, flags); } skip: remaining -= sizeof(*attr); offset += sizeof(*attr); } if (intf->i_flags & IF_IS_CHILD) local_intf->i_is_child = 1; local_intf->i_level = level; local_intf->i_link = link; notify_update(local_intf); increase_lifetime(local_intf, 1); if (remaining < 0) if (c_debug) fprintf(stderr, "Leftover from attributes: %d\n", abs(remaining)); return 0; }
static void kstat_do_read(void) { kstat_ctl_t * kc; kstat_t * kst; kstat_named_t * kn, *kn2; intf_t * i; if (!(kc = kstat_open())) quit("kstat_open() failed"); if ((kst = kstat_lookup(kc, NULL, -1, NULL))) { for (; kst; kst = kst->ks_next) { if (strcmp(kst->ks_class, "net")) continue; if (kstat_read(kc, kst, NULL) < 0) continue; if (!strcmp(kst->ks_name, "zero_copy")) continue; i = lookup_intf(get_local_node(), kst->ks_name, 0, 0); if (NULL == i) continue; #define KSTAT_GET(S) (kstat_named_t *) kstat_data_lookup(kst, #S) if ((kn = KSTAT_GET(rbytes64))) { i->i_rx_bytes.r_total = kn->value.ui64; i->i_rx_bytes.r_is64bit = 1; } else if ((kn = KSTAT_GET(rbytes))) i->i_rx_bytes.r_total = kn->value.ui32; if ((kn = KSTAT_GET(ipackets64))) { i->i_rx_packets.r_total = kn->value.ui64; i->i_rx_packets.r_is64bit = 1; } else if ((kn = KSTAT_GET(ipackets))) i->i_rx_packets.r_total = kn->value.ui32; if ((kn = KSTAT_GET(obytes64))) i->i_tx_bytes.r_total = kn->value.ui64; else if ((kn = KSTAT_GET(obytes))) i->i_tx_bytes.r_total = kn->value.ui32; if ((kn = KSTAT_GET(opackets64))) i->i_tx_packets.r_total = kn->value.ui64; else if ((kn = KSTAT_GET(opackets))) i->i_tx_packets.r_total = kn->value.ui32; if ((kn = KSTAT_GET(ierror)) && (kn2 = KSTAT_GET(oerrors))) update_attr(i, ERRORS, kn->value.ui32, kn2->value.ui32, RX_PROVIDED | TX_PROVIDED); if ((kn = KSTAT_GET(multircv64)) && (kn2 = KSTAT_GET(multixmt64))) update_attr(i, MULTICAST, kn->value.ui64, kn2->value.ui64, RX_PROVIDED | TX_PROVIDED); else if ((kn = KSTAT_GET(multircv)) && (kn2 = KSTAT_GET(multixmt))) update_attr(i, MULTICAST, kn->value.ui32, kn2->value.ui32, RX_PROVIDED | TX_PROVIDED); if ((kn = KSTAT_GET(brdcstrcv)) && (kn2 = KSTAT_GET(brdcstxmt))) update_attr(i, BROADCAST, kn->value.ui32, kn2->value.ui32, RX_PROVIDED | TX_PROVIDED); #undef KSTAT_GET notify_update(i); increase_lifetime(i, 1); } } kstat_close(kc); }