This source file includes following definitions.
- ax25_rt_rx_frame
- ax25_rt_device_down
- ax25_rt_get_info
- ax25_cs_get_info
- ax25_rt_autobind
- ax25_ip_mode_set
- ax25_ip_mode_get
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 #include <linux/config.h>
30 #ifdef CONFIG_AX25
31 #include <linux/errno.h>
32 #include <linux/types.h>
33 #include <linux/socket.h>
34 #include <linux/in.h>
35 #include <linux/kernel.h>
36 #include <linux/sched.h>
37 #include <linux/timer.h>
38 #include <linux/string.h>
39 #include <linux/sockios.h>
40 #include <linux/net.h>
41 #include <net/ax25.h>
42 #include <linux/inet.h>
43 #include <linux/netdevice.h>
44 #include <linux/skbuff.h>
45 #include <net/sock.h>
46 #include <asm/segment.h>
47 #include <asm/system.h>
48 #include <linux/fcntl.h>
49 #include <linux/mm.h>
50 #include <linux/interrupt.h>
51
52 #define AX25_ROUTE_MAX 40
53
54 static struct ax25_route {
55 struct ax25_route *next;
56 ax25_address callsign;
57 struct device *dev;
58 struct timeval stamp;
59 int n;
60 char ip_mode;
61 } *ax25_route = NULL;
62
63 void ax25_rt_rx_frame(ax25_address *src, struct device *dev)
64 {
65 unsigned long flags;
66 extern struct timeval xtime;
67 struct ax25_route *ax25_rt;
68 struct ax25_route *oldest;
69 int count;
70
71 count = 0;
72 oldest = NULL;
73
74 for (ax25_rt = ax25_route; ax25_rt != NULL; ax25_rt = ax25_rt->next) {
75 if (count == 0 || ax25_rt->stamp.tv_sec < oldest->stamp.tv_sec)
76 oldest = ax25_rt;
77
78 if (ax25cmp(&ax25_rt->callsign, src) == 0 && ax25_rt->dev == dev) {
79 ax25_rt->stamp = xtime;
80 ax25_rt->n++;
81 return;
82 }
83
84 count++;
85 }
86
87 if (count > AX25_ROUTE_MAX) {
88 oldest->callsign = *src;
89 oldest->dev = dev;
90 oldest->stamp = xtime;
91 oldest->n = 1;
92 oldest->ip_mode = ' ';
93 return;
94 }
95
96 if ((ax25_rt = (struct ax25_route *)kmalloc(sizeof(struct ax25_route), GFP_ATOMIC)) == NULL)
97 return;
98
99 ax25_rt->callsign = *src;
100 ax25_rt->dev = dev;
101 ax25_rt->stamp = xtime;
102 ax25_rt->n = 1;
103 ax25_rt->ip_mode = ' ';
104
105 save_flags(flags);
106 cli();
107
108 ax25_rt->next = ax25_route;
109 ax25_route = ax25_rt;
110
111 restore_flags(flags);
112 }
113
114 void ax25_rt_device_down(struct device *dev)
115 {
116 struct ax25_route *s, *t, *ax25_rt = ax25_route;
117
118 while (ax25_rt != NULL) {
119 s = ax25_rt;
120 ax25_rt = ax25_rt->next;
121
122 if (s->dev == dev) {
123 if (ax25_route == s) {
124 ax25_route = s->next;
125 kfree_s((void *)s, (sizeof *s));
126 } else {
127 for (t = ax25_route; t != NULL; t = t->next) {
128 if (t->next == s) {
129 t->next = s->next;
130 kfree_s((void *)s, sizeof(*s));
131 break;
132 }
133 }
134 }
135 }
136 }
137 }
138
139 int ax25_rt_get_info(char *buffer, char **start, off_t offset, int length)
140 {
141 struct ax25_route *ax25_rt;
142 int len = 0;
143 off_t pos = 0;
144 off_t begin = 0;
145
146 cli();
147
148 len += sprintf(buffer, "callsign dev count time mode\n");
149
150 for (ax25_rt = ax25_route; ax25_rt != NULL; ax25_rt = ax25_rt->next) {
151 len += sprintf(buffer + len, "%-9s %-4s %5d %9d",
152 ax2asc(&ax25_rt->callsign),
153 ax25_rt->dev ? ax25_rt->dev->name : "???",
154 ax25_rt->n,
155 ax25_rt->stamp.tv_sec);
156
157 switch (ax25_rt->ip_mode) {
158 case 'V':
159 case 'v':
160 len += sprintf(buffer + len, " vc\n");
161 break;
162 case 'D':
163 case 'd':
164 len += sprintf(buffer + len, " dg\n");
165 break;
166 default:
167 len += sprintf(buffer + len, "\n");
168 break;
169 }
170
171 pos = begin + len;
172
173 if (pos < offset) {
174 len = 0;
175 begin = pos;
176 }
177
178 if (pos > offset + length)
179 break;
180 }
181
182 sti();
183
184 *start = buffer + (offset - begin);
185 len -= (offset - begin);
186
187 if (len > length) len = length;
188
189 return len;
190 }
191
192 int ax25_cs_get_info(char *buffer, char **start, off_t offset, int length)
193 {
194 ax25_uid_assoc *pt;
195 int len = 0;
196 off_t pos = 0;
197 off_t begin = 0;
198
199 cli();
200
201 len += sprintf(buffer, "Policy: %d\n", ax25_uid_policy);
202
203 for (pt = ax25_uid_list; pt != NULL; pt = pt->next) {
204 len += sprintf(buffer + len, "%6d %s\n", pt->uid, ax2asc(&pt->call));
205
206 pos = begin + len;
207
208 if (pos < offset) {
209 len = 0;
210 begin = pos;
211 }
212
213 if (pos > offset + length)
214 break;
215 }
216
217 sti();
218
219 *start = buffer + (offset - begin);
220 len -= offset - begin;
221
222 if (len > length) len = length;
223
224 return len;
225 }
226
227
228
229
230 int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr)
231 {
232 struct ax25_route *ax25_rt;
233 ax25_address *call;
234
235 for (ax25_rt = ax25_route; ax25_rt != NULL; ax25_rt = ax25_rt->next) {
236 if (ax25cmp(&ax25_rt->callsign, addr) == 0) {
237
238
239
240 if ((ax25->device = ax25_rt->dev) == NULL)
241 continue;
242 if ((call = ax25_findbyuid(current->euid)) == NULL) {
243 if (ax25_uid_policy && !suser())
244 return -EPERM;
245 call = (ax25_address *)ax25->device->dev_addr;
246 }
247 memcpy(&ax25->source_addr, call, sizeof(ax25_address));
248 if (ax25->sk != NULL)
249 ax25->sk->zapped = 0;
250
251 return 0;
252 }
253 }
254
255 return -EINVAL;
256 }
257
258
259
260
261
262 void ax25_ip_mode_set(ax25_address *callsign, struct device *dev, char ip_mode)
263 {
264 struct ax25_route *ax25_rt;
265
266 for (ax25_rt = ax25_route; ax25_rt != NULL; ax25_rt = ax25_rt->next) {
267 if (ax25cmp(&ax25_rt->callsign, callsign) == 0 && ax25_rt->dev == dev) {
268 ax25_rt->ip_mode = ip_mode;
269 return;
270 }
271 }
272 }
273
274
275
276
277 char ax25_ip_mode_get(ax25_address *callsign, struct device *dev)
278 {
279 struct ax25_route *ax25_rt;
280
281 for (ax25_rt = ax25_route; ax25_rt != NULL; ax25_rt = ax25_rt->next)
282 if (ax25cmp(&ax25_rt->callsign, callsign) == 0 && ax25_rt->dev == dev)
283 return ax25_rt->ip_mode;
284
285 return ' ';
286 }
287
288 #endif