00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "rerr.h"
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 extern u_int32_t g_broadcast_ip;
00037 extern u_int32_t g_my_ip;
00038
00039
00040
00041 void free_rerrhdr(struct rerrhdr *tmp_rerrhdr);
00042
00043 int send_rerr(struct rerrhdr *tmp_rerrhdr, u_int32_t sent_to);
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 int link_break( u_int32_t brk_dst_ip)
00058 {
00059 struct route_table_entry *tmp_entry;
00060 struct rerrhdr *new_rerrhdr = NULL;
00061 struct precursor_entry *tmp_precursor;
00062 struct precursor_entry *dead_precursor;
00063
00064
00065 u_int32_t last_precursor;
00066 u_int8_t precursor_num=0;
00067
00068
00069 int rerrhdr_created = 0;
00070
00071
00072 delete_precursor_entry_from_route_table(brk_dst_ip);
00073
00074
00075 tmp_entry=get_first_route_table_entry();
00076
00077
00078 while(tmp_entry != NULL)
00079 {
00080
00081 if((tmp_entry->next_hop == brk_dst_ip) && (tmp_entry->route_valid))
00082 {
00083
00084
00085 printk(KERN_INFO "RERR: Broken link as next hop for - %s \n",inet_ntoa(tmp_entry->dst_ip));
00086
00087
00088 route_expiry(tmp_entry);
00089
00090 if(tmp_entry->precursors!=NULL)
00091 {
00092
00093 if(!rerrhdr_created)
00094 {
00095 if((new_rerrhdr =create_rerrhdr(tmp_entry->dst_ip,tmp_entry->dst_seq)) == NULL)
00096 return 1;
00097 rerrhdr_created = 1;
00098 }
00099 else
00100 {
00101 append_unr_dst(new_rerrhdr, tmp_entry->dst_ip, tmp_entry->dst_seq);
00102 }
00103 }
00104
00105
00106 tmp_precursor=tmp_entry->precursors;
00107
00108 while (tmp_precursor!=NULL)
00109 {
00110 last_precursor=tmp_precursor->ip;
00111 dead_precursor=tmp_precursor;
00112 tmp_precursor=tmp_precursor->next;
00113 kfree(dead_precursor);
00114 }
00115 tmp_entry->precursors=NULL;
00116
00117
00118
00119 }
00120
00121
00122 tmp_entry = tmp_entry->next;
00123 }
00124
00125
00126
00127
00128 if(rerrhdr_created)
00129 {
00130 if (precursor_num==1)
00131 send_rerr(new_rerrhdr,last_precursor);
00132 else
00133 send_rerr(new_rerrhdr,g_broadcast_ip);
00134
00135 free_rerrhdr(new_rerrhdr);
00136 }
00137
00138 return 0;
00139 }
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151 void route_expiry(struct route_table_entry *tmp_entry)
00152 {
00153
00154
00155
00156 tmp_entry->lifetime = (getcurrtime() + DELETE_PERIOD);
00157 tmp_entry->dst_seq++;
00158 tmp_entry->route_valid=FALSE;
00159 delete_kernel_route_entry(tmp_entry->dst_ip, tmp_entry->next_hop);
00160 }
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172 int host_unr(u_int32_t brk_dst_ip)
00173 {
00174 struct rerrhdr *new_rerrhdr = NULL;
00175 struct route_table_entry *tmp_entry;
00176
00177 tmp_entry = find_route_table_entry(brk_dst_ip);
00178
00179 if((new_rerrhdr = create_rerrhdr(brk_dst_ip, 1)) == NULL)
00180 return -ENOMEM;
00181
00182 send_rerr(new_rerrhdr,g_broadcast_ip);
00183 free_rerrhdr(new_rerrhdr);
00184
00185 return 0;
00186 }
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 int recv_rerr(struct event_queue_entry *working_packet)
00199 {
00200 struct rerr *tmp_hdr;
00201 struct rerrhdr *new_rerrhdr = NULL;
00202 struct rerrdst *tmp_dst;
00203 struct route_table_entry *tmp_route;
00204 struct interface_list_entry *tmp_interface;
00205
00206 int new_rerr_created = 0;
00207 int i;
00208
00209 tmp_interface=find_interface_by_dev(working_packet->dev);
00210 if (tmp_interface==NULL)
00211 {
00212 printk(KERN_WARNING "AODV: Recieved RERR on an unknown device!\n");
00213 return -ENODEV;
00214 }
00215
00216 tmp_hdr =(struct rerr *) ((char *) working_packet->data);
00217 tmp_dst = (struct rerrdst *) ((char *) tmp_hdr + sizeof (struct rerr));
00218
00219
00220 printk(KERN_INFO "AODV: recieved a route error from %s, count= %u\n",inet_ntoa(working_packet->src_ip),tmp_hdr->dst_count);
00221
00222
00223 for(i = 0; i < tmp_hdr->dst_count; i++)
00224 {
00225
00226
00227 printk(KERN_INFO " -> %s",inet_ntoa(tmp_dst->unr_dst_ip));
00228
00229
00230 tmp_route = find_route_table_entry(tmp_dst->unr_dst_ip);
00231
00232
00233 if(tmp_route != NULL)
00234 {
00235
00236 if( !tmp_route->self_route )
00237 {
00238
00239 if (tmp_route->next_hop == working_packet->src_ip)
00240 {
00241
00242 printk(KERN_INFO " Removing route");
00243
00244
00245 tmp_route->dst_seq = ntohl(tmp_dst->unr_dst_seq);
00246 tmp_route->route_valid=FALSE;
00247 tmp_route->lifetime = (getcurrtime() + DELETE_PERIOD);
00248 delete_kernel_route_entry(tmp_route->dst_ip, tmp_route->next_hop);
00249
00250 if(tmp_route->precursors != NULL)
00251 {
00252
00253 if(!new_rerr_created)
00254 {
00255 new_rerr_created = 1;
00256 new_rerrhdr = create_rerrhdr(tmp_dst->unr_dst_ip,ntohl( tmp_dst->unr_dst_seq));
00257
00258 }
00259 else
00260 {
00261 append_unr_dst(new_rerrhdr, tmp_dst->unr_dst_ip, ntohl(tmp_dst->unr_dst_seq));
00262
00263 }
00264 }
00265 }
00266 }
00267
00268 }
00269
00270 printk(KERN_INFO" \n");
00271
00272 tmp_dst =(struct rerrdst *) ((char *) tmp_dst + sizeof (struct rerrdst));
00273
00274
00275
00276 }
00277
00278 if(new_rerr_created)
00279 {
00280 send_rerr(new_rerrhdr,g_broadcast_ip);
00281 free_rerrhdr(new_rerrhdr);
00282 }
00283
00284 return 0;
00285 }
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295 struct rerrhdr* create_rerrhdr(u_int32_t tmp_ip, u_int32_t tmp_dst_seq)
00296 {
00297 struct rerr_unr_dst *tmp_rerr_unr_dst;
00298 struct rerrhdr *tmp_rerrhdr;
00299
00300
00301 if((tmp_rerrhdr = kmalloc(sizeof(struct rerrhdr),GFP_ATOMIC)) == NULL)
00302 {
00303
00304 printk(KERN_WARNING "AODV: Error creating tmp_rerrhdr \n");
00305
00306 return NULL;
00307 }
00308
00309
00310 if((tmp_rerr_unr_dst = kmalloc(sizeof(struct rerr_unr_dst),GFP_ATOMIC)) == NULL)
00311 {
00312 kfree(tmp_rerrhdr);
00313 printk(KERN_WARNING "AODV: Error creating temp_rerr_unr_dst\n");
00314
00315 return NULL;
00316 }
00317
00318
00319
00320 tmp_rerr_unr_dst->unr_dst_ip = tmp_ip;
00321 tmp_rerr_unr_dst->unr_dst_seq = tmp_dst_seq;
00322 tmp_rerr_unr_dst->next = NULL;
00323
00324
00325 tmp_rerrhdr->unr_dst = tmp_rerr_unr_dst;
00326 tmp_rerrhdr->type = 3;
00327 tmp_rerrhdr->dst_count = 1;
00328
00329 return tmp_rerrhdr;
00330 }
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341 int append_unr_dst(struct rerrhdr *tmp_rerrhdr, u_int32_t tmp_ip,u_int32_t tmp_dst_seq)
00342 {
00343 struct rerr_unr_dst *tmp_rerr_unr_dst;
00344
00345
00346 if((tmp_rerr_unr_dst = kmalloc(sizeof(struct rerr_unr_dst),GFP_ATOMIC)) == NULL)
00347 {
00348 printk(KERN_WARNING "AODV: Error appending new unr_dst\n");
00349 return -ENOMEM;
00350 }
00351
00352
00353
00354
00355 tmp_rerr_unr_dst->next = tmp_rerrhdr->unr_dst;
00356 tmp_rerrhdr->unr_dst = tmp_rerr_unr_dst;
00357 tmp_rerrhdr->dst_count++;
00358 tmp_rerr_unr_dst->unr_dst_ip = tmp_ip;
00359 tmp_rerr_unr_dst->unr_dst_seq = tmp_dst_seq;
00360
00361 return 0;
00362 }
00363
00364
00365
00366
00367
00368
00369
00370
00371 void free_rerrhdr(struct rerrhdr *tmp_rerrhdr)
00372 {
00373 struct rerr_unr_dst *tmp_unr_dst;
00374 struct rerr_unr_dst *dead_dst;
00375
00376
00377 tmp_unr_dst=tmp_rerrhdr->unr_dst;
00378
00379 while (tmp_unr_dst!=NULL)
00380 {
00381 dead_dst=tmp_unr_dst;
00382
00383 tmp_unr_dst = tmp_unr_dst->next;
00384 kfree(dead_dst);
00385 }
00386
00387 kfree(tmp_rerrhdr);
00388 }
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399 int send_rerr(struct rerrhdr *tmp_rerrhdr, u_int32_t sent_to)
00400 {
00401 struct rerr *out_hdr;
00402 struct rerrdst *out_dst;
00403 struct rerr_unr_dst *tmp_dst;
00404 void *data;
00405
00406 int datalen, i;
00407
00408 datalen = sizeof(struct rerr) + sizeof(struct rerrdst) * (tmp_rerrhdr->dst_count);
00409
00410 if((data = kmalloc(datalen,GFP_ATOMIC)) == NULL)
00411 {
00412
00413 printk(KERN_WARNING"AODV: Error creating packet to send RERR\n");
00414
00415 return -ENOMEM;
00416 }
00417
00418
00419 out_hdr =(struct rerr *) ((char *) data);
00420 out_hdr->type = 3;
00421 out_hdr->dst_count = tmp_rerrhdr->dst_count;
00422 out_hdr->reserved =0;
00423
00424 out_dst=(struct rerrdst *) ((char *) out_hdr + sizeof(struct rerr));
00425 tmp_dst = tmp_rerrhdr->unr_dst;
00426
00427 for(i = 0; i < tmp_rerrhdr->dst_count; i++)
00428 {
00429 out_dst->unr_dst_ip=tmp_dst->unr_dst_ip;
00430
00431 printk(KERN_INFO "AODV: adding... %s to RERR\n",inet_ntoa(out_dst->unr_dst_ip));
00432
00433
00434
00435 out_dst->unr_dst_seq=htonl(tmp_dst->unr_dst_seq);
00436 out_dst =(struct rerrdst *) ((char *) out_dst + sizeof(struct rerrdst));
00437 tmp_dst = tmp_dst->next;
00438 }
00439
00440 if (sent_to==g_broadcast_ip)
00441 local_broadcast(NET_DIAMETER, data, datalen);
00442 else
00443 send_message(sent_to,NET_DIAMETER, data, datalen);
00444
00445 kfree(data);
00446 return 0;
00447 }
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461 void print_rerrhdr(struct rerrhdr *new_rerrhdr)
00462 {
00463 struct rerr_unr_dst *tmp_rerr_unr_dst;
00464 struct in_addr tmp_in_addr;
00465 int i;
00466
00467 printk(KERN_INFO "Outgoing RERR message: type: %d dst_cnt: %d\n",
00468 new_rerrhdr->type, new_rerrhdr->dst_count);
00469
00470 for(i = 0, tmp_rerr_unr_dst = new_rerrhdr->unr_dst;
00471 i < new_rerrhdr->dst_count;
00472 i++, tmp_rerr_unr_dst = tmp_rerr_unr_dst->next)
00473 {
00474 tmp_in_addr.s_addr = tmp_rerr_unr_dst->unr_dst_ip;
00475 printk(KERN_INFO "unr_dst_ip: %s unr_dst_seq %d\n",
00476 inet_ntoa(tmp_in_addr.s_addr),
00477 tmp_rerr_unr_dst->unr_dst_seq);
00478 }
00479 }
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491