OSDN Git Service

2013.10.24
[uclinux-h8/uClinux-dist.git] / user / xl2tpd / avpsend.c
1 /*
2  * Layer Two Tunnelling Protocol Daemon
3  * Copyright (C) 1998 Adtran, Inc.
4  * Copyright (C) 2002 Jeff McAdams
5  *
6  * Mark Spencer
7  *
8  * This software is distributed under the terms
9  * of the GPL, which you should have received
10  * along with this source.
11  *
12  * Attribute Value Pair creating routines
13  */
14
15 #include <stdlib.h>
16 #include <string.h>
17 #include <netinet/in.h>
18 #include <sys/utsname.h>
19 #include "l2tp.h"
20
21 struct half_words {
22         _u16 s0;
23         _u16 s1;
24         _u16 s2;
25         _u16 s3;
26 } __attribute__ ((packed));
27
28 void add_header(struct buffer *buf, _u8 length, _u16 type) {
29         struct avp_hdr *avp = (struct avp_hdr *) (buf->start + buf->len);
30         avp->length = htons (length | MBIT);
31         avp->vendorid = htons (VENDOR_ID);
32         avp->attr = htons (type);
33 }
34
35 /* 
36  * These routines should add avp's to a buffer
37  * to be sent
38  */
39
40 /* FIXME:  If SANITY is on, we should check for buffer overruns */
41
42 int add_message_type_avp (struct buffer *buf, _u16 type)
43 {
44         struct half_words *ptr = (struct half_words *) (buf->start + buf->len + sizeof(struct avp_hdr));
45         add_header(buf, 0x8, 0);
46         ptr->s0 = htons(type);
47     buf->len += 0x8;
48     return 0;
49 }
50
51 int add_protocol_avp (struct buffer *buf)
52 {
53     struct half_words *ptr = (struct half_words *) (buf->start + buf->len + sizeof(struct avp_hdr));
54     add_header(buf, 0x8, 0x2);        /* Length and M bit */
55     ptr->s0 = htons (OUR_L2TP_VERSION);
56     buf->len += 0x8;
57     return 0;
58 }
59
60 int add_frame_caps_avp (struct buffer *buf, _u16 caps)
61 {
62     struct half_words *ptr = (struct half_words *) (buf->start + buf->len + sizeof(struct avp_hdr));
63     add_header(buf, 0xA, 0x3);
64     ptr->s0 = 0;
65     ptr->s1 = htons (caps);
66     buf->len += 0xA;
67     return 0;
68 }
69
70 int add_bearer_caps_avp (struct buffer *buf, _u16 caps)
71 {
72     struct half_words *ptr = (struct half_words *) (buf->start + buf->len + sizeof(struct avp_hdr));
73     add_header(buf, 0xA, 0x4);
74     ptr->s0 = 0;
75     ptr->s1 = htons (caps);
76     buf->len += 0xA;
77     return 0;
78 }
79
80 /* FIXME: I need to send tie breaker AVP's */
81
82 int add_firmware_avp (struct buffer *buf)
83 {
84     struct half_words *ptr = (struct half_words *) (buf->start + buf->len + sizeof(struct avp_hdr));
85     add_header(buf, 0x8, 0x6);
86     ptr->s0 = htons (FIRMWARE_REV);
87     buf->len += 0x8;
88     return 0;
89 }
90
91 int add_hostname_avp (struct buffer *buf, const char *hostname)
92 {
93     size_t namelen = strlen(hostname);
94     if (namelen > MAXAVPSIZE - 6) {
95         namelen = MAXAVPSIZE - 6;
96     }
97     add_header(buf, 0x6 + namelen, 0x7);
98     strncpy ((char *) (buf->start + buf->len + sizeof(struct avp_hdr)),
99              hostname, namelen);
100     buf->len += 0x6 + namelen;
101     return 0;
102 }
103
104 int add_vendor_avp (struct buffer *buf)
105 {
106     add_header(buf, 0x6 + strlen (VENDOR_NAME), 0x8);
107     strcpy ((char *) (buf->start + buf->len + sizeof(struct avp_hdr)), VENDOR_NAME);
108     buf->len += 0x6 + strlen (VENDOR_NAME);
109     return 0;
110 }
111
112 int add_tunnelid_avp (struct buffer *buf, _u16 tid)
113 {
114     struct half_words *ptr = (struct half_words *) (buf->start + buf->len + sizeof(struct avp_hdr));
115     add_header(buf, 0x8, 0x9);
116     ptr->s0 = htons (tid);
117     buf->len += 0x8;
118     return 0;
119 }
120
121 int add_avp_rws (struct buffer *buf, _u16 rws)
122 {
123     struct half_words *ptr = (struct half_words *) (buf->start + buf->len + sizeof(struct avp_hdr));
124     add_header(buf, 0x8, 0xA);
125     ptr->s0 = htons (rws);
126     buf->len += 0x8;
127     return 0;
128 }
129
130 int add_challenge_avp (struct buffer *buf, unsigned char *c, int len)
131 {
132     add_header(buf, (0x6 + len), 0xB);
133     memcpy((char *) (buf->start + buf->len + sizeof(struct avp_hdr)), c, len);
134     buf->len += 0x6 + len;
135     return 0;
136 }
137
138 int add_chalresp_avp (struct buffer *buf, unsigned char *c, int len)
139 {
140     add_header(buf, (0x6 + len), 0xD);
141     memcpy((char *) (buf->start + buf->len + sizeof(struct avp_hdr)), c, len);
142     buf->len += 0x6 + len;
143     return 0;
144 }
145
146 int add_randvect_avp (struct buffer *buf, unsigned char *c, int len)
147 {
148     add_header(buf, (0x6 + len), 0x24);
149     memcpy((char *) (buf->start + buf->len + sizeof(struct avp_hdr)), c, len);
150     buf->len += 0x6 + len;
151     return 0;
152 }
153
154 int add_result_code_avp (struct buffer *buf, _u16 result, _u16 error,
155                          char *msg, int len)
156 {
157     struct half_words *ptr = (struct half_words *) (buf->start + buf->len + sizeof(struct avp_hdr));
158     add_header(buf, (0xA + len), 0x1);
159     ptr->s0 = htons (result);
160     ptr->s1 = htons (error);
161     memcpy ((char *) &ptr->s2, msg, len);
162     buf->len += 0xA + len;
163     return 0;
164 }
165
166 #ifdef TEST_HIDDEN
167 int add_callid_avp (struct buffer *buf, _u16 callid, struct tunnel *t)
168 {
169 #else
170 int add_callid_avp (struct buffer *buf, _u16 callid)
171 {
172 #endif
173     struct half_words *ptr = (struct half_words *) (buf->start + buf->len + sizeof(struct avp_hdr));
174 #ifdef TEST_HIDDEN
175     if (t->hbit)
176         raw++;
177 #endif
178     add_header(buf, 0x8, 0xE);
179     ptr->s0 = htons (callid);
180     buf->len += 0x8;
181 #ifdef TEST_HIDDEN
182     if (t->hbit)
183         encrypt_avp (buf, 8, t);
184 #endif
185     return 0;
186 }
187
188 int add_serno_avp (struct buffer *buf, unsigned int serno)
189 {
190     struct half_words *ptr = (struct half_words *) (buf->start + buf->len + sizeof(struct avp_hdr));
191     add_header(buf, 0xA, 0xF);
192     ptr->s0 = htons ((serno >> 16) & 0xFFFF);
193     ptr->s1 = htons (serno & 0xFFFF);
194     buf->len += 0xA;
195     return 0;
196 }
197
198 int add_bearer_avp (struct buffer *buf, int bearer)
199 {
200     struct half_words *ptr = (struct half_words *) (buf->start + buf->len + sizeof(struct avp_hdr));
201     add_header(buf, 0xA, 0x12);
202     ptr->s0 = htons ((bearer >> 16) & 0xFFFF);
203     ptr->s1 = htons (bearer & 0xFFFF);
204     buf->len += 0xA;
205     return 0;
206 }
207
208 int add_frame_avp (struct buffer *buf, int frame)
209 {
210     struct half_words *ptr = (struct half_words *) (buf->start + buf->len + sizeof(struct avp_hdr));
211     add_header(buf, 0xA, 0x13);
212     ptr->s0 = htons ((frame >> 16) & 0xFFFF);
213     ptr->s1 = htons (frame & 0xFFFF);
214     buf->len += 0xA;
215     return 0;
216 }
217
218 int add_txspeed_avp (struct buffer *buf, int speed)
219 {
220     struct half_words *ptr = (struct half_words *) (buf->start + buf->len + sizeof(struct avp_hdr));
221     add_header(buf, 0xA, 0x18);
222     ptr->s0 = htons ((speed >> 16) & 0xFFFF);
223     ptr->s1 = htons (speed & 0xFFFF);
224     buf->len += 0xA;
225     return 0;
226 }
227
228 int add_rxspeed_avp (struct buffer *buf, int speed)
229 {
230     struct half_words *ptr = (struct half_words *) (buf->start + buf->len + sizeof(struct avp_hdr));
231     add_header(buf, 0xA, 0x26);
232     ptr->s0 = htons ((speed >> 16) & 0xFFFF);
233     ptr->s1 = htons (speed & 0xFFFF);
234     buf->len += 0xA;
235     return 0;
236 }
237
238 int add_physchan_avp (struct buffer *buf, unsigned int physchan)
239 {
240     struct half_words *ptr = (struct half_words *) (buf->start + buf->len + sizeof(struct avp_hdr));
241     add_header(buf, 0xA, 0x19);
242     ptr->s0 = htons ((physchan >> 16) & 0xFFFF);
243     ptr->s1 = htons (physchan & 0xFFFF);
244     buf->len += 0xA;
245     return 0;
246 }
247
248 int add_ppd_avp (struct buffer *buf, _u16 ppd)
249 {
250     struct half_words *ptr = (struct half_words *) (buf->start + buf->len + sizeof(struct avp_hdr));
251     add_header(buf, 0x8, 0x14);
252     ptr->s0 = htons (ppd);
253     buf->len += 0x8;
254     return 0;
255 }
256
257 int add_seqreqd_avp (struct buffer *buf)
258 {
259     add_header(buf, 0x6, 0x27);
260     buf->len += 0x6;
261     return 0;
262 }
263
264 /* jz: options dor the outgoing call */
265
266 /* jz: Minimum BPS - 16 */
267 int add_minbps_avp (struct buffer *buf, int speed)
268 {
269     struct half_words *ptr = (struct half_words *) (buf->start + buf->len + sizeof(struct avp_hdr));
270     add_header(buf, 0xA, 0x10);
271     ptr->s0 = htons ((speed >> 16) & 0xFFFF);
272     ptr->s1 = htons (speed & 0xFFFF);
273     buf->len += 0xA;
274     return 0;
275 }
276
277 /* jz: Maximum BPS - 17 */
278 int add_maxbps_avp (struct buffer *buf, int speed)
279 {
280     struct half_words *ptr = (struct half_words *) (buf->start + buf->len + sizeof(struct avp_hdr));
281     add_header(buf, 0xA, 0x11);
282     ptr->s0 = htons ((speed >> 16) & 0xFFFF);
283     ptr->s1 = htons (speed & 0xFFFF);
284     buf->len += 0xA;
285     return 0;
286 }
287
288 /* jz: Dialed Number 21 */
289 int add_number_avp (struct buffer *buf, char *no)
290 {
291     add_header(buf, (0x6 + strlen (no)), 0x15);
292     strncpy ((char *) (buf->start + buf->len + sizeof(struct avp_hdr)), no, strlen (no));
293     buf->len += 0x6 + strlen (no);
294     return 0;
295 }