rreq.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 "rreq.h"
00027 /****************************************************
00028 
00029    rreq
00030 ----------------------------------------------------
00031 Handles the generation of RREQ and recieving
00032 ****************************************************/
00033 
00034 extern u_int32_t g_broadcast_ip;
00035 extern struct route_table_entry *g_my_entry;
00036 extern u_int32_t g_my_ip;
00037 
00038 
00039 void convert_rreq_to_host(struct rreq *tmp_rreq)
00040 {
00041     tmp_rreq->rreq_id=ntohl(tmp_rreq->rreq_id);
00042     tmp_rreq->dst_seq=ntohl(tmp_rreq->dst_seq);
00043     tmp_rreq->src_seq=ntohl(tmp_rreq->src_seq);
00044 }
00045 
00046 void convert_rreq_to_network(struct rreq *tmp_rreq)
00047 {
00048     tmp_rreq->rreq_id=htonl(tmp_rreq->rreq_id);
00049     tmp_rreq->dst_seq=htonl(tmp_rreq->dst_seq);
00050     tmp_rreq->src_seq=htonl(tmp_rreq->src_seq);
00051 }
00052 
00053 
00054 
00055 /****************************************************
00056 
00057    recv_rreq
00058 ----------------------------------------------------
00059 Handles the recieving of RREQs
00060 ****************************************************/
00061 int recv_rreq(struct event_queue_entry *working_packet)
00062 {
00063     struct rreq *working_rreq;
00064     struct interface_list_entry *tmp_interface;
00065     struct rreq       *out_rreq;  /* Forwarded RREQ */
00066     struct route_table_entry   *tmp_entry;       /* Routing table entry */
00067     struct flood_id_queue_entry *tmp_rreq_id;
00068     u_int64_t          current_time;  /* Current time */
00069     int size_out;
00070 
00071     /* Update the hop count */
00072     char src_ip[16];
00073     char dst_ip[16];
00074 
00075 
00076 
00077     working_rreq=working_packet->data;
00078     convert_rreq_to_host(working_rreq);
00079 
00080     //find what interface the packet was recived on
00081     tmp_interface=find_interface_by_dev(working_packet->dev);
00082 
00083     if (tmp_interface==NULL)
00084     {
00085 
00086         printk (KERN_WARNING "AODV: Recieved on a RREQ from an unrecognized interface.\n");
00087 
00088         return -ENODEV;
00089     }
00090 
00091 
00092     /* Look in the route request list to see if the node has
00093        already received this request. */
00094     tmp_rreq_id = find_flood_id_queue_entry(working_rreq->src_ip, working_rreq->rreq_id);
00095 
00096 
00097     /* Check if an entry in the route request list was found, and if it's
00098        still valid. If there is a valid entry, this request shouldn't be
00099        checked. */
00100     if (tmp_rreq_id != NULL) 
00101     {
00102         return 0;
00103     }
00104 
00105     tmp_entry=find_route_table_entry(working_rreq->src_ip);
00106     
00107     if ((tmp_entry!=NULL) && (tmp_entry->next_hop!=working_packet->src_ip))
00108       
00109       {
00110         strcpy(src_ip,inet_ntoa(working_rreq->src_ip));
00111         strcpy(dst_ip,inet_ntoa(working_rreq->dst_ip));
00112         //      printk("To: %s src: %s RREQ_ID: %u, expires: %d\n",src_ip,dst_ip,working_rreq->rreq_id,tmp_entry->lifetime-getcurrtime());
00113         return -EHOSTDOWN;
00114       }
00115 
00116 
00117     /* Have not received this RREQ within BCAST_ID_SAVE time */
00118 
00119     /* Add this RREQ to the list for further checks */
00120 
00121     current_time = getcurrtime(); /* Get the current time */
00122 
00123 
00124     if (insert_flood_id_queue_entry(working_rreq->src_ip, working_rreq->dst_ip,working_rreq->rreq_id, current_time + PATH_TRAVERSAL_TIME) == 1)
00125       {
00126         /* Couldn't add the entry, ignore and continue */
00127       }
00128     working_rreq->hop_count=working_rreq->hop_count+1;
00129 
00130     /* UPDATE REVERSE */
00131 
00132     update_route_entry(working_rreq->src_ip,  working_packet->src_ip, working_rreq->hop_count, working_rreq->src_seq, working_packet->dev);
00133 
00134 
00135 
00136     tmp_entry = find_route_table_entry(working_rreq->dst_ip);
00137 
00138 
00139 
00140 
00141 
00142 
00143     /* Test to see if we should send a RREP AKA we have or are the desired route*/
00144 
00145     if ((working_rreq->dst_ip == tmp_interface->ip) || 
00146         (tmp_entry != NULL && tmp_entry->route_valid && tmp_entry->route_seq_valid) )
00147     {
00148       /* The node already had a valid route to the destination */      
00149         if (working_rreq->u || seq_less_or_equal(working_rreq->dst_seq,tmp_entry->dst_seq ))
00150           {
00151             /*Check to see if only the destination should reply */
00152             
00153             if (!working_rreq->d || (find_interface_by_ip(working_rreq->dst_ip)!=NULL))
00154               {
00155                 
00156                 //If the RREQ is addressed to us and we have the same Seq as the RREQ we up our Seq by one
00157                 if ((find_interface_by_ip(working_rreq->dst_ip)!=NULL) && (working_rreq->dst_seq>=tmp_entry->dst_seq))
00158                   {
00159                     tmp_entry->dst_seq=working_rreq->dst_seq+1;
00160                   }
00161 
00162                 strcpy(src_ip,inet_ntoa(working_rreq->src_ip));
00163                 strcpy(dst_ip,inet_ntoa(working_rreq->dst_ip));
00164                 printk(KERN_INFO "AODV: Generating RREP -  src: %s dst: %s \n",src_ip,dst_ip);
00165 
00166 
00167                 /* Call for gen_rrep to send a Route Reply */
00168 
00169 
00170                 gen_rrep(working_rreq->src_ip,working_rreq->dst_ip,working_packet->src_ip,working_rreq->dst_seq,working_rreq->g);
00171 
00172                 return 0;
00173             }
00174         }
00175     }
00176 
00177 #ifdef AODV_GATEWAY
00178     if (!adhoc_subnet_test(working_rreq->dst_ip))
00179       {
00180         printk("Gatewaying for address: %s \n", inet_ntoa( working_rreq->dst_ip ));
00181         if (tmp_entry == NULL)
00182           {
00183             tmp_entry = create_route_table_entry();
00184             /*lock table*/
00185             if (tmp_entry==NULL) // Thanks to M. Musuvathi for catching this!
00186               return -ENOMEM;
00187             tmp_entry->dst_ip = working_rreq->dst_ip;
00188             tmp_entry->next_hop = g_my_ip;
00189             tmp_entry->dev= g_my_entry->dev;
00190             tmp_entry->dst_seq = 1;
00191             tmp_entry->route_valid = 1;
00192             tmp_entry->route_seq_valid = 1;
00193             tmp_entry->rreq_id = 0;
00194             tmp_entry->hop_count = 20;
00195             tmp_entry->lifetime = getcurrtime() + 5000;
00196           }
00197         else
00198           {
00199             tmp_entry->dst_seq++;
00200           }
00201 
00202         gen_rrep(working_rreq->src_ip,working_rreq->dst_ip,working_packet->src_ip,working_rreq->dst_seq,0);
00203         return 0;
00204       }
00205 #endif
00206 
00207 
00208 
00209     /* The node didn't have a valid route to the destination */
00210 
00211     if ((working_packet->ttl) <=1)
00212     {
00213         return -ETIMEDOUT;
00214     }
00215 
00216     if ((out_rreq = (struct rreq*) kmalloc(sizeof (struct rreq),GFP_ATOMIC)) == NULL)
00217       {
00218 
00219         printk(KERN_WARNING "AODV: Error creating a new RREQ\n");
00220 
00221         /* Failed to allocate memory for forwarded RREQ */
00222         return -ENOMEM;
00223     }
00224 
00225 
00226     size_out=sizeof(struct rreq);
00227 
00228     /* Set the RREQ structure */
00229     out_rreq->type = 1;
00230     out_rreq->j = working_rreq->j;
00231     out_rreq->r = working_rreq->r;
00232     out_rreq->g = working_rreq->g;
00233     out_rreq->d = working_rreq->d;
00234     out_rreq->u = working_rreq->u;
00235     out_rreq->reserved = 0;
00236     out_rreq->hop_count = working_rreq->hop_count;
00237     out_rreq->dst_ip = working_rreq->dst_ip;
00238     out_rreq->src_ip = working_rreq->src_ip;
00239 
00240     //we want it to be network byte order
00241     out_rreq->src_seq = htonl(working_rreq->src_seq);
00242     out_rreq->rreq_id = htonl(working_rreq->rreq_id);
00243 
00244     /* Set the right sequence number */
00245     if (tmp_entry!=NULL)
00246     {
00247         if (seq_greater(working_rreq->dst_seq, tmp_entry->dst_seq))
00248             out_rreq->dst_seq=htonl(working_rreq->dst_seq);
00249         else
00250             out_rreq->dst_seq=htonl(tmp_entry->dst_seq);
00251     }
00252     else
00253         out_rreq->dst_seq = htonl(working_rreq->dst_seq);
00254 
00255 
00256 
00257     /* Call send_datagram to send and forward the RREQ */
00258     local_broadcast(working_packet->ttl-1, out_rreq, sizeof(struct rreq));
00259 
00260     kfree(out_rreq);
00261 
00262     return 0;
00263 }
00264 
00265 
00266 
00267 /****************************************************
00268 
00269    gen_rreq
00270 ----------------------------------------------------
00271 Generates a RREQ! wahhooo!
00272 ****************************************************/
00273 int gen_rreq(u_int32_t src_ip, u_int32_t dst_ip)
00274 {
00275     struct route_table_entry *tmp_entry;
00276     struct rreq *out_rreq, *timer_rreq;
00277     u_int8_t  out_ttl;
00278 
00279 
00280 
00281 
00282     /* Do not send rreq to the same host again if its already in the timer queue */
00283 
00284     if (find_first_timer_queue_entry_of_id_and_flag(dst_ip,EVENT_RREQ) != NULL)
00285         return 0;
00286 
00287     /* Allocate memory for the rreq message */
00288 
00289 
00290     if ((out_rreq = (struct rreq*) kmalloc(sizeof(struct rreq),GFP_ATOMIC)) == NULL)
00291     {
00292         printk(KERN_WARNING "AODV: Can't allocate new rreq\n");
00293         return -ENOMEM;
00294     }
00295 
00296     /* Allocate memory for the timer queue position for the rreq */
00297 
00298     if ((timer_rreq = kmalloc(sizeof(struct rreq),GFP_ATOMIC))==NULL)
00299     {
00300         printk("AODV: Can't allocate for a new timer queue position\n");
00301         kfree(out_rreq);
00302 
00303         /* Couldn't allocate memory */
00304         return -ENOMEM;
00305     }
00306 
00307     /* Get routing table entry for destination */
00308     tmp_entry = find_route_table_entry(dst_ip);
00309 
00310 
00311     if (tmp_entry == NULL)
00312     {
00313         /* Entry does not exist -> set to initial values*/
00314         out_rreq->dst_seq = 0;
00315         out_rreq->u = TRUE;
00316         out_ttl =  TTL_START;
00317     }
00318     else
00319     {
00320         /* Entry does exist -> get value from rt */
00321         out_rreq->dst_seq = htonl(tmp_entry->dst_seq);
00322         if (tmp_entry->route_seq_valid)
00323         {
00324             out_rreq->u=FALSE;
00325         }
00326         else
00327         {
00328             out_rreq->u=TRUE;
00329         }
00330         out_ttl =  tmp_entry->hop_count + TTL_INCREMENT;
00331     }
00332 
00333     /* Get routing table entry for source, when this is ourself this one should always exist*/
00334 
00335     tmp_entry = (find_interface_by_ip(src_ip))->route_entry;
00336 
00337     if (tmp_entry == NULL)
00338     {
00339         printk(KERN_WARNING "AODV: Can't get route to self\n");
00340 
00341         kfree(out_rreq);
00342         kfree(timer_rreq);
00343 
00344         return -EHOSTUNREACH;
00345     }
00346 
00347     /* Get our own sequence number */
00348     (tmp_entry->rreq_id)++;
00349     tmp_entry->dst_seq=tmp_entry->dst_seq+1;
00350     out_rreq->src_seq = htonl(tmp_entry->dst_seq);
00351     out_rreq->rreq_id = htonl(tmp_entry->rreq_id);
00352 
00353     /* Fill in the package */
00354     out_rreq->dst_ip = dst_ip;
00355     out_rreq->src_ip = src_ip;
00356     out_rreq->type = 1;
00357     out_rreq->hop_count = htonl(0);
00358     out_rreq->j = 0;
00359     out_rreq->r = 0;
00360     out_rreq->d = 0;
00361     out_rreq->reserved = 0;
00362     out_rreq->second_reserved = 0;
00363     out_rreq->g=1;
00364 
00365     /* Get the broadcast address and ttl right */
00366 
00367     //    if (insert_flood_id_queue_entry(out_rreq->src_ip, out_rreq->dst_ip,out_rreq->rreq_id, getcurrtime() + 2* out_ttl * NODE_TRAVERSAL_TIME) == 1)
00368     if (insert_flood_id_queue_entry(out_rreq->src_ip, out_rreq->dst_ip,out_rreq->rreq_id, getcurrtime() + 2 * NET_TRAVERSAL_TIME) < 0)
00369     {
00370       kfree(out_rreq);
00371       kfree(timer_rreq);
00372 
00373       printk(KERN_WARNING "AODV: Can't add to broadcast list\n");
00374 
00375       return -ENOMEM;
00376     }
00377 
00378     memcpy(timer_rreq,out_rreq,sizeof(struct rreq));
00379     out_ttl=10;
00380     //    insert_timer_queue_entry(getcurrtime() + NET_TRAVERSAL_TIME,timer_rreq, sizeof(struct rreq),out_rreq->dst_ip,0,out_ttl, EVENT_RREQ);
00381     insert_timer_queue_entry(getcurrtime() + NET_TRAVERSAL_TIME,timer_rreq, sizeof(struct rreq),out_rreq->dst_ip,RREQ_RETRIES,out_ttl, EVENT_RREQ);
00382 
00383 
00384     update_timer_queue();
00385 
00386     //local_broadcast(out_ttl,out_rreq,sizeof(struct rreq));
00387     local_broadcast(10,out_rreq,sizeof(struct rreq));
00388 
00389     kfree(out_rreq);
00390 
00391     return 0;
00392 }
00393 
00394 
00395 
00396 
00397 
00398 
00399 
00400 
00401 
00402 
00403 
00404 

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