Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
net
ax25
ax25_addr.c
Go to the documentation of this file.
1
/*
2
* This program is free software; you can redistribute it and/or modify
3
* it under the terms of the GNU General Public License as published by
4
* the Free Software Foundation; either version 2 of the License, or
5
* (at your option) any later version.
6
*
7
* Copyright (C) Jonathan Naylor G4KLX (
[email protected]
)
8
*/
9
#include <linux/errno.h>
10
#include <linux/types.h>
11
#include <linux/socket.h>
12
#include <linux/in.h>
13
#include <linux/kernel.h>
14
#include <linux/module.h>
15
#include <
linux/timer.h
>
16
#include <linux/string.h>
17
#include <
linux/sockios.h
>
18
#include <linux/net.h>
19
#include <
net/ax25.h
>
20
#include <
linux/inet.h
>
21
#include <linux/netdevice.h>
22
#include <
linux/skbuff.h
>
23
#include <
net/sock.h
>
24
#include <asm/uaccess.h>
25
#include <linux/fcntl.h>
26
#include <
linux/mm.h
>
27
#include <
linux/interrupt.h
>
28
29
/*
30
* The default broadcast address of an interface is QST-0; the default address
31
* is LINUX-1. The null address is defined as a callsign of all spaces with
32
* an SSID of zero.
33
*/
34
35
const
ax25_address
ax25_bcast
=
36
{{
'Q'
<< 1,
'S'
<< 1,
'T'
<< 1,
' '
<< 1,
' '
<< 1,
' '
<< 1, 0 << 1}};
37
const
ax25_address
ax25_defaddr
=
38
{{
'L'
<< 1,
'I'
<< 1,
'N'
<< 1,
'U'
<< 1,
'X'
<< 1,
' '
<< 1, 1 << 1}};
39
const
ax25_address
null_ax25_address
=
40
{{
' '
<< 1,
' '
<< 1,
' '
<< 1,
' '
<< 1,
' '
<< 1,
' '
<< 1, 0 << 1}};
41
42
EXPORT_SYMBOL_GPL
(ax25_bcast);
43
EXPORT_SYMBOL_GPL
(ax25_defaddr);
44
EXPORT_SYMBOL
(null_ax25_address);
45
46
/*
47
* ax25 -> ascii conversion
48
*/
49
char
*
ax2asc
(
char
*
buf
,
const
ax25_address
*
a
)
50
{
51
char
c
, *
s
;
52
int
n
;
53
54
for
(n = 0, s = buf; n < 6; n++) {
55
c = (a->
ax25_call
[
n
] >> 1) & 0x7F;
56
57
if
(c !=
' '
) *s++ =
c
;
58
}
59
60
*s++ =
'-'
;
61
62
if
((n = ((a->
ax25_call
[6] >> 1) & 0x0F)) > 9) {
63
*s++ =
'1'
;
64
n -= 10;
65
}
66
67
*s++ = n +
'0'
;
68
*s++ =
'\0'
;
69
70
if
(*buf ==
'\0'
|| *buf ==
'-'
)
71
return
"*"
;
72
73
return
buf
;
74
75
}
76
77
EXPORT_SYMBOL
(
ax2asc
);
78
79
/*
80
* ascii -> ax25 conversion
81
*/
82
void
asc2ax
(
ax25_address
*
addr
,
const
char
*callsign)
83
{
84
const
char
*
s
;
85
int
n
;
86
87
for
(s = callsign, n = 0; n < 6; n++) {
88
if
(*s !=
'\0'
&& *s !=
'-'
)
89
addr->
ax25_call
[
n
] = *s++;
90
else
91
addr->
ax25_call
[
n
] =
' '
;
92
addr->
ax25_call
[
n
] <<= 1;
93
addr->
ax25_call
[
n
] &= 0xFE;
94
}
95
96
if
(*s++ ==
'\0'
) {
97
addr->
ax25_call
[6] = 0x00;
98
return
;
99
}
100
101
addr->
ax25_call
[6] = *s++ -
'0'
;
102
103
if
(*s !=
'\0'
) {
104
addr->
ax25_call
[6] *= 10;
105
addr->
ax25_call
[6] += *s++ -
'0'
;
106
}
107
108
addr->
ax25_call
[6] <<= 1;
109
addr->
ax25_call
[6] &= 0x1E;
110
}
111
112
EXPORT_SYMBOL
(
asc2ax
);
113
114
/*
115
* Compare two ax.25 addresses
116
*/
117
int
ax25cmp
(
const
ax25_address
*
a
,
const
ax25_address
*
b
)
118
{
119
int
ct
= 0;
120
121
while
(ct < 6) {
122
if
((a->
ax25_call
[ct] & 0xFE) != (b->
ax25_call
[ct] & 0xFE))
/* Clean off repeater bits */
123
return
1;
124
ct++;
125
}
126
127
if
((a->
ax25_call
[ct] & 0x1E) == (b->
ax25_call
[ct] & 0x1E))
/* SSID without control bit */
128
return
0;
129
130
return
2;
/* Partial match */
131
}
132
133
EXPORT_SYMBOL
(
ax25cmp
);
134
135
/*
136
* Compare two AX.25 digipeater paths.
137
*/
138
int
ax25digicmp
(
const
ax25_digi
*digi1,
const
ax25_digi
*digi2)
139
{
140
int
i
;
141
142
if
(digi1->
ndigi
!= digi2->
ndigi
)
143
return
1;
144
145
if
(digi1->
lastrepeat
!= digi2->
lastrepeat
)
146
return
1;
147
148
for
(i = 0; i < digi1->
ndigi
; i++)
149
if
(
ax25cmp
(&digi1->
calls
[i], &digi2->
calls
[i]) != 0)
150
return
1;
151
152
return
0;
153
}
154
155
/*
156
* Given an AX.25 address pull of to, from, digi list, command/response and the start of data
157
*
158
*/
159
const
unsigned
char
*
ax25_addr_parse
(
const
unsigned
char
*
buf
,
int
len,
160
ax25_address
*
src
,
ax25_address
*
dest
,
ax25_digi
*digi,
int
*
flags
,
161
int
*dama)
162
{
163
int
d
= 0;
164
165
if
(len < 14)
return
NULL
;
166
167
if
(flags !=
NULL
) {
168
*flags = 0;
169
170
if
(buf[6] &
AX25_CBIT
)
171
*flags =
AX25_COMMAND
;
172
if
(buf[13] & AX25_CBIT)
173
*flags =
AX25_RESPONSE
;
174
}
175
176
if
(dama !=
NULL
)
177
*dama = ~buf[13] &
AX25_DAMA_FLAG
;
178
179
/* Copy to, from */
180
if
(dest !=
NULL
)
181
memcpy
(dest, buf + 0,
AX25_ADDR_LEN
);
182
if
(src !=
NULL
)
183
memcpy
(src, buf + 7,
AX25_ADDR_LEN
);
184
185
buf += 2 *
AX25_ADDR_LEN
;
186
len -= 2 *
AX25_ADDR_LEN
;
187
188
digi->
lastrepeat
= -1;
189
digi->
ndigi
= 0;
190
191
while
(!(buf[-1] &
AX25_EBIT
)) {
192
if
(d >=
AX25_MAX_DIGIS
)
193
return
NULL
;
194
if
(len <
AX25_ADDR_LEN
)
195
return
NULL
;
196
197
memcpy
(&digi->
calls
[d], buf,
AX25_ADDR_LEN
);
198
digi->
ndigi
= d + 1;
199
200
if
(buf[6] &
AX25_HBIT
) {
201
digi->
repeated
[
d
] = 1;
202
digi->
lastrepeat
=
d
;
203
}
else
{
204
digi->
repeated
[
d
] = 0;
205
}
206
207
buf +=
AX25_ADDR_LEN
;
208
len -=
AX25_ADDR_LEN
;
209
d++;
210
}
211
212
return
buf
;
213
}
214
215
/*
216
* Assemble an AX.25 header from the bits
217
*/
218
int
ax25_addr_build
(
unsigned
char
*
buf
,
const
ax25_address
*
src
,
219
const
ax25_address
*
dest
,
const
ax25_digi
*
d
,
int
flag
,
int
modulus
)
220
{
221
int
len
= 0;
222
int
ct
= 0;
223
224
memcpy
(buf, dest,
AX25_ADDR_LEN
);
225
buf[6] &= ~(
AX25_EBIT
|
AX25_CBIT
);
226
buf[6] |=
AX25_SSSID_SPARE
;
227
228
if
(flag ==
AX25_COMMAND
) buf[6] |=
AX25_CBIT
;
229
230
buf +=
AX25_ADDR_LEN
;
231
len +=
AX25_ADDR_LEN
;
232
233
memcpy
(buf, src,
AX25_ADDR_LEN
);
234
buf[6] &= ~(
AX25_EBIT
|
AX25_CBIT
);
235
buf[6] &= ~
AX25_SSSID_SPARE
;
236
237
if
(modulus ==
AX25_MODULUS
)
238
buf[6] |=
AX25_SSSID_SPARE
;
239
else
240
buf[6] |=
AX25_ESSID_SPARE
;
241
242
if
(flag ==
AX25_RESPONSE
) buf[6] |=
AX25_CBIT
;
243
244
/*
245
* Fast path the normal digiless path
246
*/
247
if
(d ==
NULL
|| d->
ndigi
== 0) {
248
buf[6] |=
AX25_EBIT
;
249
return
2 *
AX25_ADDR_LEN
;
250
}
251
252
buf +=
AX25_ADDR_LEN
;
253
len +=
AX25_ADDR_LEN
;
254
255
while
(ct < d->ndigi) {
256
memcpy
(buf, &d->
calls
[ct],
AX25_ADDR_LEN
);
257
258
if
(d->
repeated
[ct])
259
buf[6] |=
AX25_HBIT
;
260
else
261
buf[6] &= ~
AX25_HBIT
;
262
263
buf[6] &= ~
AX25_EBIT
;
264
buf[6] |=
AX25_SSSID_SPARE
;
265
266
buf +=
AX25_ADDR_LEN
;
267
len +=
AX25_ADDR_LEN
;
268
ct++;
269
}
270
271
buf[-1] |=
AX25_EBIT
;
272
273
return
len;
274
}
275
276
int
ax25_addr_size
(
const
ax25_digi
*
dp
)
277
{
278
if
(dp ==
NULL
)
279
return
2 *
AX25_ADDR_LEN
;
280
281
return
AX25_ADDR_LEN
* (2 + dp->
ndigi
);
282
}
283
284
/*
285
* Reverse Digipeat List. May not pass both parameters as same struct
286
*/
287
void
ax25_digi_invert
(
const
ax25_digi
*
in
,
ax25_digi
*
out
)
288
{
289
int
ct
;
290
291
out->
ndigi
= in->
ndigi
;
292
out->
lastrepeat
= in->
ndigi
- in->
lastrepeat
- 2;
293
294
/* Invert the digipeaters */
295
for
(ct = 0; ct < in->
ndigi
; ct++) {
296
out->
calls
[
ct
] = in->
calls
[in->
ndigi
- ct - 1];
297
298
if
(ct <= out->lastrepeat) {
299
out->
calls
[
ct
].
ax25_call
[6] |=
AX25_HBIT
;
300
out->
repeated
[
ct
] = 1;
301
}
else
{
302
out->
calls
[
ct
].
ax25_call
[6] &= ~
AX25_HBIT
;
303
out->
repeated
[
ct
] = 0;
304
}
305
}
306
}
307
Generated on Thu Jan 10 2013 14:56:49 for Linux Kernel by
1.8.2