rrep2.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 "rrep.h"
00027 /****************************************************
00028 
00029    rrep
00030 ----------------------------------------------------
00031 Handles sending and recieving RREPs
00032 ****************************************************/
00033 
00034 extern struct route_table_entry *g_my_entry;
00035 extern u_int32_t g_my_ip;
00036 extern u_int32_t g_broadcast_ip;
00037 
00038 int recv_hello(struct event_queue_entry *working_packet)
00039 {
00040     struct route_table_entry *recv_route;
00041     struct rrep *tmp_rrep;
00042     struct neighbor_list_entry  *tmp_entry;
00043     unsigned char *ucp;
00044 
00045     tmp_rrep=working_packet->data;
00046     ucp=(unsigned char *)&(tmp_rrep->dst_ip);
00047     
00048     tmp_entry=find_neighbor_list_entry(tmp_rrep->dst_ip);
00049     if (tmp_entry==NULL)
00050       {
00051         tmp_entry=create_neighbor_list_entry(tmp_rrep->dst_ip);
00052         memcpy(&(tmp_entry->hw_addr),&(working_packet->src_hw_addr),sizeof(unsigned char) * ETH_ALEN);
00053         tmp_entry->dev=working_packet->dev;
00054 
00055 #ifdef AODV_SIGNAL
00056         set_spy();
00057 #endif
00058         
00059       }
00060 
00061     delete_timer_queue_entry_of_id(tmp_entry->ip, EVENT_NEIGHBOR);
00062     insert_timer_queue_entry(tmp_rrep->lifetime+getcurrtime()+20,NULL,0,tmp_entry->ip,0,0,EVENT_NEIGHBOR);
00063     update_timer_queue();
00064     
00065     recv_route = find_route_table_entry(tmp_rrep->dst_ip);
00066 
00067     if (recv_route==NULL)
00068       {
00069         
00070         // No entry in RT found, generate a new
00071         recv_route = create_route_table_entry();
00072         recv_route->dst_ip = tmp_rrep->dst_ip;
00073         recv_route->lifetime = 0;
00074         recv_route->dev = working_packet->dev;
00075         recv_route->next_hop = working_packet->src_ip;
00076         recv_route->hop_count = tmp_rrep->hop_count ;
00077         recv_route->route_valid = TRUE;
00078         recv_route->route_seq_valid = TRUE;
00079         insert_kernel_route_entry(recv_route->dst_ip, recv_route->next_hop,recv_route->dev->name);
00080       }
00081 
00082     if ((tmp_rrep->hop_count < recv_route->hop_count) || (recv_route->route_valid==FALSE))// || (( tmp_rrep->dst_seq>=recv_route->dst_seq) && (recv_route->next_hop!=recv_route->dst_ip)))
00083       {
00084         delete_kernel_route_entry(recv_route->dst_ip, recv_route->next_hop);
00085         recv_route->dev = working_packet->dev;
00086         recv_route->next_hop = working_packet->src_ip;
00087         recv_route->hop_count = tmp_rrep->hop_count ;
00088         recv_route->route_valid = TRUE;
00089         recv_route->route_seq_valid = TRUE;
00090         insert_kernel_route_entry(recv_route->dst_ip, recv_route->next_hop,recv_route->dev->name);
00091       }
00092     
00093     tmp_entry->route_entry=recv_route;
00094     
00095     recv_route->lifetime = MAX(recv_route->lifetime,(tmp_rrep->lifetime+getcurrtime()+20));
00096     recv_route->dst_seq = tmp_rrep->dst_seq;
00097     
00098     return 0;
00099 }
00100 
00101 
00102 void convert_rrep_to_host(struct rrep *tmp_rrep)
00103 {
00104   tmp_rrep->dst_seq=ntohl(tmp_rrep->dst_seq);
00105   tmp_rrep->lifetime=ntohl(tmp_rrep->lifetime);
00106 }
00107 
00108 
00109 void convert_rrep_to_network(struct rrep *tmp_rrep)
00110 {
00111   tmp_rrep->dst_seq=htonl(tmp_rrep->dst_seq);
00112   tmp_rrep->lifetime=htonl(tmp_rrep->lifetime);
00113 }
00114 
00115 /****************************************************
00116 
00117    recv_rrep
00118 ----------------------------------------------------
00119 Handles recieving route replies. It is passed
00120 packets from the AODV thread
00121 ****************************************************/
00122 int recv_rrep(struct event_queue_entry *working_packet)
00123 {
00124   struct route_table_entry *send_route;
00125   struct route_table_entry *recv_route;
00126   struct rrep *tmp_rrep;
00127   struct interface_list_entry *tmp_interface;
00128   u_int64_t        curr_time;
00129   u_int32_t     tmp_ip=0;
00130   
00131 #ifdef MESSAGES
00132   char rt_ip[16];
00133 #endif
00134   
00135 #ifndef TRACE
00136   char dst_ip[16];
00137   char src_ip[16];
00138 #endif
00139 
00140   
00141   tmp_interface=find_interface_by_dev(working_packet->dev);
00142   //check to make sure the interface found
00143   
00144 
00145   if (tmp_interface==NULL)
00146     {
00147 
00148       printk(KERN_WARNING "AODV: Error finding interface RREP recieved on!\n");
00149 
00150       return 0;
00151     }
00152 
00153   tmp_ip=tmp_interface->ip;
00154 
00155   tmp_rrep=working_packet->data;
00156   convert_rrep_to_host(tmp_rrep);
00157 
00158   // increase the hop count on the rrep
00159   tmp_rrep->hop_count = tmp_rrep->hop_count + 1;
00160 
00161 
00162   
00163   if (tmp_rrep->hop_count==1)
00164     {
00165       //its a hello messages! HELLO WORLD!
00166       recv_hello(working_packet);
00167       return 0;
00168     }
00169  
00170   if ((tmp_ip!=0) && (working_packet->src_ip==tmp_ip))
00171     {
00172       printk(KERN_WARNING "AODV: Reading our own RREP! \n");
00173 
00174       return 0;
00175     }
00176 
00177 
00178   update_route_entry(tmp_rrep->dst_ip,  working_packet->src_ip, tmp_rrep->hop_count, tmp_rrep->dst_seq, working_packet->dev);
00179   delete_timer_queue_entry_of_id(tmp_rrep->dst_ip,EVENT_RREQ);
00180   
00181   recv_route = find_route_table_entry(tmp_rrep->dst_ip);
00182 
00183   /* If I'm not the destination of the RREP I forward it */
00184   if((tmp_rrep->src_ip != tmp_ip) && (tmp_rrep->src_ip!=tmp_rrep->dst_ip))
00185     {
00186 
00187         strcpy(src_ip,inet_ntoa(tmp_rrep->src_ip));
00188         strcpy(dst_ip,inet_ntoa(tmp_rrep->dst_ip));
00189         printk(KERN_INFO "AODV: Forwarding a route to: %s from node: %s \n",dst_ip,src_ip);
00190 
00191 
00192         /* Get the entry to the source from RT */
00193 
00194         send_route = find_route_table_entry(tmp_rrep->src_ip);
00195         if ((send_route!=NULL) && (recv_route!=NULL)) //thanks to Madanlal Musuvathi and the CMC program for catching this! I didn't check recv_route for NULL
00196         {
00197             /* Add to precursors... */
00198             if (insert_precursor_entry(recv_route, send_route->next_hop) == 1)
00199             {
00200                 /* Couldn't add precursor. Ignore and continue */
00201             }
00202             recv_route->lifetime = curr_time + ACTIVE_ROUTE_TIMEOUT;
00203 
00204             convert_rrep_to_network(tmp_rrep);
00205 
00206             send_message(tmp_rrep->src_ip,NET_DIAMETER, working_packet->data, working_packet->size);
00207 
00208         }
00209         else
00210             printk(KERN_WARNING "AODV: ERROR finding RREP sending address!\n");
00211 
00212     }
00213 
00214     return 0;
00215 }
00216 
00217 
00218 /****************************************************
00219 
00220    gen_rrep
00221 ----------------------------------------------------
00222 Generates a route reply
00223 ****************************************************/
00224 int gen_rrep(u_int32_t src_ip, u_int32_t dst_ip, u_int32_t packet_src_ip, u_int32_t dst_seq, int grat_rrep)
00225 {
00226     struct rrep      tmp_rrep;
00227     struct route_table_entry  *src_route;
00228     struct route_table_entry  *dst_route;
00229     struct interface_list_entry *tmp_interface=NULL;
00230     u_int64_t        curr_time;  /* Current time */
00231 
00232 
00233     char srcip[16];
00234     char dstip[16];
00235 
00236 
00237 
00238     curr_time = getcurrtime(); /* Get current time */
00239 
00240 
00241     /* Get the source and destination IP address from the RREQ */
00242     src_route = find_route_table_entry(src_ip);
00243     dst_route = find_route_table_entry(dst_ip);
00244 
00245 
00246     if ((dst_route==NULL) && (src_route==NULL))
00247       {
00248 
00249         printk(KERN_WARNING "AODV: RREP  No Source or DST route! src: %s\n",inet_ntoa(src_ip));
00250 
00251         return -EHOSTUNREACH;
00252       }
00253 
00254 
00255     if (dst_route!=NULL)
00256         tmp_interface=find_interface_by_dev(dst_route->dev);
00257     else
00258         tmp_interface=find_interface_by_dev(src_route->dev);
00259 
00260     if (dst_route==NULL)
00261         printk(KERN_WARNING "AODV: GEN_RREP - DST route invalid!\n");
00262     if(src_route==NULL)
00263         printk(KERN_WARNING "AODV: GEN_RREP SRC route invalid!\n");
00264 
00265 
00266 
00267     if ((dst_ip != tmp_interface->ip) && (dst_ip != g_broadcast_ip) && (grat_rrep))
00268     {
00269         /* Now send a datagram to the requested host telling it it has been
00270         asked for */
00271 
00272         tmp_rrep.type = 2;
00273         tmp_rrep.r = 0;
00274         tmp_rrep.prefix_sz = 0;
00275         tmp_rrep.reserved1=0;
00276         tmp_rrep.reserved2=0;
00277 
00278         /* Set the source to be the destination of the rreq (it has asked for
00279         it itself)*/
00280         tmp_rrep.src_ip = dst_ip;
00281 
00282 
00283 
00284         /* Insert the rreq's source attributes */
00285         tmp_rrep.dst_ip = src_ip;
00286 
00287         //we want it to be in network byte order!
00288         tmp_rrep.dst_seq = htonl(src_route->dst_seq);
00289         tmp_rrep.hop_count = src_route->hop_count;
00290 
00291         //we want it to be in network byte order!
00292         tmp_rrep.lifetime = htonl(src_route->lifetime - curr_time);
00293 
00294         /* Get info on the destination */
00295 
00296         strcpy(srcip,inet_ntoa(tmp_rrep.src_ip));
00297         strcpy(dstip,inet_ntoa(tmp_rrep.dst_ip));
00298         printk(KERN_WARNING "AODV: Sending out a Grat RREP -  src: %s dst: %s \n",srcip,dstip);
00299 
00300         send_message(dst_route->dst_ip,NET_DIAMETER, &tmp_rrep, sizeof(struct rrep));
00301     }
00302 
00303 
00304 
00305     /* Check if the destination IP of RREQ was this node */
00306     if (dst_ip == tmp_interface->ip)
00307     {
00308         /* The RREQ was for this node */
00309         /* Set the reply structure */
00310         if (seq_greater(dst_seq,dst_route->dst_seq))
00311             dst_route->dst_seq = dst_seq;
00312 
00313         //we want it to be in network byte order!
00314         tmp_rrep.dst_seq = htonl(dst_route->dst_seq);
00315         tmp_rrep.hop_count = 0;
00316 
00317         //we want it to be in network byte order!
00318         tmp_rrep.lifetime = htonl(MY_ROUTE_TIMEOUT);
00319     }
00320     else
00321     {
00322         /* The RREQ was for a node in RT */
00323         /* Set the reply structure */
00324 
00325         //we want it to be in network byte order!
00326         tmp_rrep.dst_seq = htonl(dst_route->dst_seq);
00327         tmp_rrep.lifetime = htonl(dst_route->lifetime - curr_time);
00328         tmp_rrep.hop_count = dst_route->hop_count;
00329 
00330 
00331         /* Add to precursors... */
00332         insert_precursor_entry(dst_route, packet_src_ip);
00333         insert_precursor_entry(src_route, dst_route->next_hop);
00334 
00335     }
00336 
00337     /* Set the rest of the RREP structure */
00338 
00339     tmp_rrep.src_ip = src_ip;
00340     tmp_rrep.dst_ip = dst_ip;
00341     tmp_rrep.type = 2;
00342     tmp_rrep.r = 0;
00343     tmp_rrep.prefix_sz = 0;
00344 
00345     send_message(packet_src_ip,NET_DIAMETER, &tmp_rrep, sizeof(struct rrep));
00346 
00347     return 0;
00348 }

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