/* Code style: -*- linux-c -*- */ /* File : xfw/add_specials.c */ #include #include #include #include #include #include #include "xfw.h" #define TRUE 1 #define FALSE 0 static int filter(FL_OBJECT * ob, const char *s, const char *new, int c) { static char test[1]; static int ok; ok = TRUE; test[0] = c; /* ok I admit it's a hack and nasty, but it works */ test[1] = 0; /* safety first! */ if (strspn(test, "0123456789. /") > 0) { /* ok so far so good, it's one of the above */ /* now then maximum of one space and one / oh, and 4 '.'s */ if (special_count(new, 46) > 3) ok = FALSE; if (special_count(new, 47) > 1) ok = FALSE; if (special_count(new, 32) > 1) ok = FALSE; if (ok == TRUE) { return(FL_VALID); } else { return(!FL_VALID); } } else { return (!FL_VALID); } } int special_count(const char *string, int cval) { int loop=0, tally=0; for (loop=0; loop < strlen(string); loop++) if (string[loop] == cval) tally++; return (tally); } void add_specials(void) { /* all we wish to do here is to add characteristics to various parts of the form */ /* input fields return on each charater press */ fl_set_input_return(src_in, FL_RETURN_ALWAYS); fl_set_input_return(dest_in, FL_RETURN_ALWAYS); /* oh, and we only want certain characters in the field "0 1 2 3 4 5 6 7 8 9 / < > ." */ /* add filters */ fl_set_input_filter(src_in, filter); fl_set_input_filter(dest_in, filter); /* now then, we also want the choice objects to have actual menu items */ fl_addto_choice(type_in, "accept|reject|deny|masq"); fl_addto_choice(prot_in, "all|tcp|udp|icmp"); fl_addto_choice(opt_in, "----|---o|--y-|--yo|-k--|"); fl_addto_choice(opt_in, "-k-o|-ky-|-kyo|b---|b--o|"); fl_addto_choice(opt_in, "b-y-|b-yo|bk--|bk-o|bkyo"); /* ifname_in needs to be read from the kernel, easiest approach is to read */ /* /proc/net/dev and /proc/net/aliases */ /* oh, and while we're in there, add some stuff to ifaddr */ add_interfaces(); /* and now add in some shortcuts */ fl_set_button_shortcut(add, "#a", TRUE); fl_set_button_shortcut(replace, "#r", TRUE); fl_set_button_shortcut(append, "#p", TRUE); fl_set_button_shortcut(save, "#s", TRUE); fl_set_button_shortcut(load, "#l", TRUE); fl_set_button_shortcut(delete, "#d", TRUE); fl_set_button_shortcut(quit, "#x", TRUE); /* I suppose we ought to start off with accounting being active */ fl_set_button(accounting, TRUE); /* and better stick in a default for the ifaddr and a few others */ fl_set_input(src_in, "127.0.0.1/24"); fl_set_input(dest_in, "127.0.0.1/24"); fl_set_input(tosa_in, "0xFF"); fl_set_input(tosx_in, "0x00"); /* oh yes, I also have to setup the browsers to NOT have scroll bars */ fl_set_browser_vscrollbar(disp_pkts, FL_OFF); fl_set_browser_vscrollbar(disp_bytes, FL_OFF); fl_set_browser_vscrollbar(disp_type, FL_OFF); fl_set_browser_vscrollbar(disp_prot, FL_OFF); fl_set_browser_vscrollbar(disp_opt, FL_OFF); fl_set_browser_vscrollbar(disp_tosa, FL_OFF); fl_set_browser_vscrollbar(disp_tosx, FL_OFF); fl_set_browser_vscrollbar(disp_ifname, FL_OFF); fl_set_browser_vscrollbar(disp_ifaddr, FL_OFF); fl_set_browser_vscrollbar(disp_source, FL_OFF); fl_set_browser_vscrollbar(disp_dest, FL_ON); } void add_interfaces(void) { FILE *devs; char s[100]="", interf[10]; int loop=0, pos=0; /* ok open up /proc/net/dev */ /* Alan, it would be *REALLY* nice to have a system call that returns */ /* a structure containg the list of currently used interfaces */ /* THIS IS FAIRLY DIRTY CODE */ /* straight off add 0.0.0.0 to ifaddr */ fl_addto_choice(ifaddr_in,"All - 0.0.0.0"); devs = fopen("/proc/net/dev", "r"); if (devs != NULL) { /* skip the top two lines */ fgets(s, 100, devs); fgets(s, 100, devs); /* ok read in the interfaces and add then to the choices list */ while ( fgets(s,100,devs) != NULL) { /* ok looks like I'll have to trim the line */ for (loop = 0; loop< 10; loop++) if ((s[loop]==58) && (s[loop+1] == 32)) s[loop] = 0; /* terminate the sucker */ /* brilliant! we have the interfaces! now trim off */ /* the leading whitespace */ for (loop = 0, pos=0; loop < strlen(s) ; loop++) { if (s[loop]!= 32) interf[pos++] = s[loop]; } interf[pos++]=0; /* terminate it */ fl_addto_choice(ifname_in, interf); /* it would be good to find out that ip is associated with this interface */ fetch_ip(interf); } fclose (devs); } return; } void fetch_ip(char *interface) { struct ifreq ifr; int sd; strcpy (ifr.ifr_name, interface); /* interface address */ sd = socket(AF_INET, SOCK_DGRAM, 0); /* open a socket so we can start asking questions */ if (ioctl (sd, SIOCGIFADDR, &ifr) < 0) { close (sd); perror ("Can't get address of interface: "); exit (1); } close (sd); /* we don't need this anymore */ fl_addto_choice(ifaddr_in, dig_out_ip((unsigned char *)ifr.ifr_addr.sa_data)); } char * dig_out_ip(const unsigned char *ip) { /* *Sigh* where the hell was the nice fuction to get this? */ /* the structure holds 14 bytes which is all well and nice */ /* but no convient syscall to get *JUST* the ip */ static char buffer[20]=""; /* not the worlds neatest way of doing things, magic numbers time */ sprintf(buffer, "%d.%d.%d.%d", ip[2], ip[3], ip[4], ip[5]); return (buffer); } .