utils.c

説明を見る。
00001 /*
00002                Kernel AODV  v2.1
00003 National Institute of Standards and Technology
00004                Luke Klein-Berndt
00005 -----------------------------------------------------
00006   Version 2.1 new features:
00007      * Much more stable!
00008      * Added locks around important areas
00009      * Multihop Internet gatewaying now works
00010      * Multicast hack added
00011      * Many bug fixes!
00012 -----------------------------------------------------
00013 
00014 Originally based upon MadHoc code. I am not
00015 sure how much of it is left anymore, but MadHoc
00016 proved to be a great starting point.
00017 
00018 MadHoc was written by - Fredrik Lilieblad,
00019 Oskar Mattsson, Petra Nylund, Dan Ouchterlony
00020 and Anders Roxenhag Mail: mad-hoc@flyinglinux.net
00021 
00022 This software is Open Source under the GNU General Public Licence.
00023 
00024 */
00025 
00026 #include "utils.h"
00027 
00028 /****************************************************
00029 
00030    utils.h
00031 ----------------------------------------------------
00032 Contains many misc funcations that provide
00033 basic functionality.
00034 ****************************************************/
00035 
00036 extern u_int32_t g_broadcast_ip;
00037 extern u_int32_t g_my_ip;
00038 extern struct route_table_entry *g_my_entry;
00039 
00040 static struct sockaddr_in sin; //the port we are sending from
00041 
00042 #ifdef AODV_MULTICAST
00043 static struct socket *multicast_sock;
00044 #endif
00045 
00046 #ifdef AODV_SIGNAL
00047 static struct socket *iw_sock;
00048 #endif
00049 
00050 /****************************************************
00051 
00052    init_sock
00053 ----------------------------------------------------
00054 Creates a socket for sending out data
00055 ****************************************************/
00056 
00057 
00058 #ifdef AODV_MULTICAST
00059 int init_multicast_sock(void)
00060 {
00061   
00062   int error;
00063   struct ifreq interface;
00064   mm_segment_t oldfs;
00065   int bool=1;
00066   char loop=0;
00067   char ttl;
00068   int choice=1;
00069   
00070   
00071         
00072   error=sock_create(PF_INET, SOCK_RAW, IPPROTO_RAW, &(multicast_sock));
00073   
00074   
00075   memset(&sin,0,sizeof(sin));
00076   sin.sin_family = AF_INET;
00077   sin.sin_addr.s_addr=g_my_ip;
00078   sin.sin_port         = htons(AODVPORT);
00079   
00080   multicast_sock->sk->reuse =1;
00081   multicast_sock->sk->allocation = GFP_ATOMIC;
00082   multicast_sock->sk->priority = GFP_ATOMIC;
00083   
00084   error = multicast_sock->ops->bind(multicast_sock,(struct sockaddr*)&sin,sizeof(struct sockaddr_in));
00085 
00086   
00087 
00088 
00089   /*  
00090 #ifdef ARM
00091         strncpy(interface.ifr_ifrn.ifrn_name, "eth0", IFNAMSIZ);
00092 #else
00093         strncpy(interface.ifr_ifrn.ifrn_name, "eth1", IFNAMSIZ);
00094 #endif
00095   */
00096   if (g_my_entry)
00097     strncpy(interface.ifr_ifrn.ifrn_name, g_my_entry->dev->name, IFNAMSIZ);
00098   else
00099     strncpy(interface.ifr_ifrn.ifrn_name, "eth0", IFNAMSIZ);
00100 
00101   oldfs = get_fs();
00102   set_fs(get_ds());
00103 
00104   //    error=sys_fcntl(&(multicast_sock->sk),F_SETFL,O_NONBLOCK);
00105   //printk("error: %d\n",error);
00106 
00107   if (sock_setsockopt(multicast_sock,IPPROTO_IP,SO_BINDTODEVICE, (char *) &interface, sizeof(interface))<0)
00108     {
00109       printk(KERN_WARNING " Couldn't bind to route!\n"); 
00110     }
00111 
00112   if ((error=sock_setsockopt(multicast_sock,IPPROTO_IP,SO_DONTROUTE,(char *) &choice, sizeof(int)))<0)
00113     {
00114       printk(KERN_WARNING " Couldn't mark not to route! %d\n",error); 
00115     }
00116   
00117   if (error<0)
00118     {
00119       printk(KERN_ERR "Kernel AODV: Error, %d  binding socket. This means that some other \n",error);
00120       printk(KERN_ERR "        daemon is (or was a short time axgo) using port %i.\n",AODVPORT);
00121       return 0;
00122     }
00123   
00124   if((error =multicast_sock->ops->setsockopt(multicast_sock, IPPROTO_IP, IP_HDRINCL, (char *)&bool, sizeof(bool)))<0)
00125     {
00126       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);
00127       
00128     }
00129   /*
00130 
00131   //Set the interface on which the multicast packets will be sent
00132   if((error=sock->ops->setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, (char *)& ip, sizeof(ip)))<0)
00133   {
00134   printk("Error: %d In init_sock... I have a problem setting the interface on which the multicast packets leave...\n", error);
00135   }
00136   
00137   if((error=sock->ops->setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&loop, sizeof(loop)))<0)
00138   {
00139   printk("Error: %d In init_sock...I have a problem in unsetting the LOOP_BACK for the multicast packets...\n", error);
00140   
00141         }
00142         
00143   */
00144         
00145   set_fs(oldfs);
00146   return 0;
00147 }
00148 
00149 #endif
00150 
00151 int init_sock(struct socket *sock, u_int32_t ip, char *dev_name)
00152 {
00153 
00154     int error;
00155     struct ifreq interface;
00156     mm_segment_t oldfs;
00157 
00158     //set the address we are sending from
00159     memset(&sin,0,sizeof(sin));
00160     sin.sin_family = AF_INET;
00161     sin.sin_addr.s_addr=ip;
00162     sin.sin_port         = htons(AODVPORT);
00163 
00164     sock->sk->reuse =1;
00165     sock->sk->allocation = GFP_ATOMIC;
00166     sock->sk->priority = GFP_ATOMIC;
00167 
00168     error = sock->ops->bind(sock,(struct sockaddr*)&sin,sizeof(struct sockaddr_in));
00169     strncpy(interface.ifr_ifrn.ifrn_name,dev_name,IFNAMSIZ);
00170 
00171     oldfs = get_fs();
00172     set_fs(KERNEL_DS); //thank to Soyeon Anh and Dinesh Dharmaraju for spotting this bug!
00173     error=sock_setsockopt(sock,SOL_SOCKET,SO_BINDTODEVICE, (char *) &interface, sizeof(interface))<0;
00174     set_fs(oldfs);
00175     
00176 
00177     
00178     if (error<0)
00179     {
00180       printk(KERN_ERR "Kernel AODV: Error, %d  binding socket. This means that some other \n",error);
00181       printk(KERN_ERR "        daemon is (or was a short time axgo) using port %i.\n",AODVPORT);
00182       return 0;
00183     }
00184     
00185     return 0;
00186 }
00187 
00188 /****************************************************
00189 
00190    close_sock
00191 ----------------------------------------------------
00192 Closes the socket
00193 ****************************************************/
00194 void close_sock(void)
00195 {
00196     struct interface_list_entry *tmp_interface,*dead_interface;
00197 
00198 #ifdef AODV_MULTICAST
00199     sock_release(multicast_sock);
00200 #endif
00201 
00202     tmp_interface=find_first_interface_entry();
00203     while(tmp_interface!=NULL)
00204     {
00205         sock_release(tmp_interface->sock);
00206         dead_interface=tmp_interface;
00207         tmp_interface=tmp_interface->next;
00208         kfree(dead_interface);
00209     }
00210 }
00211 
00212 
00213 #ifdef AODV_SIGNAL
00214 void init_iw_sock(void)
00215 {
00216     int error;
00217 
00218     error = sock_create(AF_INET,SOCK_DGRAM,0,&iw_sock);
00219     if (error<0)
00220       {
00221         printk(KERN_ERR "Error during creation of socket; terminating, %d\n",error);
00222 
00223     }
00224 }
00225 
00226 
00227 void close_iw_sock(void)
00228 {
00229     sock_release(iw_sock);
00230 }
00231 #endif
00232 
00233 
00234 #ifdef AODV_SIGNAL
00235 int set_spy()
00236 {
00237     int errno;
00238     int                 i;
00239     int                 nbr;            /* Number of valid addresses */
00240     mm_segment_t oldfs;
00241     struct neighbor_list_entry *tmp_neigh;
00242     struct interface_list_entry *tmp_interface;
00243     struct sockaddr iw_sa[IW_MAX_SPY];
00244     struct iwreq                wrq;
00245     unsigned char *ucp;
00246 
00247     tmp_interface=find_first_interface_entry();
00248 
00249     while (tmp_interface!=NULL)
00250       {
00251         
00252         if ((tmp_interface->dev->get_wireless_stats!=NULL) && (tmp_interface->dev->do_ioctl!=NULL))
00253         {
00254           i=0;
00255           
00256           tmp_neigh=find_first_neighbor_list_entry();
00257           
00258           while (tmp_neigh!=NULL) 
00259             {
00260               
00261               //ucp=(unsigned char *)&(tmp_neigh->ip);
00262               
00263               if ((tmp_interface->dev==tmp_neigh->dev))// && (((ucp[3] & 0xff)<111) &&((ucp[3] & 0xff)>100)  ))
00264                 {
00265                   if ( i<IW_MAX_SPY)
00266                     {
00267                       memcpy((char *) &(iw_sa[i].sa_data), (char *) &(tmp_neigh->hw_addr),sizeof(struct sockaddr));
00268                       i++;
00269                       tmp_neigh->link=255;
00270                     }
00271                   /*  else
00272                       {
00273                       update_link_by_hw(tmp_neigh->hw_addr,255);
00274                       tmp_neigh->link=255;
00275                       }*/
00276                   
00277                 }
00278 
00279                 tmp_neigh=tmp_neigh->next;
00280             }
00281 
00282             strncpy(wrq.ifr_name, tmp_interface->dev->name, IFNAMSIZ);
00283             wrq.u.data.pointer = (caddr_t) &(iw_sa);
00284             wrq.u.data.length = i;
00285             wrq.u.data.flags = 0;
00286 
00287 
00288 
00289             oldfs = get_fs();
00290             set_fs(KERNEL_DS);
00291             errno=tmp_interface->dev->do_ioctl(tmp_interface->dev, (struct ifreq * ) &wrq,SIOCSIWSPY);
00292             set_fs(oldfs);
00293 
00294             if (errno<0)
00295                 printk(KERN_WARNING "AODV: Error with SIOCSIWSPY: %d\n", errno);
00296 
00297 
00298         }
00299         tmp_interface=tmp_interface->next;
00300 
00301     }
00302 }
00303 
00304 
00305 int get_range_info(struct net_device *dev,char *                ifname, struct iw_range *       range)
00306 {
00307     struct iwreq                wrq;
00308     char                        buffer[sizeof(struct iw_range) * 2];    /* Large enough */
00309 
00310     /* Cleanup */
00311     memset(buffer, 0, sizeof(range));
00312     strcpy(wrq.ifr_name, ifname);
00313     wrq.u.data.pointer = (caddr_t) buffer;
00314     wrq.u.data.length = 0;
00315     wrq.u.data.flags = 0;
00316 
00317     if(dev->do_ioctl(dev, (struct ifreq * ) &wrq,SIOCGIWRANGE) < 0)
00318         return(-1);
00319 
00320     /* Copy stuff at the right place, ignore extra */
00321     memcpy((char *) range, buffer, sizeof(struct iw_range));
00322 
00323     return(0);
00324 }
00325 
00326 
00327 void get_wireless_stats()
00328 {
00329     int n,i,has_range=0;
00330     char                buffer[(sizeof(struct iw_quality) +     sizeof(struct sockaddr)) * IW_MAX_SPY];
00331     u_int8_t temp;
00332 
00333     struct iwreq                wrq;
00334     struct neighbor_list_entry *tmp_neigh;
00335     struct interface_list_entry *tmp_interface;
00336     struct sockaddr     hwa[IW_MAX_SPY];
00337     struct iw_quality   qual[IW_MAX_SPY];
00338     struct iw_range     range;
00339 
00340 
00341     tmp_interface=find_first_interface_entry();
00342 
00343 
00344     while (tmp_interface!=NULL)
00345     {
00346 
00347         if ((tmp_interface->dev->get_wireless_stats!=NULL) && (tmp_interface->dev->do_ioctl!=NULL))
00348         {
00349             strncpy(wrq.ifr_name,tmp_interface->dev->name , IFNAMSIZ);
00350             wrq.u.data.pointer = (caddr_t) buffer;
00351             wrq.u.data.length = 0;
00352             wrq.u.data.flags = 0;
00353 
00354             tmp_interface->dev->do_ioctl(tmp_interface->dev,(struct ifreq * ) &wrq,SIOCGIWSPY );
00355 
00356 
00357             if(get_range_info(tmp_interface->dev, tmp_interface->dev->name , &(range)) >= 0)
00358               {
00359                 has_range = 1;
00360               }
00361             n = wrq.u.data.length;
00362 
00363             memcpy(hwa, buffer, n * sizeof(struct sockaddr));
00364             memcpy(qual, buffer + n*sizeof(struct sockaddr), n*sizeof(struct iw_quality));
00365 
00366             for(i = 0; i < n; i++)
00367             {
00368                 if(has_range && (qual[i].level != 0))
00369                 {
00370                     if (range.max_qual.qual!=0)
00371                     {
00372 
00373                         update_link_by_hw(hwa[i].sa_data,qual[i].level);
00374                         
00375                     }
00376                 }
00377                 else
00378                 {
00379                     update_link_by_hw(hwa[i].sa_data,qual[i].level);
00380                 }
00381 
00382         
00383             }
00384         }
00385         tmp_interface=tmp_interface->next;
00386     }
00387 }
00388 
00389 
00390 
00391 
00392 
00393 
00394 int read_signal_proc(char *buffer, char **buffer_location, off_t offset, int buffer_length,int *eof,void *data)
00395 {
00396 
00397     static char *my_buffer;
00398     char temp_buffer[200];
00399     struct neighbor_list_entry *tmp_entry;
00400     int len;
00401     char dst[16];
00402 
00403     int n,i;
00404     char  stats_buffer[(sizeof(struct iw_quality) +     sizeof(struct sockaddr)) * IW_MAX_SPY];
00405 
00406     struct iwreq                wrq;
00407     struct interface_list_entry *tmp_interface;
00408     struct sockaddr *hwa;
00409     struct iw_quality *qual;
00410     mm_segment_t oldfs;
00411 
00412     //    struct sockaddr       hwa[IW_MAX_SPY];
00413     //struct iw_quality         qual[IW_MAX_SPY];
00414 
00415 
00416 
00417     my_buffer=buffer;
00418 
00419     strcpy(my_buffer,"");
00420 
00421     tmp_interface=find_first_interface_entry();
00422 
00423     //reset_route_table_link();
00424     while (tmp_interface!=NULL)
00425     {
00426 
00427         if ((tmp_interface->dev->get_wireless_stats!=NULL) && (tmp_interface->dev->do_ioctl!=NULL))
00428         {
00429             strncpy(wrq.ifr_name,tmp_interface->dev->name , IFNAMSIZ);
00430             wrq.u.data.pointer = (caddr_t) stats_buffer;
00431             wrq.u.data.length = 64; //IW_MAX_GET_SPY;
00432             wrq.u.data.flags = 0;
00433 
00434         oldfs = get_fs();
00435         set_fs(KERNEL_DS);
00436             tmp_interface->dev->do_ioctl(tmp_interface->dev,(struct ifreq * ) &wrq,SIOCGIWSPY );
00437         set_fs(oldfs);
00438 
00439 
00440             n = wrq.u.data.length;
00441 
00442             
00443             hwa = (struct sockaddr *) stats_buffer;
00444             qual = (struct iw_quality *) (stats_buffer + (sizeof(struct sockaddr) * n));
00445                                           
00446 
00447 
00448             for(i = 0; i < n; i++)
00449             {
00450               //printk ("%u  %d\n",hwa[i].sa_data,qual[i].level - 0x100);
00451               //update_link_by_hw(hwa[i].sa_data,qual[i].level);
00452              tmp_entry= find_neighbor_list_entry_by_hw(hwa[i].sa_data);
00453              if(tmp_entry!=NULL)
00454                {
00455                  strcpy(dst,inet_ntoa(tmp_entry->ip));
00456                  sprintf(temp_buffer,"1 %s, %d \n",dst ,qual[i].level - 0x100);
00457                  strcat(my_buffer,temp_buffer);       
00458                }
00459 
00460 
00461         
00462             }
00463         }
00464         tmp_interface=tmp_interface->next;
00465     }
00466 
00467 
00468     len = strlen(my_buffer);
00469     *buffer_location = my_buffer + offset;
00470     len -= offset;
00471     if (len > buffer_length)
00472         len = buffer_length;
00473     else if (len < 0)
00474         len = 0;
00475     return len;
00476 
00477 }
00478 #endif
00479 
00480 
00481 
00482 
00483 int read_stats_proc(char *buffer, char **buffer_location, off_t offset, int buffer_length,int *eof,void *data)
00484 {
00485 
00486     static char *my_buffer;
00487     char temp_buffer[200];
00488     char temp[20];
00489     int len=0,i;
00490     u_int32_t curr_time;
00491     char dst[16];
00492     char hop[16];
00493     u_int64_t numerator;
00494 
00495     my_buffer=buffer;
00496 
00497     numerator = (getcurrtime()-monitor.last_read);
00498     curr_time=do_div( numerator, 1000 );
00499 
00500     if (curr_time!=0)
00501     {
00502         sprintf(my_buffer,"Bytes: %d\nPackets: %d\nRouting: %d\nRREP: %d\nRREQ: %d\nRERR: %d\n",monitor.bytes/curr_time,monitor.packets/curr_time,monitor.routing_packets/curr_time,monitor.rrep/curr_time,monitor.rreq/curr_time,monitor.rrer/curr_time);
00503 
00504         monitor.last_read=getcurrtime();
00505         monitor.bytes=0;
00506         monitor.packets=0;
00507         monitor.routing_packets=0;
00508         monitor.rreq=0;
00509         monitor.rrep=0;
00510         monitor.rrer=0;
00511 
00512         len = strlen(my_buffer);
00513         *buffer_location = my_buffer + offset;
00514         len -= offset;
00515 
00516         if (len > buffer_length)
00517             len = buffer_length;
00518         else if (len < 0)
00519             len = 0;
00520     }
00521     return len;
00522 }
00523 
00524 
00525 
00526 
00527 /****************************************************
00528 
00529    send_datagram
00530 ----------------------------------------------------
00531 Used to send out a UDP packet through a
00532 socket
00533 ****************************************************/
00534 
00535 #ifdef AODV_MULTICAST
00536 
00537 int rebroadcast(u_int32_t dst,u_int16_t datalen, void *data, u_int8_t ttl)
00538 {
00539    struct msghdr msg;
00540    struct iovec iov;
00541     mm_segment_t oldfs;
00542 
00543     unsigned char *ucp;
00544     u_int32_t space;
00545     struct iphdr *iph=data;
00546     int retval;
00547     int len=0;
00548 
00549 
00550 
00551 
00552     /* First, test if the socket has any buffer-space left.
00553        If not, no need to actually try to send something.  */
00554                   
00555                 
00556         
00557     ucp=(unsigned char *)&(g_my_ip);
00558 
00559 
00560 
00561     space = sock_wspace(multicast_sock->sk);
00562     
00563     if (space<datalen)
00564       {
00565         printk(KERN_WARNING "AODV: Space: %d, Data: %d \n",space,datalen);
00566         return -ENOMEM;
00567       }
00568 
00569     if (ttl < 1 )
00570         return 0;
00571 
00572     memset(&sin,0,sizeof(sin));
00573     sin.sin_family = AF_INET;
00574     sin.sin_addr.s_addr= dst;
00575     //    sin.sin_port         = htons(0);
00576 
00577     //define the message we are going to be sending out
00578     msg.msg_name     = (void *) &(sin);
00579     msg.msg_namelen  = sizeof(sin);
00580     msg.msg_iov  = &iov;
00581     msg.msg_iovlen   = 1;
00582     msg.msg_control  = NULL;
00583     msg.msg_controllen = 0;
00584     msg.msg_flags    = MSG_DONTWAIT|MSG_NOSIGNAL;
00585     msg.msg_iov->iov_len =  datalen;
00586     msg.msg_iov->iov_base = (char*) data;
00587 
00588     multicast_sock->sk->broadcast=1;
00589     multicast_sock->sk->protinfo.af_inet.ttl=ttl;
00590 
00591     oldfs = get_fs();
00592     set_fs(KERNEL_DS);
00593 
00594     len = sock_sendmsg(multicast_sock,&msg,datalen);
00595     if (len<0)
00596     {
00597         printk("REBROADCAST: Error sending! err no: %d, Dst: %s\n",len,inet_ntoa(dst));
00598     }
00599     set_fs(oldfs);
00600 
00601     return 0;
00602 }
00603 #endif
00604 
00605 
00606 int local_broadcast(u_int8_t ttl, void *data, int datalen)
00607 {
00608     struct interface_list_entry *tmp_interface;
00609     struct msghdr msg;
00610     struct iovec iov;
00611     u_int64_t curr_time;
00612     mm_segment_t oldfs;
00613     int len=0;
00614 
00615     curr_time=getcurrtime();
00616 
00617     if (ttl == 0 )
00618         return 0;
00619 
00620 
00621 
00622     memset(&sin,0,sizeof(sin));
00623     sin.sin_family = AF_INET;
00624     sin.sin_addr.s_addr= g_broadcast_ip;
00625     sin.sin_port         = htons((unsigned short)AODVPORT);
00626 
00627     //define the message we are going to be sending out
00628     msg.msg_name     = (void *) &(sin);
00629     msg.msg_namelen  = sizeof(sin);
00630     msg.msg_iov  = &iov;
00631     msg.msg_iovlen   = 1;
00632     msg.msg_control  = NULL;
00633     msg.msg_controllen = 0;
00634     msg.msg_flags    = MSG_DONTWAIT|MSG_NOSIGNAL;
00635     msg.msg_iov->iov_len = (__kernel_size_t) datalen;
00636     msg.msg_iov->iov_base = (char*) data;
00637 
00638     tmp_interface=find_first_interface_entry();
00639     
00640     while ( (tmp_interface) && (tmp_interface->sock) && ( sock_wspace(tmp_interface->sock->sk) >= datalen) )
00641     {
00642         tmp_interface->sock->sk->broadcast=1;
00643         tmp_interface->sock->sk->protinfo.af_inet.ttl=ttl;
00644         tmp_interface->last_broadcast=curr_time;
00645 
00646         oldfs = get_fs();
00647         set_fs(KERNEL_DS);
00648 
00649         len = sock_sendmsg(tmp_interface->sock,&msg,datalen);
00650 
00651         if (len<0)
00652             printk(KERN_WARNING "AODV: Error sending! err no: %d,on interface: %s\n",len,tmp_interface->dev->name);
00653         set_fs(oldfs);
00654         monitor.routing_packets++;
00655         tmp_interface=tmp_interface->next;
00656     }
00657 
00658     return len;
00659 }
00660 
00661 
00662 int send_message(u_int32_t dst_ip,u_int8_t ttl, void *data, int datalen)
00663 {
00664     mm_segment_t oldfs;
00665     struct msghdr msg;
00666     struct interface_list_entry *tmp_interface;
00667     struct route_table_entry *tmp_route;
00668     struct iovec iov;
00669     u_int64_t curr_time;
00670     int   len;
00671     u_int32_t space;
00672 
00673 
00674     memset(&sin,0,sizeof(sin));
00675     sin.sin_family = AF_INET;
00676     sin.sin_addr.s_addr= dst_ip;
00677     sin.sin_port         = htons((unsigned short)AODVPORT);
00678 
00679 
00680 
00681     //define the message we are going to be sending out
00682     msg.msg_name     = (void *) &(sin);
00683     msg.msg_namelen  = sizeof(sin);
00684     msg.msg_iov  = &iov;
00685     msg.msg_iovlen   = 1;
00686     msg.msg_control  = NULL;
00687     msg.msg_controllen = 0;
00688     msg.msg_flags    = MSG_DONTWAIT|MSG_NOSIGNAL;
00689     msg.msg_iov->iov_len =  datalen;
00690     msg.msg_iov->iov_base = (char*) data;
00691 
00692 
00693     if (ttl == 0 )
00694         return 0;
00695 
00696     curr_time=getcurrtime();
00697     tmp_route=find_route_table_entry(dst_ip);
00698     if (tmp_route==NULL)
00699       {
00700 
00701         printk(KERN_WARNING "AODV: Can't find route to: %s \n",inet_ntoa(dst_ip));
00702         return -EHOSTUNREACH;
00703 
00704       }
00705     tmp_interface=find_interface_by_dev(tmp_route->dev);
00706     if (tmp_interface==NULL)
00707     {
00708         
00709         printk(KERN_WARNING "AODV: Error sending! Unable to find interface!\n");
00710         
00711         return -ENODEV;
00712     }
00713 
00714     space = sock_wspace(tmp_interface->sock->sk);
00715     
00716     if (space<datalen)
00717     {
00718         printk(KERN_WARNING "AODV: Space: %d, Data: %d \n",space,datalen);
00719         return -ENOMEM;
00720     }
00721 
00722     tmp_interface->sock->sk->broadcast=0;
00723     tmp_interface->sock->sk->protinfo.af_inet.ttl=ttl;
00724     tmp_interface->last_broadcast=curr_time;
00725     oldfs = get_fs();
00726     set_fs(KERNEL_DS);
00727 
00728     len = sock_sendmsg(tmp_interface->sock,&msg,datalen);
00729     if (len<0)
00730     {
00731         printk(KERN_WARNING "AODV: Error sending! err no: %d, Dst: %s\n",len,inet_ntoa(dst_ip));
00732     }
00733     set_fs(oldfs);
00734 
00735     monitor.routing_packets++;
00736     return 0;
00737 }
00738 
00739 /****************************************************
00740 
00741    getcurrtime
00742 ----------------------------------------------------
00743 Returns the current time
00744 ****************************************************/
00745 u_int64_t getcurrtime()
00746 {
00747     struct timeval tv;
00748         u_int64_t      result;
00749 
00750     do_gettimeofday(&tv);
00751 
00752         //This is a fix for an error that occurs on ARM Linux Kernels because they do 64bits differently
00753         //Thanks to S. Peter Li for coming up with this fix!
00754 
00755     result = (u_int64_t)tv.tv_usec;
00756     do_div(result, 1000);
00757     return ((u_int64_t)tv.tv_sec) * 1000 + result;
00758 }
00759 
00760 /****************************************************
00761 
00762    inet_ntoa
00763 ----------------------------------------------------
00764 Converts a IP address repersented in a 32 bit
00765 unsigned int into a string
00766 ****************************************************/
00767 char *inet_ntoa(__u32 ina)
00768 {
00769     static char buf[4*sizeof "123"];
00770     unsigned char *ucp = (unsigned char *)&ina;
00771     sprintf(buf, "%d.%d.%d.%d",
00772             ucp[0] & 0xff,
00773             ucp[1] & 0xff,
00774             ucp[2] & 0xff,
00775             ucp[3] & 0xff);
00776     return buf;
00777 }
00778 
00779 
00780 #ifdef AODV_GATEWAY
00781 
00782 /****************************************************
00783 
00784    adhoc_subnet_test
00785 ----------------------------------------------------
00786 Tests to see if the address is the subnet defined 
00787 as the Ad Hoc Subnet
00788 ****************************************************/
00789 int adhoc_subnet_test( u_int32_t ina)
00790 {
00791 
00792     unsigned char *ucp = (unsigned char *)&ina;
00793     unsigned char *uco = (unsigned char *)&g_aodv_subnet;
00794 
00795 
00796     if (g_aodv_subnet==0)
00797         return 1;
00798 
00799     if ((!(uco[0] & 0xff) || ((uco[0] & 0xff) == (ucp[0] & 0xff))) &&
00800             (!(uco[1] & 0xff) || ((uco[1] & 0xff) == (ucp[1] & 0xff))) &&
00801             (!(uco[2] & 0xff) || ((uco[2] & 0xff) == (ucp[2] & 0xff))) &&
00802             (!(uco[3] & 0xff) || ((uco[3] & 0xff) == (ucp[3] & 0xff))))
00803         return 1;
00804 
00805     printk(" AODV: %s is not in the AODV subnet\n",inet_ntoa(ina));
00806 
00807         return 0;
00808 }
00809 #endif
00810 
00811 
00812 #ifdef AODV_MULTICAST
00813 /****************************************************
00814 
00815    multicast_test
00816 ----------------------------------------------------
00817 Tests to see if the address is a multicast address
00818 ****************************************************/
00819 int multicast_test( u_int32_t ina)
00820 {
00821 
00822     unsigned char *ucp = (unsigned char *)&ina;
00823     
00824     if (((ucp[0] & 0xff) >=224) && ((ucp[0] & 0xff)<239))
00825         return 1;
00826     else
00827         return 0;
00828 }
00829 #endif
00830 
00831 int seq_less_or_equal(u_int32_t seq_one,u_int32_t seq_two)
00832 {
00833     int *comp_seq_one = &seq_one;
00834     int *comp_seq_two = &seq_two;
00835 
00836     if (  ( *comp_seq_one - *comp_seq_two ) > 0 )
00837     {
00838         return 0;
00839     }
00840     else
00841         return 1;
00842 }
00843 
00844 
00845 int seq_greater(u_int32_t seq_one,u_int32_t seq_two)
00846 {
00847     int *comp_seq_one = &seq_one;
00848     int *comp_seq_two = &seq_two;
00849 
00850     if (  ( *comp_seq_one - *comp_seq_two ) < 0 )
00851         return 0;
00852     else
00853         return 1;
00854 }
00855 
00856 
00857 
00858 /****************************************************
00859 
00860    inet_aton
00861 ----------------------------------------------------
00862 Converts a string into a 32-bit unsigned int
00863 ****************************************************/
00864 int inet_aton(const char *cp, __u32 *addr)
00865 {
00866     unsigned int val;
00867     int                     base,
00868     n;
00869     char            c;
00870     u_int           parts[4];
00871     u_int      *pp = parts;
00872 
00873     for (;;)
00874     {
00875 
00876         //Collect number up to ``.''. Values are specified as for C:
00877         // 0x=hex, 0=octal, other=decimal.
00878 
00879         val = 0;
00880         base = 10;
00881         if (*cp == '0')
00882         {
00883             if (*++cp == 'x' || *cp == 'X')
00884                 base = 16, cp++;
00885             else
00886                 base = 8;
00887         }
00888         while ((c = *cp) != '\0')
00889         {
00890             if (isascii(c) && isdigit(c))
00891             {
00892                 val = (val * base) + (c - '0');
00893                 cp++;
00894                 continue;
00895 
00896             }
00897             if (base == 16 && isascii(c) && isxdigit(c))
00898             {
00899                 val = (val << 4) +
00900                       (c + 10 - (islower(c) ? 'a' : 'A'));
00901                 cp++;
00902                 continue;
00903             }
00904             break;
00905         }
00906         if (*cp == '.')
00907         {
00908             // Internet format: a.b.c.d a.b.c       (with c treated as
00909             // 16-bits) a.b         (with b treated as 24 bits)
00910 
00911             if (pp >= parts + 3 || val > 0xff)
00912                 return (0);
00913             *pp++ = val, cp++;
00914         }
00915         else
00916             break;
00917     }
00918 
00919     // Check for trailing characters.
00920 
00921     if (*cp && (!isascii(*cp) || !isspace(*cp)))
00922         return (0);
00923 
00924 
00925     // Concoct the address according to the number of parts specified.
00926 
00927     n = pp - parts + 1;
00928     switch (n)
00929     {
00930 
00931     case 1:                 // a -- 32 bits
00932         break;
00933 
00934     case 2:                 //a.b -- 8.24 bits
00935         if (val > 0xffffff)
00936             return (0);
00937         val |= parts[0] << 24;
00938         break;
00939 
00940     case 3:                 //a.b.c -- 8.8.16 bits
00941         if (val > 0xffff)
00942             return (0);
00943         val |= (parts[0] << 24) | (parts[1] << 16);
00944         break;
00945 
00946     case 4:                 // a.b.c.d -- 8.8.8.8 bits
00947         if (val > 0xff)
00948             return (0);
00949         val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
00950         break;
00951     }
00952     if (addr)
00953         *addr= htonl(val);
00954     return (1);
00955 }
00956 

kernel_aodvmに対してThu Nov 10 18:53:11 2005に生成されました。  doxygen 1.4.5