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 "rreq.h"
00027
00028
00029
00030
00031
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
00058
00059
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;
00066 struct route_table_entry *tmp_entry;
00067 struct flood_id_queue_entry *tmp_rreq_id;
00068 u_int64_t current_time;
00069 int size_out;
00070
00071
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
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
00093
00094 tmp_rreq_id = find_flood_id_queue_entry(working_rreq->src_ip, working_rreq->rreq_id);
00095
00096
00097
00098
00099
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
00113 return -EHOSTDOWN;
00114 }
00115
00116
00117
00118
00119
00120
00121 current_time = getcurrtime();
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
00127 }
00128 working_rreq->hop_count=working_rreq->hop_count+1;
00129
00130
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
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
00149 if (working_rreq->u || seq_less_or_equal(working_rreq->dst_seq,tmp_entry->dst_seq ))
00150 {
00151
00152
00153 if (!working_rreq->d || (find_interface_by_ip(working_rreq->dst_ip)!=NULL))
00154 {
00155
00156
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
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
00185 if (tmp_entry==NULL)
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
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
00222 return -ENOMEM;
00223 }
00224
00225
00226 size_out=sizeof(struct rreq);
00227
00228
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
00241 out_rreq->src_seq = htonl(working_rreq->src_seq);
00242 out_rreq->rreq_id = htonl(working_rreq->rreq_id);
00243
00244
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
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
00270
00271
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
00283
00284 if (find_first_timer_queue_entry_of_id_and_flag(dst_ip,EVENT_RREQ) != NULL)
00285 return 0;
00286
00287
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
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
00304 return -ENOMEM;
00305 }
00306
00307
00308 tmp_entry = find_route_table_entry(dst_ip);
00309
00310
00311 if (tmp_entry == NULL)
00312 {
00313
00314 out_rreq->dst_seq = 0;
00315 out_rreq->u = TRUE;
00316 out_ttl = TTL_START;
00317 }
00318 else
00319 {
00320
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
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
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
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
00366
00367
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
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
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