-
Notifications
You must be signed in to change notification settings - Fork 2
/
dsr.h
303 lines (264 loc) · 6.79 KB
/
dsr.h
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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
/* 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]>
*/
#ifndef _DSR_H
#define _DSR_H
#include "platform.h"
#ifdef __KERNEL__
#include <linux/version.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
#include <linux/config.h>
#endif
#include <asm/byteorder.h>
#include <linux/types.h>
//#include <linux/in.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/ip.h>
#include <linux/time.h>
#ifdef KERNEL26
#include <linux/jiffies.h>
#endif
#else
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
//#include <endian.h>
#include <netinet/in.h>
#endif /* __KERNEL__ */
#include "dsr-pkt.h"
#include "timer.h"
#ifndef NO_GLOBALS
#define DSR_BROADCAST ((unsigned int) 0xffffffff)
#ifdef NS2
#define IPPROTO_DSR PT_DSR
#else
#define IPPROTO_DSR 168 /* Is this correct? */
#endif
#define IP_HDR_LEN 20
#define DSR_OPTS_MAX_SIZE 50 /* This is used to reduce the MTU of the DSR *
* device so that packets are not too big after
* adding the DSR header. A better solution
* should probably be found... */
enum confval {
#ifdef ENABLE_DEBUG
PrintDebug,
#endif
AutomaticRouteShortening,
RoundTripTimeout, /* Determines the Round trip timeout (RTO)
* used for DSR acks. If set to 0, dynamic
* measurement is used. */
FlushLinkCache,
PromiscOperation,
BroadCastJitter,
RouteCacheTimeout,
SendBufferTimeout,
SendBufferSize,
RequestTableSize,
RequestTableIds,
MaxRequestRexmt,
MaxRequestPeriod,
RequestPeriod,
NonpropRequestTimeout,
RexmtBufferSize,
MaintHoldoffTime,
MaxMaintRexmt,
UseNetworkLayerAck,
TryPassiveAcks,
PassiveAckTimeout,
GratReplyHoldOff,
MAX_SALVAGE_COUNT,
CONFVAL_MAX,
};
enum confval_type {
SECONDS,
MILLISECONDS,
MICROSECONDS,
NANOSECONDS,
QUANTA,
BINARY,
COMMAND,
CONFVAL_TYPE_MAX,
};
#define MAINT_BUF_MAX_LEN 100
#define RREQ_TBL_MAX_LEN 64 /* Should be enough */
#define SEND_BUF_MAX_LEN 100
#define RREQ_TLB_MAX_ID 16
static struct {
const char *name;
const unsigned int val;
enum confval_type type;
} confvals_def[CONFVAL_MAX] = {
#ifdef ENABLE_DEBUG
{
"PrintDebug", 0, BINARY},
#endif
{
"AutomaticRouteShortening", 1, BINARY}, {
"RoundTripTimeout", 2000, MILLISECONDS}, {
"FlushLinkCache", 1, COMMAND}, {
"PromiscOperation", 1, BINARY}, {
"BroadCastJitter", 20, MILLISECONDS}, {
"RouteCacheTimeout", 300, SECONDS}, {
"SendBufferTimeout", 30, SECONDS}, {
"SendBufferSize", SEND_BUF_MAX_LEN, QUANTA}, {
"RequestTableSize", RREQ_TBL_MAX_LEN, QUANTA}, {
"RequestTableIds", RREQ_TLB_MAX_ID, QUANTA}, {
"MaxRequestRexmt", 16, QUANTA}, {
"MaxRequestPeriod", 10, SECONDS}, {
"RequestPeriod", 500, MILLISECONDS}, {
"NonpropRequestTimeout", 30, MILLISECONDS}, {
"RexmtBufferSize", MAINT_BUF_MAX_LEN}, {
"MaintHoldoffTime", 250, MILLISECONDS}, {
"MaxMaintRexmt", 2, QUANTA}, {
"UseNetworkLayerAck", 1, BINARY}, {
"TryPassiveAcks", 1, QUANTA}, {
"PassiveAckTimeout", 100, MILLISECONDS}, {
"GratReplyHoldOff", 1, SECONDS}, {
"MAX_SALVAGE_COUNT", 15, QUANTA}
};
struct dsr_node {
struct in_addr ifaddr;
struct in_addr bcaddr;
unsigned int confvals[CONFVAL_MAX];
#ifdef __KERNEL__
char slave_ifname[IFNAMSIZ];
struct net_device *slave_dev;
struct in_device *slave_indev;
struct net_device_stats stats;
spinlock_t lock;
#endif
};
#ifdef __KERNEL__
#define NSCLASS
#define XMIT(pkt) dsr_dev_xmit(pkt)
/* Some macros to access different layer headers in the skb. The APIs
* changed around kernel 2.6.22, so these macros make us backwards
* compatible with older kernels. */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)
#define SKB_NETWORK_HDR_RAW(skb) skb->nh.raw
#define SKB_NETWORK_HDR_RIPH(skb) skb->nh.iph
#define SKB_MAC_HDR_RAW(skb) skb->mac.raw
#define SKB_TAIL(skb) skb->tail
#define SKB_SET_MAC_HDR(skb, offset) (skb->mac.raw = (skb->data + (offset)))
#define SKB_SET_NETWORK_HDR(skb, offset) (skb->nh.raw = (skb->data + (offset)))
#else
#define SKB_NETWORK_HDR_RAW(skb) skb_network_header(skb)
#define SKB_NETWORK_HDR_IPH(skb) ((struct iphdr *)skb_network_header(skb))
#define SKB_MAC_HDR_RAW(skb) skb_mac_header(skb)
#define SKB_TAIL(skb) skb_tail_pointer(skb)
#define SKB_SET_MAC_HDR(skb, offset) skb_set_mac_header(skb, offset)
#define SKB_SET_NETWORK_HDR(skb, offset) skb_set_network_header(skb, offset)
#endif
#endif /* __KERNEL__ */
#ifdef __KERNEL__
#define ConfVal(cv) get_confval(cv)
#define ConfValToUsecs(cv) confval_to_usecs(cv)
extern struct dsr_node *dsr_node;
static inline unsigned int get_confval(enum confval cv)
{
unsigned int val = 0;
if (dsr_node) {
spin_lock_bh(&dsr_node->lock);
val = dsr_node->confvals[cv];
spin_unlock_bh(&dsr_node->lock);
}
return val;
}
static inline int set_confval(enum confval cv, unsigned int val)
{
if (dsr_node) {
spin_lock_bh(&dsr_node->lock);
dsr_node->confvals[cv] = val;
spin_unlock_bh(&dsr_node->lock);
} else
return -1;
return val;
}
static inline void dsr_node_init(struct dsr_node *dn, char *ifname)
{
int i;
dn->slave_indev = NULL;
dn->slave_dev = NULL;
dn->slave_ifname[0] - '\0';
if (ifname)
memcpy(dn->slave_ifname, ifname, IFNAMSIZ);
spin_lock_init(&dn->lock);
for (i = 0; i < CONFVAL_MAX; i++) {
dn->confvals[i] = confvals_def[i].val;
}
}
static inline struct in_addr my_addr(void)
{
static struct in_addr my_addr;
if (dsr_node) {
spin_lock_bh(&dsr_node->lock);
my_addr = dsr_node->ifaddr;
spin_unlock_bh(&dsr_node->lock);
}
return my_addr;
}
static inline unsigned long time_add_msec(unsigned long msecs)
{
struct timespec t;
t.tv_sec = msecs / 1000;
t.tv_nsec = (msecs * 1000000) % 1000000000;
return timespec_to_jiffies(&t);
}
static inline int get_slave_dev_ifindex(void)
{
int ifindex = -1;
if (dsr_node) {
spin_lock_bh(&dsr_node->lock);
if (dsr_node->slave_dev)
ifindex = dsr_node->slave_dev->ifindex;
spin_unlock_bh(&dsr_node->lock);
}
return ifindex;
}
static inline void dsr_node_lock(struct dsr_node *dnode)
{
spin_lock_bh(&dnode->lock);
}
static inline void dsr_node_unlock(struct dsr_node *dnode)
{
spin_unlock_bh(&dnode->lock);
}
int dsr_ip_recv(struct sk_buff *skb);
int do_mackill(char *mac);
#endif
#endif /* NO_GLOBALS */
#ifndef NO_DECLS
static inline usecs_t confval_to_usecs(enum confval cv)
{
usecs_t usecs = 0;
unsigned int val;
val = ConfVal(cv);
switch (confvals_def[cv].type) {
case SECONDS:
usecs = val * 1000000;
break;
case MILLISECONDS:
usecs = val * 1000;
break;
case MICROSECONDS:
usecs = val;
break;
case NANOSECONDS:
usecs = val / 1000;
break;
case BINARY:
case QUANTA:
case COMMAND:
case CONFVAL_TYPE_MAX:
break;
}
return usecs;
}
#endif /* NO_DECLS */
#endif /* _DSR_H */