13 #include <netinet/in.h>
14 #include <arpa/inet.h>
15 #include <sys/ioctl.h>
16 #include <sys/socket.h>
18 #if defined(__OpenBSD__)
19 #include <net/if_dl.h>
20 #include <net/if_types.h>
21 #include <net/route.h>
22 #include <sys/param.h>
23 #include <sys/sysctl.h>
24 #include <netinet/if_ether.h>
25 #include <net/if_ieee80211.h>
26 #include <dev/ic/if_wi_ieee.h>
27 #include <dev/ic/if_wireg.h>
28 #include <dev/ic/if_wi_hostap.h>
30 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
34 #include <sys/types.h>
36 #ifdef ENABLE_NWN_SUPPORT
41 #include "bitmaps/wmifinfo_led.xbm"
42 #include "bitmaps/wmifinfo_led.xpm"
43 #include "bitmaps/wmifinfo_lcd.xbm"
44 #include "bitmaps/wmifinfo_lcd.xpm"
48 #define DELAY 1000000L
76 char LabelColor
[30] = "#79bdbf";
77 char WindGustColor
[30] = "#ff0000";
78 char DataColor
[30] = "#ffbf50";
79 char BackColor
[30] = "#181818";
80 char StationTimeColor
[30] = "#c5a6ff";
82 struct font_t font1
= { " 0123456789ABCDEF", 64, 74, 4, 5, 17};
83 struct font_t font2
= { "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789: ", 1, 65, 5, 7, 26};
85 char *exec_dflt
= "echo Use the -u and -d options for setting ifup/ifdown commands.";
90 char startif
[16] = "";
91 char ifname
[MAXIFS
][16];
94 struct ifinfo_t ifinfo
;
97 volatile int exec_busy
=0;
100 void parse_cmdline(int argc
, char *argv
[]);
101 void ButtonPressEvent(XButtonEvent
*);
102 char *strupper(char *str
);
103 void getifnames(void);
104 int getifinfo(char *ifname
, struct ifinfo_t
*info
);
109 void drawtext(char *str
, struct font_t
*font
, int x
, int y
)
116 p
= strchr(font
->chars
, str
[i
]);
117 ix
= (p
) ? (p
- font
->chars
) : 0;
119 iy
= (ix
/ font
->charspline
);
120 ix
= (ix
% font
->charspline
);
122 copyXPMArea( font
->sx
+ ix
* font
->dx
,
123 font
->sy
+ iy
* font
->dy
,
134 void drawipaddr(uint32_t a
, int linenum
)
138 uint32_t addr
= ntohl(a
);
141 snprintf(buf
, 4, "%3d", (addr
>> ((3-i
)*8)) & 255);
142 drawtext(buf
, &font1
, 5 + i
*14, 19 + linenum
*9);
146 void drawhwaddr(unsigned char *addr
)
152 snprintf(buf
, 4, "%02X", addr
[i
]);
153 drawtext(buf
, &font1
, 6 + i
*9, 46);
157 int main(int argc
, char *argv
[])
168 int prev_exec_busy
=0;
171 exec_down
= exec_dflt
;
173 parse_cmdline(argc
, argv
);
175 initXwindow(argc
, argv
);
177 if(mode
== MODE_LED
) {
178 openXwindow(argc
, argv
, wmifinfo_led_xpm
, wmifinfo_led_bits
,
179 wmifinfo_led_width
, wmifinfo_led_height
, BackColor
,
180 LabelColor
, WindGustColor
, DataColor
, StationTimeColor
);
182 openXwindow(argc
, argv
, wmifinfo_lcd_xpm
, wmifinfo_lcd_bits
,
183 wmifinfo_lcd_width
, wmifinfo_lcd_height
, BackColor
,
184 LabelColor
, WindGustColor
, DataColor
, StationTimeColor
);
187 // Initialize global variables
189 fd
= socket(AF_INET
, SOCK_DGRAM
, IPPROTO_IP
);
190 ifc
.ifc_len
= sizeof(struct ifreq
) * 10;
191 ifc
.ifc_buf
= malloc(ifc
.ifc_len
);
195 while (XPending(display
)) {
196 XNextEvent(display
, &event
);
198 switch (event
.type
) {
203 ButtonPressEvent(&event
.xbutton
);
211 if ((d
++ == 3) || (ifno
!= pifno
) || (exec_busy
!= prev_exec_busy
)) {
215 copyXPMArea(64, 0, 64, 64, 0, 0);
219 ifno
= ifno
% ifaces
;
221 getifinfo(ifname
[ifno
], &ifinfo
);
223 if(ifno
!= pifno
) lastbytes
= ifinfo
.bytes
;
225 sprintf(buf
, "%-7s", ifinfo
.id
);
227 drawtext(buf
, &font2
, 6, 4);
229 if(memcmp(ifinfo
.hw
, "\x00\x00\x00\x00\x00\x00", 6) != 0) {
230 drawhwaddr(ifinfo
.hw
);
233 if(ifinfo
.ip
) drawipaddr(ifinfo
.ip
, 0);
234 if(ifinfo
.nm
) drawipaddr(ifinfo
.nm
, 1);
235 if(ifinfo
.gw
) drawipaddr(ifinfo
.gw
, 2);
241 #elif defined(__OpenBSD__)
245 copyXPMArea(4, 82, x
*4, 4, 6, 53);
253 if(ifinfo
.state
) x
+= 8;
254 if(lastbytes
== ifinfo
.bytes
) x
+= 16;
256 copyXPMArea(64 + x
, 81, 8, 8, 50, 4);
257 lastbytes
= ifinfo
.bytes
;
262 prev_exec_busy
= exec_busy
;
271 FD_SET(ConnectionNumber(display
), &fds
);
273 select(ConnectionNumber(display
)+1, &fds
, NULL
, NULL
, &tv
);
274 #elif defined(__OpenBSD__)
285 "usage: wmifinfo [-lh] [-i interface]\n"
286 " -d <cmd> Command to exec for iface-down\n"
287 " -i <interface> Start with given interface, if available\n"
288 " -l LCD display mode\n"
289 " -h Print this help\n"
290 " -u <cmd> Command to exec for iface-up\n"
291 " -v Show version info and exit\n"
298 printf("%s version %s, compile-time options: ", NAME
, VERSION
);
300 #ifdef ENABLE_NWN_SUPPORT
301 printf("ENABLE NWN SUPPORT ");
307 void parse_cmdline(int argc
, char *argv
[])
311 while((c
= getopt(argc
, argv
, "d:i:lhu:v")) != EOF
) {
314 exec_down
= strdup(optarg
);
317 strncpy(startif
, optarg
, sizeof(startif
));
326 exec_up
= strdup(optarg
);
336 void sigchldhandler(int a
)
342 void exec_cmd(char *cmd
)
346 signal(SIGCHLD
, sigchldhandler
);
348 if(exec_busy
) return;
360 void ButtonPressEvent(XButtonEvent
* xev
)
364 if (xev
->type
!= ButtonPress
) return;
366 switch (xev
->button
) {
375 if(ifinfo
.state
== 0) {
376 sprintf(buf
, exec_up
, ifinfo
.id
);
378 sprintf(buf
, exec_down
, ifinfo
.id
);
388 char *strupper(char *str
)
393 for (i
= 0; i
< strlen(str
); i
++)
394 str
[i
] = toupper(str
[i
]);
401 int getifinfo(char *ifname
, struct ifinfo_t
*info
)
405 struct sockaddr_in
*sa
;
408 static FILE *froute
= NULL
;
409 static FILE *fwireless
= NULL
;
410 static FILE *fdev
= NULL
;
411 #elif defined(__OpenBSD__)
412 struct ifreq ibuf
[32];
414 struct ifreq
*ifrp
, *ifend
;
424 if(froute
== NULL
) froute
= fopen("/proc/net/route", "r");
425 if(fwireless
== NULL
) fwireless
= fopen("/proc/net/wireless", "r");
426 if(fdev
== NULL
) fdev
= fopen("/proc/net/dev", "r");
430 strcpy(parent
, ifname
);
431 p
=strchr(parent
, ':');
434 strcpy(info
->id
, ifname
);
436 strcpy(ifr
.ifr_name
, ifname
);
438 // Get status (UP/DOWN)
440 if(ioctl(fd
, SIOCGIFFLAGS
, &ifr
) != -1) {
441 sa
= (struct sockaddr_in
*)&(ifr
.ifr_addr
);
442 info
->state
= (ifr
.ifr_flags
& 1) ? 1 : 0;
450 if(ioctl(fd
, SIOCGIFHWADDR
, &ifr
) != -1) {
451 memcpy(info
->hw
, ifr
.ifr_hwaddr
.sa_data
, 6);
453 memset(info
->hw
, 0, 6);
455 #elif defined(__OpenBSD__)
456 ifc
.ifc_len
= sizeof(ibuf
);
457 ifc
.ifc_buf
= (caddr_t
) ibuf
;
458 if (ioctl(fd
, SIOCGIFCONF
, (char *) &ifc
) == -1 ||
459 ifc
.ifc_len
< sizeof(struct ifreq
)) {
460 memset(info
->hw
, 0, 6);
462 /* Search interface configuration list for link layer address. */
464 ifend
= (struct ifreq
*) ((char *) ibuf
+ ifc
.ifc_len
);
465 while (ifrp
< ifend
) {
466 /* Look for interface */
467 if (strcmp(ifname
, ifrp
->ifr_name
) == 0 &&
468 ifrp
->ifr_addr
.sa_family
== AF_LINK
&&
469 ((struct sockaddr_dl
*) &ifrp
->ifr_addr
)->sdl_type
== IFT_ETHER
) {
470 memcpy(info
->hw
, LLADDR((struct sockaddr_dl
*) &ifrp
->ifr_addr
), 6);
473 /* Bump interface config pointer */
474 r
= ifrp
->ifr_addr
.sa_len
+ sizeof(ifrp
->ifr_name
);
475 if (r
< sizeof(*ifrp
))
477 ifrp
= (struct ifreq
*) ((char *) ifrp
+ r
);
484 if(ioctl(fd
, SIOCGIFADDR
, &ifr
) != -1) {
485 sa
= (struct sockaddr_in
*)&(ifr
.ifr_addr
);
486 info
->ip
= sa
->sin_addr
.s_addr
;
493 if(ioctl(fd
, SIOCGIFNETMASK
, &ifr
) != -1) {
494 sa
= (struct sockaddr_in
*)&(ifr
.ifr_addr
);
495 info
->nm
= sa
->sin_addr
.s_addr
;
500 // Get default gateway if on this interface
507 while(fgets(buf
, sizeof(buf
), froute
)) {
508 r
= sscanf(buf
, "%s %x %x", a
, &b
, &c
);
510 if((strcmp(a
, info
->id
) == 0) && (b
== 0)) {
516 #elif defined(__OpenBSD__)
518 struct rt_msghdr
*rtm
= NULL
;
519 char *buf
= NULL
, *next
, *lim
= NULL
;
523 struct sockaddr_in
*sin
;
529 mib
[4] = NET_RT_DUMP
;
531 if (sysctl(mib
, 6, NULL
, &needed
, NULL
, 0) == -1) {
532 perror("route-sysctl-estimate");
536 if ((buf
= malloc(needed
)) == 0) {
537 printf("out of space\n");
540 if (sysctl(mib
, 6, buf
, &needed
, NULL
, 0) == -1) {
541 perror("sysctl of routing table");
548 for (next
= buf
; next
< lim
; next
+= rtm
->rtm_msglen
) {
549 rtm
= (struct rt_msghdr
*)next
;
550 sa
= (struct sockaddr
*)(rtm
+ 1);
551 sin
= (struct sockaddr_in
*)sa
;
553 if (sin
->sin_addr
.s_addr
== 0) {
554 sa
= (struct sockaddr
*)(ROUNDUP(sa
->sa_len
) + (char *)sa
);
555 sin
= (struct sockaddr_in
*)sa
;
556 info
->gw
= sin
->sin_addr
.s_addr
;
565 // Get wireless link status if wireless
569 if(fwireless
!= NULL
) {
570 fseek(fwireless
, 0, 0);
572 while(fgets(buf
, sizeof(buf
), fwireless
)) {
573 r
= sscanf(buf
, "%s %d %d ", a
, &b
, &c
);
574 if(strchr(a
, ':')) *(strchr(a
, ':')) = 0;
575 if(strcmp(a
, parent
) == 0) {
581 #ifdef ENABLE_NWN_SUPPORT
582 info
->sl
= nwn_get_link(parent
);
584 #elif defined(__OpenBSD__)
589 wreq
.wi_len
= WI_MAX_DATALEN
;
590 wreq
.wi_type
= WI_RID_COMMS_QUALITY
;
592 strlcpy(ifr
.ifr_name
, ifname
, sizeof(ifr
.ifr_name
));
593 ifr
.ifr_data
= (caddr_t
)&wreq
;
595 if (ioctl(fd
, SIOCGWAVELAN
, &ifr
) != -1)
596 info
->sl
= letoh16(wreq
.wi_val
[0]);
600 // Get Total tx/rx bytes
606 while(fgets(buf
, sizeof(buf
), fdev
)) {
607 r
= sscanf(buf
, "%s %d %d %d %d %d %d %d %d %d", a
, &b
, &d
,&d
,&d
,&d
,&d
,&d
,&d
, &c
);
608 if(strchr(a
, ':')) *(strchr(a
, ':')) = 0;
609 if(strcmp(a
, parent
) == 0) {
620 void addifname(char *name
)
624 if(strcmp(name
, "lo") == 0) return;
625 if(strncmp(name
, "vlan", 4) == 0) return;
627 for(i
=0; i
<ifaces
; i
++) {
628 if(strcmp(ifname
[i
], name
) == 0) return;
631 strcpy(ifname
[ifaces
], name
);
633 if(strcasecmp(name
, startif
) == 0) {
645 * get list of interfaces. First read /proc/net/dev, then do a SIOCGIFCONF
648 void getifnames(void)
659 f
= fopen("/proc/net/dev", "r");
662 fprintf(stderr
, "Can't open /proc/net/dev\n");
666 fgets(buf
, sizeof(buf
),f
);
667 while(fgets(buf
, sizeof(buf
), f
)) {
669 while(*p1
== ' ') p1
++;
671 while(*p2
&& (*p2
!= ':')) p2
++;
680 ifc
.ifc_len
= sizeof(struct ifreq
) * 10;
682 if(ioctl(fd
, SIOCGIFCONF
, &ifc
) == -1) {
683 fprintf(stderr
, "SIOCGIFCONF : Can't get list of interfaces : %s\n", strerror(errno
));
687 ifcount
= ifc
.ifc_len
/ sizeof(struct ifreq
);
689 for(i
=0; i
<ifcount
; i
++) {
690 addifname(ifc
.ifc_req
[i
].ifr_name
);
692 #elif defined(__OpenBSD__)
693 struct ifreq ibuf
[32];
695 struct ifreq
*ifrp
, *ifend
;
700 ifc
.ifc_len
= sizeof(ibuf
);
701 ifc
.ifc_buf
= (caddr_t
) ibuf
;
702 if (ioctl(fd
, SIOCGIFCONF
, (char *) &ifc
) == -1 ||
703 ifc
.ifc_len
< sizeof(struct ifreq
)) {
704 fprintf(stderr
, "SIOCGIFCONF : Can't get list of interfaces : %s\n", strerror(errno
));
707 /* Search interface configuration list for link layer address. */
709 ifend
= (struct ifreq
*) ((char *) ibuf
+ ifc
.ifc_len
);
710 while (ifrp
< ifend
) {
711 if (ifrp
->ifr_addr
.sa_family
== AF_LINK
&&
712 ((struct sockaddr_dl
*) &ifrp
->ifr_addr
)->sdl_type
== IFT_ETHER
) {
713 addifname(ifrp
->ifr_name
);
715 /* Bump interface config pointer */
716 r
= ifrp
->ifr_addr
.sa_len
+ sizeof(ifrp
->ifr_name
);
717 if (r
< sizeof(*ifrp
))
719 ifrp
= (struct ifreq
*) ((char *) ifrp
+ r
);