-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathdsr-io.c
171 lines (149 loc) · 3.33 KB
/
dsr-io.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/* Copyright (C) Uppsala University
*
* This file is distributed under the terms of the GNU general Public
* License (GPL), see the file LICENSE
*
* Author: Erik Nordström, <[email protected]>
*/
#ifdef NS2
#include "ns-agent.h"
#else
#include "dsr-dev.h"
#endif
#include "dsr.h"
#include "dsr-pkt.h"
#include "dsr-rreq.h"
#include "dsr-rrep.h"
#include "dsr-srt.h"
#include "dsr-ack.h"
#include "dsr-rtc.h"
#include "dsr-ack.h"
#include "maint-buf.h"
#include "neigh.h"
#include "dsr-opt.h"
#include "link-cache.h"
#include "debug.h"
#include "send-buf.h"
int NSCLASS dsr_recv(struct dsr_pkt *dp)
{
int i = 0, action;
int mask = DSR_PKT_NONE;
struct in_addr myaddr = my_addr();
/* Ignore packets that are originated by this node to avoid
* poluting the link cache with old information that we keep
* on genereating. */
if (dp->flags & PKT_PROMISC_RECV &&
memcmp(&myaddr, &dp->src, sizeof(struct in_addr)) == 0) {
dsr_pkt_free(dp);
return 0;
}
/* Process DSR Options */
action = dsr_opt_recv(dp);
/* Add mac address of previous hop to the neighbor table */
if (dp->flags & PKT_PROMISC_RECV) {
dsr_pkt_free(dp);
return 0;
}
for (i = 0; i < DSR_PKT_ACTION_LAST; i++) {
switch (action & mask) {
case DSR_PKT_NONE:
break;
case DSR_PKT_DROP:
case DSR_PKT_ERROR:
LOG_DBG("DSR_PKT_DROP or DSR_PKT_ERROR\n");
dsr_pkt_free(dp);
return 0;
case DSR_PKT_SEND_ACK:
/* Moved to dsr-ack.c */
break;
case DSR_PKT_SRT_REMOVE:
//LOG_DBG("Remove source route\n");
// Hmm, we remove the DSR options when we deliver a
//packet
//dsr_opt_remove(dp);
break;
case DSR_PKT_FORWARD:
#ifdef NS2
if (dp->nh.iph->ttl() < 1)
#else
if (dp->nh.iph->ttl < 1)
#endif
{
LOG_DBG("ttl=0, dropping!\n");
dsr_pkt_free(dp);
return 0;
} else {
LOG_DBG("Forwarding %s %s nh %s\n",
print_ip(dp->src),
print_ip(dp->dst), print_ip(dp->nxt_hop));
XMIT(dp);
return 0;
}
break;
case DSR_PKT_FORWARD_RREQ:
XMIT(dp);
return 0;
case DSR_PKT_SEND_RREP:
/* In dsr-rrep.c */
break;
case DSR_PKT_SEND_ICMP:
LOG_DBG("Send ICMP\n");
break;
case DSR_PKT_SEND_BUFFERED:
if (dp->rrep_opt) {
struct in_addr rrep_srt_dst;
int i;
for (i = 0; i < dp->num_rrep_opts; i++) {
rrep_srt_dst.s_addr = dp->rrep_opt[i]->addrs[DSR_RREP_ADDRS_LEN(dp->rrep_opt[i]) / sizeof(struct in_addr)];
send_buf_set_verdict(SEND_BUF_SEND, rrep_srt_dst);
}
}
break;
case DSR_PKT_DELIVER:
LOG_DBG("Deliver to DSR device\n");
DELIVER(dp);
return 0;
case 0:
break;
default:
LOG_DBG("Unknown pkt action\n");
}
mask = (mask << 1);
}
dsr_pkt_free(dp);
return 0;
}
void NSCLASS dsr_start_xmit(struct dsr_pkt *dp)
{
int res;
if (!dp) {
LOG_DBG("Could not allocate DSR packet\n");
return;
}
dp->srt = dsr_rtc_find(dp->src, dp->dst);
if (dp->srt) {
if (dsr_srt_add(dp) < 0) {
LOG_DBG("Could not add source route\n");
goto out;
}
/* Send packet */
XMIT(dp);
return;
} else {
#ifdef NS2
res = send_buf_enqueue_packet(dp, &DSRUU::ns_xmit);
#else
res = send_buf_enqueue_packet(dp, &dsr_dev_xmit);
#endif
if (res < 0) {
LOG_DBG("Queueing failed!\n");
goto out;
}
res = dsr_rreq_route_discovery(dp->dst);
if (res < 0)
LOG_DBG("RREQ Transmission failed...");
return;
}
out:
dsr_pkt_free(dp);
}