+
+/*
+ * Figure out device configuration and select
+ * networks which deserve status information.
+ */
+configure(s)
+ int s;
+{
+ char buf[BUFSIZ];
+ struct ifconf ifc;
+ struct ifreq ifreq, *ifr;
+ struct sockaddr_in *sin;
+ register struct neighbor *np;
+ int n;
+
+ ifc.ifc_len = sizeof (buf);
+ ifc.ifc_buf = buf;
+ if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
+ syslog(LOG_ERR, "ioctl (get interface configuration)");
+ return (0);
+ }
+ ifr = ifc.ifc_req;
+ for (n = ifc.ifc_len / sizeof (struct ifreq); n > 0; n--, ifr++) {
+ for (np = neighbors; np != NULL; np = np->n_next)
+ if (np->n_name &&
+ strcmp(ifr->ifr_name, np->n_name) == 0)
+ break;
+ if (np != NULL)
+ continue;
+ ifreq = *ifr;
+ np = (struct neighbor *)malloc(sizeof (*np));
+ if (np == NULL)
+ continue;
+ np->n_name = malloc(strlen(ifr->ifr_name) + 1);
+ if (np->n_name == NULL) {
+ free((char *)np);
+ continue;
+ }
+ strcpy(np->n_name, ifr->ifr_name);
+ np->n_addrlen = sizeof (ifr->ifr_addr);
+ np->n_addr = malloc(np->n_addrlen);
+ if (np->n_addr == NULL) {
+ free(np->n_name);
+ free((char *)np);
+ continue;
+ }
+ bcopy((char *)&ifr->ifr_addr, np->n_addr, np->n_addrlen);
+ if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
+ syslog(LOG_ERR, "ioctl (get interface flags)");
+ free((char *)np);
+ continue;
+ }
+ if ((ifreq.ifr_flags & IFF_UP) == 0 ||
+ (ifreq.ifr_flags & (IFF_BROADCAST|IFF_POINTOPOINT)) == 0) {
+ free((char *)np);
+ continue;
+ }
+ np->n_flags = ifreq.ifr_flags;
+ if (np->n_flags & IFF_POINTOPOINT) {
+ if (ioctl(s, SIOCGIFDSTADDR, (char *)&ifreq) < 0) {
+ syslog(LOG_ERR, "ioctl (get dstaddr)");
+ free((char *)np);
+ continue;
+ }
+ /* we assume addresses are all the same size */
+ bcopy((char *)&ifreq.ifr_dstaddr,
+ np->n_addr, np->n_addrlen);
+ }
+ if (np->n_flags & IFF_BROADCAST) {
+ if (ioctl(s, SIOCGIFBRDADDR, (char *)&ifreq) < 0) {
+ syslog(LOG_ERR, "ioctl (get broadaddr)");
+ free((char *)np);
+ continue;
+ }
+ /* we assume addresses are all the same size */
+ bcopy((char *)&ifreq.ifr_broadaddr,
+ np->n_addr, np->n_addrlen);
+ }
+ /* gag, wish we could get rid of Internet dependencies */
+ sin = (struct sockaddr_in *)np->n_addr;
+ sin->sin_port = sp->s_port;
+ np->n_next = neighbors;
+ neighbors = np;
+ }
+ return (1);
+}
+
+#ifdef DEBUG
+sendto(s, buf, cc, flags, to, tolen)
+ int s;
+ char *buf;
+ int cc, flags;
+ char *to;
+ int tolen;
+{
+ register struct whod *w = (struct whod *)buf;
+ register struct whoent *we;
+ struct sockaddr_in *sin = (struct sockaddr_in *)to;
+ char *interval();
+
+ printf("sendto %x.%d\n", ntohl(sin->sin_addr), ntohs(sin->sin_port));
+ printf("hostname %s %s\n", w->wd_hostname,
+ interval(ntohl(w->wd_sendtime) - ntohl(w->wd_boottime), " up"));
+ printf("load %4.2f, %4.2f, %4.2f\n",
+ ntohl(w->wd_loadav[0]) / 100.0, ntohl(w->wd_loadav[1]) / 100.0,
+ ntohl(w->wd_loadav[2]) / 100.0);
+ cc -= WHDRSIZE;
+ for (we = w->wd_we, cc /= sizeof (struct whoent); cc > 0; cc--, we++) {
+ time_t t = ntohl(we->we_utmp.out_time);
+ printf("%-8.8s %s:%s %.12s",
+ we->we_utmp.out_name,
+ w->wd_hostname, we->we_utmp.out_line,
+ ctime(&t)+4);
+ we->we_idle = ntohl(we->we_idle) / 60;
+ if (we->we_idle) {
+ if (we->we_idle >= 100*60)
+ we->we_idle = 100*60 - 1;
+ if (we->we_idle >= 60)
+ printf(" %2d", we->we_idle / 60);
+ else
+ printf(" ");
+ printf(":%02d", we->we_idle % 60);
+ }
+ printf("\n");
+ }
+}
+
+char *
+interval(time, updown)
+ int time;
+ char *updown;
+{
+ static char resbuf[32];
+ int days, hours, minutes;
+
+ if (time < 0 || time > 3*30*24*60*60) {
+ (void) sprintf(resbuf, " %s ??:??", updown);
+ return (resbuf);
+ }
+ minutes = (time + 59) / 60; /* round to minutes */
+ hours = minutes / 60; minutes %= 60;
+ days = hours / 24; hours %= 24;
+ if (days)
+ (void) sprintf(resbuf, "%s %2d+%02d:%02d",
+ updown, days, hours, minutes);
+ else
+ (void) sprintf(resbuf, "%s %2d:%02d",
+ updown, hours, minutes);
+ return (resbuf);
+}
+#endif