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 "l2tp.h"
19
20/*
21 * These routines should add avp's to a buffer
22 * to be sent
23 */
24
25
26/* FIXME:  If SANITY is on, we should check for buffer overruns */
27
28/* FIXME: Can't this be condensed alot? */
29
30int add_message_type_avp (struct buffer *buf, _u16 type)
31{
32    _u16 *raw = (_u16 *) (buf->start + buf->len);
33    raw[0] = htons (0x8 | MBIT);
34    raw[1] = htons (VENDOR_ID);
35    raw[2] = 0;
36    raw[3] = htons (type);
37    buf->len += 8;
38    return 0;
39}
40
41int add_protocol_avp (struct buffer *buf)
42{
43    _u16 *raw = (_u16 *) (buf->start + buf->len);
44    raw[0] = htons (0x8 | MBIT);        /* Length and M bit */
45    raw[1] = htons (VENDOR_ID);
46    raw[2] = htons (0x2);       /* Value of our AVP */
47    raw[3] = htons (OUR_L2TP_VERSION);
48    buf->len += 8;
49    return 0;
50}
51
52int add_frame_caps_avp (struct buffer *buf, _u16 caps)
53{
54    _u16 *raw = (_u16 *) (buf->start + buf->len);
55    raw[0] = htons (0xA | MBIT);
56    raw[1] = htons (VENDOR_ID);
57    raw[2] = htons (0x3);
58    raw[3] = 0;
59    raw[4] = htons (caps);
60    buf->len += 10;
61    return 0;
62}
63
64int add_bearer_caps_avp (struct buffer *buf, _u16 caps)
65{
66    _u16 *raw = (_u16 *) (buf->start + buf->len);
67    raw[0] = htons (0xA | MBIT);
68    raw[1] = htons (VENDOR_ID);
69    raw[2] = htons (0x4);
70    raw[3] = 0;
71    raw[4] = htons (caps);
72    buf->len += 10;
73    return 0;
74}
75
76/* FIXME: I need to send tie breaker AVP's */
77
78int add_firmware_avp (struct buffer *buf)
79{
80    _u16 *raw = (_u16 *) (buf->start + buf->len);
81    raw[0] = htons (0x8);
82    raw[1] = htons (VENDOR_ID);
83    raw[2] = htons (0x6);
84    raw[3] = htons (FIRMWARE_REV);
85    buf->len += 8;
86    return 0;
87}
88
89/*
90int add_hostname_avp(struct buffer *buf) {
91	_u16 *raw = (_u16 *)(buf->start + buf->len);
92	raw[0] = htons((0x6 + strlen(hostname)) | MBIT);
93	raw[1] = htons(VENDOR_ID);
94	raw[2] = htons(0x7);
95	strcpy((char *)(&raw[3]), hostname);
96	buf->len += 6 + strlen(hostname);
97	return 0;
98}
99*/
100
101int add_hostname_avp (struct buffer *buf)
102{
103    char names[6] = "eriwan";
104    _u16 *raw = (_u16 *) (buf->start + buf->len);
105    raw[0] = htons (0xC | MBIT);
106    raw[1] = htons (VENDOR_ID);
107    raw[2] = htons (0x7);
108    strcpy ((char *) (&raw[3]), names);
109    buf->len += 12;
110    return 0;
111}
112
113int add_vendor_avp (struct buffer *buf)
114{
115    _u16 *raw = (_u16 *) (buf->start + buf->len);
116    raw[0] = htons (0x6 + strlen (VENDOR_NAME));
117    raw[1] = htons (VENDOR_ID);
118    raw[2] = htons (0x8);
119    strcpy ((char *) (&raw[3]), VENDOR_NAME);
120    buf->len += 6 + strlen (VENDOR_NAME);
121    return 0;
122}
123
124int add_tunnelid_avp (struct buffer *buf, _u16 tid)
125{
126    _u16 *raw = (_u16 *) (buf->start + buf->len);
127    raw[0] = htons (0x8 | MBIT);
128    raw[1] = htons (VENDOR_ID);
129    raw[2] = htons (0x9);
130    raw[3] = htons (tid);
131    buf->len += 8;
132    return 0;
133}
134
135int add_avp_rws (struct buffer *buf, _u16 rws)
136{
137    _u16 *raw = (_u16 *) (buf->start + buf->len);
138    raw[0] = htons (0x8 | MBIT);
139    raw[1] = htons (VENDOR_ID);
140    raw[2] = htons (0xA);
141    raw[3] = htons (rws);
142    buf->len += 8;
143    return 0;
144}
145
146int add_challenge_avp (struct buffer *buf, char *c, int len)
147{
148    _u16 *raw = (_u16 *) (buf->start + buf->len);
149    raw[0] = htons ((0x6 + len) | MBIT);
150    raw[1] = htons (VENDOR_ID);
151    raw[2] = htons (0xB);
152    bcopy (c, (char *) (&raw[3]), len);
153    buf->len += 6 + len;
154    return 0;
155}
156
157int add_chalresp_avp (struct buffer *buf, char *c, int len)
158{
159    _u16 *raw = (_u16 *) (buf->start + buf->len);
160    raw[0] = htons ((0x6 + len) | MBIT);
161    raw[1] = htons (VENDOR_ID);
162    raw[2] = htons (0xD);
163    bcopy (c, (char *) (&raw[3]), len);
164    buf->len += 6 + len;
165    return 0;
166}
167
168int add_randvect_avp (struct buffer *buf, char *c, int len)
169{
170    _u16 *raw = (_u16 *) (buf->start + buf->len);
171    raw[0] = htons ((0x6 + len) | MBIT);
172    raw[1] = htons (VENDOR_ID);
173    raw[2] = htons (0x24);
174    bcopy (c, (char *) (&raw[3]), len);
175    buf->len += 6 + len;
176    return 0;
177}
178
179int add_result_code_avp (struct buffer *buf, _u16 result, _u16 error,
180                         char *msg, int len)
181{
182    _u16 *raw = (_u16 *) (buf->start + buf->len);
183    raw[0] = htons ((0xA + len) | MBIT);
184    raw[1] = htons (VENDOR_ID);
185    raw[2] = htons (0x1);
186    raw[3] = htons (result);
187    raw[4] = htons (error);
188    bcopy (msg, (char *) &raw[5], len);
189    buf->len += (10 + len);
190    return 0;
191}
192
193#ifdef TEST_HIDDEN
194int add_callid_avp (struct buffer *buf, _u16 callid, struct tunnel *t)
195{
196#else
197int add_callid_avp (struct buffer *buf, _u16 callid)
198{
199#endif
200    _u16 *raw = (_u16 *) (buf->start + buf->len);
201#ifdef TEST_HIDDEN
202    if (t->hbit)
203        raw++;
204#endif
205    raw[0] = htons (0x8 | MBIT);
206    raw[1] = htons (VENDOR_ID);
207    raw[2] = htons (0xE);
208    raw[3] = htons (callid);
209    buf->len += 8;
210#ifdef TEST_HIDDEN
211    if (t->hbit)
212        encrypt_avp (buf, 8, t);
213#endif
214    return 0;
215}
216
217int add_serno_avp (struct buffer *buf, unsigned int serno)
218{
219    _u16 *raw = (_u16 *) (buf->start + buf->len);
220    raw[0] = htons (0xA | MBIT);
221    raw[1] = htons (VENDOR_ID);
222    raw[2] = htons (0xF);
223    raw[3] = htons ((serno >> 16) & 0xFFFF);
224    raw[4] = htons (serno & 0xFFFF);
225    buf->len += 10;
226    return 0;
227}
228
229int add_bearer_avp (struct buffer *buf, int bearer)
230{
231    _u16 *raw = (_u16 *) (buf->start + buf->len);
232    raw[0] = htons (0xA | MBIT);
233    raw[1] = htons (VENDOR_ID);
234    raw[2] = htons (0x12);
235    raw[3] = htons ((bearer >> 16) & 0xFFFF);
236    raw[4] = htons (bearer & 0xFFFF);
237    buf->len += 10;
238    return 0;
239}
240
241int add_frame_avp (struct buffer *buf, int frame)
242{
243    _u16 *raw = (_u16 *) (buf->start + buf->len);
244    raw[0] = htons (0xA | MBIT);
245    raw[1] = htons (VENDOR_ID);
246    raw[2] = htons (0x13);
247    raw[3] = htons ((frame >> 16) & 0xFFFF);
248    raw[4] = htons (frame & 0xFFFF);
249    buf->len += 10;
250    return 0;
251}
252
253int add_txspeed_avp (struct buffer *buf, int speed)
254{
255    _u16 *raw = (_u16 *) (buf->start + buf->len);
256    raw[0] = htons (0xA | MBIT);
257    raw[1] = htons (VENDOR_ID);
258    raw[2] = htons (0x18);
259    raw[3] = htons ((speed >> 16) & 0xFFFF);
260    raw[4] = htons (speed & 0xFFFF);
261    buf->len += 10;
262    return 0;
263}
264
265int add_rxspeed_avp (struct buffer *buf, int speed)
266{
267    _u16 *raw = (_u16 *) (buf->start + buf->len);
268    raw[0] = htons (0xA | MBIT);
269    raw[1] = htons (VENDOR_ID);
270    raw[2] = htons (0x26);
271    raw[3] = htons ((speed >> 16) & 0xFFFF);
272    raw[4] = htons (speed & 0xFFFF);
273    buf->len += 10;
274    return 0;
275}
276
277int add_physchan_avp (struct buffer *buf, unsigned int physchan)
278{
279    _u16 *raw = (_u16 *) (buf->start + buf->len);
280    raw[0] = htons (0x8 | MBIT);
281    raw[1] = htons (VENDOR_ID);
282    raw[2] = htons (0x19);
283    raw[3] = htons ((physchan >> 16) & 0xFFFF);
284    raw[4] = htons (physchan & 0xFFFF);
285    buf->len += 10;
286    return 0;
287}
288
289int add_ppd_avp (struct buffer *buf, _u16 ppd)
290{
291    _u16 *raw = (_u16 *) (buf->start + buf->len);
292    raw[0] = htons (0x8 | MBIT);
293    raw[1] = htons (VENDOR_ID);
294    raw[2] = htons (0x14);
295    raw[3] = htons (ppd);
296    buf->len += 8;
297    return 0;
298}
299
300int add_seqreqd_avp (struct buffer *buf)
301{
302    _u16 *raw = (_u16 *) (buf->start + buf->len);
303    raw[0] = htons (0x6 | MBIT);
304    raw[1] = htons (VENDOR_ID);
305    raw[2] = htons (0x27);
306    buf->len += 6;
307    return 0;
308}
309
310/* jz: options dor the outgoing call */
311
312/* jz: Minimum BPS - 16 */
313int add_minbps_avp (struct buffer *buf, int speed)
314{
315    _u16 *raw = (_u16 *) (buf->start + buf->len);
316    raw[0] = htons (0xA | MBIT);
317    raw[1] = htons (VENDOR_ID);
318    raw[2] = htons (0x10);
319    raw[3] = htons ((speed >> 16) & 0xFFFF);
320    raw[4] = htons (speed & 0xFFFF);
321    buf->len += 10;
322    return 0;
323}
324
325/* jz: Maximum BPS - 17 */
326int add_maxbps_avp (struct buffer *buf, int speed)
327{
328    _u16 *raw = (_u16 *) (buf->start + buf->len);
329    raw[0] = htons (0xA | MBIT);
330    raw[1] = htons (VENDOR_ID);
331    raw[2] = htons (0x11);
332    raw[3] = htons ((speed >> 16) & 0xFFFF);
333    raw[4] = htons (speed & 0xFFFF);
334    buf->len += 10;
335    return 0;
336}
337
338/* jz: Dialed Number 21 */
339int add_number_avp (struct buffer *buf, char *no)
340{
341    _u16 *raw = (_u16 *) (buf->start + buf->len);
342    raw[0] = htons ((0x6 + strlen (no)) | MBIT);
343    raw[1] = htons (VENDOR_ID);
344    raw[2] = htons (0x15);
345    strncpy ((char *) (&(raw[3])), no, strlen (no));
346    buf->len += 6 + strlen (no);
347    return 0;
348}
349