/* Code style: -*- linux-c -*- */ /* File : xfw/find/if_change.c */ /* This is to open the *default* interface for promiscious reading of teh network */ #include #include #include #include #include #include #include #include /* description of ethernet packets */ #include "range.h" struct node * if_setup(void) { /* the aim here is to : a) reset the ethernet interface to be in promiscious mode b) read out the ip address of the interface c) read out the netmask address of the interface d) read out the broadcast address of the interface e) return all this info in a structure we can use elsewhere */ struct node *local_if; struct ifreq ifr, oldifr; int sd; int ip, netmask, broadcast; /* OPEN SOCKET (ETH_P_ALL definition from ) */ if ((sd = socket (AF_INET, SOCK_RAW, htons (ETH_P_ALL))) < 0) { perror ("Init_if: Can't get socket:"); exit (1); } /* SET PROMISC note "eth0" is a hard coded value */ strcpy (oldifr.ifr_name, "eth0"); if (ioctl (sd, SIOCGIFFLAGS, &oldifr) < 0) { close (sd); perror ("Can't get flags: "); exit (1); } /* Should this be rewritten to cooperate with other net tools? */ ifr = oldifr; ifr.ifr_flags |= IFF_PROMISC; /* bitwise OR */ if (ioctl (sd, SIOCSIFFLAGS, &ifr) < 0) { close (sd); perror ("Can't set flags: "); exit (1); } /* WHILE WE ARE AT IT GET THE IF DETAILS */ /* (it's extremely annoying that we have to make 3 calls but thats life) */ /* and to top it all off each of the following aparently 'corrupt' the various */ /* other fields between calls hense the need for the routine dig_out_ip*/ /* interface address */ if (ioctl (sd, SIOCGIFADDR, &ifr) < 0) { close (sd); perror ("Can't get address of interface: "); exit (1); } ip = dig_out_ip((unsigned char *)ifr.ifr_addr.sa_data); /* interface netmask */ if (ioctl (sd, SIOCGIFNETMASK, &ifr) < 0) { close (sd); perror ("Can't get netmask: "); exit (1); } netmask = dig_out_ip((unsigned char *)ifr.ifr_netmask.sa_data); /* interface broadcast */ if (ioctl (sd, SIOCGIFBRDADDR, &ifr) < 0) { close (sd); perror ("Can't get broadcast: "); exit (1); } broadcast = dig_out_ip((unsigned char *)ifr.ifr_broadaddr.sa_data); /* and now repackage the information in the net_atrtib structure */ local_if = (struct node *) calloc(1, sizeof(struct net_attrib)); local_if->ip = ip; local_if->netmask = netmask; local_if->broadcast = broadcast; return(local_if); } int 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 (encode_ip(buffer)); } .