?? utils.c
字號(hào):
/* Kernel AODV v2.1National Institute of Standards and Technology Luke Klein-Berndt----------------------------------------------------- Version 2.1 new features: * Much more stable! * Added locks around important areas * Multihop Internet gatewaying now works * Multicast hack added * Many bug fixes!-----------------------------------------------------Originally based upon MadHoc code. I am notsure how much of it is left anymore, but MadHocproved to be a great starting point.MadHoc was written by - Fredrik Lilieblad,Oskar Mattsson, Petra Nylund, Dan Ouchterlonyand Anders Roxenhag Mail: mad-hoc@flyinglinux.netThis software is Open Source under the GNU General Public Licence.*/#include "utils.h"/**************************************************** utils.h----------------------------------------------------Contains many misc funcations that providebasic functionality.****************************************************/extern u_int32_t g_broadcast_ip;extern u_int32_t g_my_ip;extern struct route_table_entry *g_my_entry;static struct sockaddr_in sin; //the port we are sending from#ifdef AODV_MULTICASTstatic struct socket *multicast_sock;#endif#ifdef AODV_SIGNALstatic struct socket *iw_sock;#endif/**************************************************** init_sock----------------------------------------------------Creates a socket for sending out data****************************************************/#ifdef AODV_MULTICASTint init_multicast_sock(void){ int error; struct ifreq interface; mm_segment_t oldfs; int bool=1; char loop=0; char ttl; int choice=1; error=sock_create(PF_INET, SOCK_RAW, IPPROTO_RAW, &(multicast_sock)); memset(&sin,0,sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr=g_my_ip; sin.sin_port = htons(AODVPORT); multicast_sock->sk->reuse =1; multicast_sock->sk->allocation = GFP_ATOMIC; multicast_sock->sk->priority = GFP_ATOMIC; error = multicast_sock->ops->bind(multicast_sock,(struct sockaddr*)&sin,sizeof(struct sockaddr_in)); /* #ifdef ARM strncpy(interface.ifr_ifrn.ifrn_name, "eth0", IFNAMSIZ);#else strncpy(interface.ifr_ifrn.ifrn_name, "eth1", IFNAMSIZ);#endif */ if (g_my_entry) strncpy(interface.ifr_ifrn.ifrn_name, g_my_entry->dev->name, IFNAMSIZ); else strncpy(interface.ifr_ifrn.ifrn_name, "eth0", IFNAMSIZ); oldfs = get_fs(); set_fs(get_ds()); // error=sys_fcntl(&(multicast_sock->sk),F_SETFL,O_NONBLOCK); //printk("error: %d\n",error); if (sock_setsockopt(multicast_sock,IPPROTO_IP,SO_BINDTODEVICE, (char *) &interface, sizeof(interface))<0) { printk(KERN_WARNING " Couldn't bind to route!\n"); } if ((error=sock_setsockopt(multicast_sock,IPPROTO_IP,SO_DONTROUTE,(char *) &choice, sizeof(int)))<0) { printk(KERN_WARNING " Couldn't mark not to route! %d\n",error); } if (error<0) { printk(KERN_ERR "Kernel AODV: Error, %d binding socket. This means that some other \n",error); printk(KERN_ERR " daemon is (or was a short time axgo) using port %i.\n",AODVPORT); return 0; } if((error =multicast_sock->ops->setsockopt(multicast_sock, IPPROTO_IP, IP_HDRINCL, (char *)&bool, sizeof(bool)))<0) { printk(KERN_WARNING "Error: %d In init_sock... I have problem in setting the multicast socket to have the IP hdr (%d) ...\n", error, bool); } /* //Set the interface on which the multicast packets will be sent if((error=sock->ops->setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, (char *)& ip, sizeof(ip)))<0) { printk("Error: %d In init_sock... I have a problem setting the interface on which the multicast packets leave...\n", error); } if((error=sock->ops->setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&loop, sizeof(loop)))<0) { printk("Error: %d In init_sock...I have a problem in unsetting the LOOP_BACK for the multicast packets...\n", error); } */ set_fs(oldfs); return 0;}#endifint init_sock(struct socket *sock, u_int32_t ip, char *dev_name){ int error; struct ifreq interface; mm_segment_t oldfs; //set the address we are sending from memset(&sin,0,sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr=ip; sin.sin_port = htons(AODVPORT); sock->sk->reuse =1; sock->sk->allocation = GFP_ATOMIC; sock->sk->priority = GFP_ATOMIC; error = sock->ops->bind(sock,(struct sockaddr*)&sin,sizeof(struct sockaddr_in)); strncpy(interface.ifr_ifrn.ifrn_name,dev_name,IFNAMSIZ); oldfs = get_fs(); set_fs(KERNEL_DS); //thank to Soyeon Anh and Dinesh Dharmaraju for spotting this bug! error=sock_setsockopt(sock,SOL_SOCKET,SO_BINDTODEVICE, (char *) &interface, sizeof(interface))<0; set_fs(oldfs); if (error<0) { printk(KERN_ERR "Kernel AODV: Error, %d binding socket. This means that some other \n",error); printk(KERN_ERR " daemon is (or was a short time axgo) using port %i.\n",AODVPORT); return 0; } return 0;}/**************************************************** close_sock----------------------------------------------------Closes the socket****************************************************/void close_sock(void){ struct interface_list_entry *tmp_interface,*dead_interface;#ifdef AODV_MULTICAST sock_release(multicast_sock);#endif tmp_interface=find_first_interface_entry(); while(tmp_interface!=NULL) { sock_release(tmp_interface->sock); dead_interface=tmp_interface; tmp_interface=tmp_interface->next; kfree(dead_interface); }}#ifdef AODV_SIGNALvoid init_iw_sock(void){ int error; error = sock_create(AF_INET,SOCK_DGRAM,0,&iw_sock); if (error<0) { printk(KERN_ERR "Error during creation of socket; terminating, %d\n",error); }}void close_iw_sock(void){ sock_release(iw_sock);}#endif#ifdef AODV_SIGNALint set_spy(){ int errno; int i; int nbr; /* Number of valid addresses */ mm_segment_t oldfs; struct neighbor_list_entry *tmp_neigh; struct interface_list_entry *tmp_interface; struct sockaddr iw_sa[IW_MAX_SPY]; struct iwreq wrq; unsigned char *ucp; tmp_interface=find_first_interface_entry(); while (tmp_interface!=NULL) { if ((tmp_interface->dev->get_wireless_stats!=NULL) && (tmp_interface->dev->do_ioctl!=NULL)) { i=0; tmp_neigh=find_first_neighbor_list_entry(); while (tmp_neigh!=NULL) { //ucp=(unsigned char *)&(tmp_neigh->ip); if ((tmp_interface->dev==tmp_neigh->dev))// && (((ucp[3] & 0xff)<111) &&((ucp[3] & 0xff)>100) )) { if ( i<IW_MAX_SPY) { memcpy((char *) &(iw_sa[i].sa_data), (char *) &(tmp_neigh->hw_addr),sizeof(struct sockaddr)); i++; tmp_neigh->link=255; } /* else { update_link_by_hw(tmp_neigh->hw_addr,255); tmp_neigh->link=255; }*/ } tmp_neigh=tmp_neigh->next; } strncpy(wrq.ifr_name, tmp_interface->dev->name, IFNAMSIZ); wrq.u.data.pointer = (caddr_t) &(iw_sa); wrq.u.data.length = i; wrq.u.data.flags = 0; oldfs = get_fs(); set_fs(KERNEL_DS); errno=tmp_interface->dev->do_ioctl(tmp_interface->dev, (struct ifreq * ) &wrq,SIOCSIWSPY); set_fs(oldfs); if (errno<0) printk(KERN_WARNING "AODV: Error with SIOCSIWSPY: %d\n", errno); } tmp_interface=tmp_interface->next; }}int get_range_info(struct net_device *dev,char * ifname, struct iw_range * range){ struct iwreq wrq; char buffer[sizeof(struct iw_range) * 2]; /* Large enough */ /* Cleanup */ memset(buffer, 0, sizeof(range)); strcpy(wrq.ifr_name, ifname); wrq.u.data.pointer = (caddr_t) buffer; wrq.u.data.length = 0; wrq.u.data.flags = 0; if(dev->do_ioctl(dev, (struct ifreq * ) &wrq,SIOCGIWRANGE) < 0) return(-1); /* Copy stuff at the right place, ignore extra */ memcpy((char *) range, buffer, sizeof(struct iw_range)); return(0);}void get_wireless_stats(){ int n,i,has_range=0; char buffer[(sizeof(struct iw_quality) + sizeof(struct sockaddr)) * IW_MAX_SPY]; u_int8_t temp; struct iwreq wrq; struct neighbor_list_entry *tmp_neigh; struct interface_list_entry *tmp_interface; struct sockaddr hwa[IW_MAX_SPY]; struct iw_quality qual[IW_MAX_SPY]; struct iw_range range; tmp_interface=find_first_interface_entry(); while (tmp_interface!=NULL) { if ((tmp_interface->dev->get_wireless_stats!=NULL) && (tmp_interface->dev->do_ioctl!=NULL)) { strncpy(wrq.ifr_name,tmp_interface->dev->name , IFNAMSIZ); wrq.u.data.pointer = (caddr_t) buffer; wrq.u.data.length = 0; wrq.u.data.flags = 0; tmp_interface->dev->do_ioctl(tmp_interface->dev,(struct ifreq * ) &wrq,SIOCGIWSPY ); if(get_range_info(tmp_interface->dev, tmp_interface->dev->name , &(range)) >= 0) { has_range = 1; } n = wrq.u.data.length; memcpy(hwa, buffer, n * sizeof(struct sockaddr)); memcpy(qual, buffer + n*sizeof(struct sockaddr), n*sizeof(struct iw_quality)); for(i = 0; i < n; i++) { if(has_range && (qual[i].level != 0)) { if (range.max_qual.qual!=0) { update_link_by_hw(hwa[i].sa_data,qual[i].level); } } else { update_link_by_hw(hwa[i].sa_data,qual[i].level); } } } tmp_interface=tmp_interface->next; }}int read_signal_proc(char *buffer, char **buffer_location, off_t offset, int buffer_length,int *eof,void *data){ static char *my_buffer; char temp_buffer[200]; struct neighbor_list_entry *tmp_entry; int len; char dst[16]; int n,i; char stats_buffer[(sizeof(struct iw_quality) + sizeof(struct sockaddr)) * IW_MAX_SPY]; struct iwreq wrq; struct interface_list_entry *tmp_interface; struct sockaddr *hwa; struct iw_quality *qual; mm_segment_t oldfs; // struct sockaddr hwa[IW_MAX_SPY]; //struct iw_quality qual[IW_MAX_SPY]; my_buffer=buffer; strcpy(my_buffer,""); tmp_interface=find_first_interface_entry(); //reset_route_table_link(); while (tmp_interface!=NULL) { if ((tmp_interface->dev->get_wireless_stats!=NULL) && (tmp_interface->dev->do_ioctl!=NULL)) { strncpy(wrq.ifr_name,tmp_interface->dev->name , IFNAMSIZ); wrq.u.data.pointer = (caddr_t) stats_buffer; wrq.u.data.length = 64; //IW_MAX_GET_SPY; wrq.u.data.flags = 0; oldfs = get_fs(); set_fs(KERNEL_DS); tmp_interface->dev->do_ioctl(tmp_interface->dev,(struct ifreq * ) &wrq,SIOCGIWSPY ); set_fs(oldfs); n = wrq.u.data.length; hwa = (struct sockaddr *) stats_buffer; qual = (struct iw_quality *) (stats_buffer + (sizeof(struct sockaddr) * n)); for(i = 0; i < n; i++) { //printk ("%u %d\n",hwa[i].sa_data,qual[i].level - 0x100); //update_link_by_hw(hwa[i].sa_data,qual[i].level); tmp_entry= find_neighbor_list_entry_by_hw(hwa[i].sa_data); if(tmp_entry!=NULL) { strcpy(dst,inet_ntoa(tmp_entry->ip)); sprintf(temp_buffer,"1 %s, %d \n",dst ,qual[i].level - 0x100); strcat(my_buffer,temp_buffer); } } } tmp_interface=tmp_interface->next; } len = strlen(my_buffer); *buffer_location = my_buffer + offset; len -= offset; if (len > buffer_length) len = buffer_length; else if (len < 0) len = 0; return len;}#endif
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -