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 handler routines
13 */
14#include <stdlib.h>
15#include <string.h>
16#include <stdio.h>
17#include <errno.h>
18#include <netinet/in.h>
19#include "l2tp.h"
20
21#define AVP_MAX 39
22
23struct avp avps[] = {
24
25    {0, 1, &message_type_avp, "Message Type"},
26    {1, 1, &result_code_avp, "Result Code"},
27    {2, 1, &protocol_version_avp, "Protocol Version"},
28    {3, 1, &framing_caps_avp, "Framing Capabilities"},
29    {4, 1, &bearer_caps_avp, "Bearer Capabilities"},
30    {5, 0, NULL, "Tie Breaker"},
31    {6, 0, &firmware_rev_avp, "Firmware Revision"},
32    {7, 0, &hostname_avp, "Host Name"},
33    {8, 1, &vendor_avp, "Vendor Name"},
34    {9, 1, &assigned_tunnel_avp, "Assigned Tunnel ID"},
35    {10, 1, &receive_window_size_avp, "Receive Window Size"},
36    {11, 1, &challenge_avp, "Challenge"},
37    {12, 0, NULL, "Q.931 Cause Code"},
38    {13, 1, &chalresp_avp, "Challenge Response"},
39    {14, 1, &assigned_call_avp, "Assigned Call ID"},
40    {15, 1, &call_serno_avp, "Call Serial Number"},
41    {16, 1, NULL, "Minimum BPS"},
42    {17, 1, NULL, "Maximum BPS"},
43    {18, 1, &bearer_type_avp, "Bearer Type"},
44    {19, 1, &frame_type_avp, "Framing Type"},
45    {20, 1, &packet_delay_avp, "Packet Processing Delay"},
46    {21, 1, &dialed_number_avp, "Dialed Number"},
47    {22, 1, &dialing_number_avp, "Dialing Number"},
48    {23, 1, &sub_address_avp, "Sub-Address"},
49    {24, 1, &tx_speed_avp, "Transmit Connect Speed"},
50    {25, 1, &call_physchan_avp, "Physical channel ID"},
51    {26, 0, NULL, "Initial Received LCP Confreq"},
52    {27, 0, NULL, "Last Sent LCP Confreq"},
53    {28, 0, NULL, "Last Received LCP Confreq"},
54    {29, 1, &ignore_avp, "Proxy Authen Type"},
55    {30, 0, &ignore_avp, "Proxy Authen Name"},
56    {31, 0, &ignore_avp, "Proxy Authen Challenge"},
57    {32, 0, &ignore_avp, "Proxy Authen ID"},
58    {33, 1, &ignore_avp, "Proxy Authen Response"},
59    {34, 1, NULL, "Call Errors"},
60    {35, 1, &ignore_avp, "ACCM"},
61    {36, 1, &rand_vector_avp, "Random Vector"},
62    {37, 1, NULL, "Private Group ID"},
63    {38, 0, &rx_speed_avp, "Receive Connect Speed"},
64    {39, 1, &seq_reqd_avp, "Sequencing Required"}
65};
66
67char *msgtypes[] = {
68    NULL,
69    "Start-Control-Connection-Request",
70    "Start-Control-Connection-Reply",
71    "Start-Control-Connection-Connected",
72    "Stop-Control-Connection-Notification",
73    NULL,
74    "Hello",
75    "Outgoing-Call-Request",
76    "Outgoing-Call-Reply",
77    "Outgoing-Call-Connected",
78    "Incoming-Call-Request",
79    "Incoming-Call-Reply",
80    "Incoming-Call-Connected",
81    NULL,
82    "Call-Disconnect-Notify",
83    "WAN-Error-Notify",
84    "Set-Link-Info"
85};
86
87char *stopccn_result_codes[] = {
88    "Reserved",
89    "General request to clear control connection",
90    "General error--Error Code indicates the problem",
91    "Control channel already exists",
92    "Requester is not authorized to establish a control channel",
93    "The protocol version of the requester is not supported--Error Code indicates the highest version supported",
94    "Requester is being shut down",
95    "Finite State Machine error"
96};
97
98char *cdn_result_codes[] = {
99    "Reserved",
100    "Call disconnected due to loss of carrier",
101    "Call disconnected for the reason indicated in error code",
102    "Call disconnected for administrative reasons",
103    "Call failed due to lack of appropriate facilities being available (temporary condition)",
104    "Call failed due to lack of appropriate facilities being available (permanent condition)",
105    "Invalid destination",
106    "Call failed due to no carrier detected",
107    "Call failed due to lack of a dial tone",
108    "Call was no established within time allotted by LAC",
109    "Call was connected but no appropriate framing was detect"
110};
111
112void wrong_length (struct call *c, char *field, int expected, int found,
113                   int min)
114{
115    if (min)
116        snprintf (c->errormsg, sizeof (c->errormsg),
117                  "%s: expected at least %d, got %d", field, expected, found);
118    else
119        snprintf (c->errormsg, sizeof (c->errormsg),
120                  "%s: expected %d, got %d", field, expected, found);
121
122    c->error = ERROR_LENGTH;
123    c->result = RESULT_ERROR;
124    c->needclose = -1;
125}
126
127/*
128 * t, c, data, and datalen may be assumed to be defined for all avp's
129 */
130
131int message_type_avp (struct tunnel *t, struct call *c, void *data,
132                      int datalen)
133{
134    /*
135     * This will be with every control message.  It is critical that this
136     * procedure check for the validity of sending this kind of a message
137     * (assuming sanity check)
138     */
139
140    _u16 *raw = data;
141    c->msgtype = ntohs (raw[3]);
142    if (datalen != 8)
143    {
144        if (DEBUG)
145            log (LOG_DEBUG, "%s: wrong size (%d != 8)\n", __FUNCTION__,
146                 datalen);
147        wrong_length (c, "Message Type", 8, datalen, 0);
148        return -EINVAL;
149    }
150    if ((c->msgtype > MAX_MSG) || (!msgtypes[c->msgtype]))
151    {
152        if (DEBUG)
153            log (LOG_DEBUG, "%s: unknown message type %d\n", __FUNCTION__,
154                 c->msgtype);
155        return -EINVAL;
156    }
157    if (debug_avp)
158        if (DEBUG)
159            log (LOG_DEBUG, "%s: message type %d (%s)\n", __FUNCTION__,
160                 c->msgtype, msgtypes[c->msgtype]);
161#ifdef SANITY
162    if (t->sanity)
163    {
164        /*
165         * Look ou our state for each message and make sure everything
166         * make sense...
167         */
168        if ((c != t->self) && (c->msgtype < Hello))
169        {
170            if (DEBUG)
171                log (LOG_DEBUG,
172                     "%s: attempting to negotiate tunnel inside a call!\n",
173                     __FUNCTION__);
174            return -EINVAL;
175        }
176
177        switch (c->msgtype)
178        {
179        case SCCRQ:
180            if ((t->state != 0) && (t->state != SCCRQ))
181            {
182                /*
183                 * When we handle tie breaker AVP's, then we'll check
184                 * to see if we've both requested tunnels
185                 */
186
187                if (DEBUG)
188                    log (LOG_DEBUG,
189                         "%s: attempting to negotiate SCCRQ with state != 0\n",
190                         __FUNCTION__);
191                return -EINVAL;
192            }
193            break;
194        case SCCRP:
195            if (t->state != SCCRQ)
196            {
197                if (DEBUG)
198                    log (LOG_DEBUG,
199                         "%s: attempting to negotiate SCCRP with state != SCCRQ!\n",
200                         __FUNCTION__);
201                return -EINVAL;
202            }
203            break;
204        case SCCCN:
205            if (t->state != SCCRP)
206            {
207                if (DEBUG)
208                    log (LOG_DEBUG,
209                         "%s: attempting to negotiate SCCCN with state != SCCRP!\n",
210                         __FUNCTION__);
211                return -EINVAL;
212            }
213            break;
214        case ICRQ:
215            if (t->state != SCCCN)
216            {
217                if (DEBUG)
218                    log (LOG_DEBUG,
219                         "%s: attempting to negotiate ICRQ when state != SCCCN\n",
220                         __FUNCTION__);
221                return -EINVAL;
222            }
223            if (c != t->self)
224            {
225                if (DEBUG)
226                    log (LOG_DEBUG,
227                         "%s: attempting to negotiate ICRQ on a call!\n",
228                         __FUNCTION__);
229                return -EINVAL;
230            }
231            break;
232        case ICRP:
233            if (t->state != SCCCN)
234            {
235                if (DEBUG)
236                    log (LOG_DEBUG,
237                         "%s: attempting to negotiate ICRP on tunnel!=SCCCN\n",
238                         __FUNCTION__);
239                return -EINVAL;
240            }
241            if (c->state != ICRQ)
242            {
243                if (DEBUG)
244                    log (LOG_DEBUG,
245                         "%s: attempting to negotiate ICRP when state != ICRQ\n",
246                         __FUNCTION__);
247                return -EINVAL;
248            }
249            break;
250        case ICCN:
251            if (c->state != ICRP)
252            {
253                if (DEBUG)
254                    log (LOG_DEBUG,
255                         "%s: attempting to negotiate ICCN when state != ICRP\n",
256                         __FUNCTION__);
257                return -EINVAL;
258            }
259            break;
260        case SLI:
261            if (c->state != ICCN)
262            {
263                if (DEBUG)
264                    log (LOG_DEBUG,
265                         "%s: attempting to negotiate SLI when state != ICCN\n",
266                         __FUNCTION__);
267                return -EINVAL;
268            }
269            break;
270        case OCRP:             /* jz: case for ORCP */
271            if (t->state != SCCCN)
272            {
273                if (DEBUG)
274                    log (LOG_DEBUG,
275                         "%s: attempting to negotiate OCRP on tunnel!=SCCCN\n",
276                         __FUNCTION__);
277                return -EINVAL;
278            }
279            if (c->state != OCRQ)
280            {
281                if (DEBUG)
282                    log (LOG_DEBUG,
283                         "%s: attempting to negotiate OCRP when state != OCRQ\n",
284                         __FUNCTION__);
285                return -EINVAL;
286            }
287            break;
288        case OCCN:             /* jz: case for OCCN */
289
290            if (c->state != OCRQ)
291            {
292                if (DEBUG)
293                    log (LOG_DEBUG,
294                         "%s: attempting to negotiate OCCN when state != OCRQ\n",
295                         __FUNCTION__);
296                return -EINVAL;
297            }
298            break;
299        case StopCCN:
300        case CDN:
301        case Hello:
302            break;
303        default:
304            log (LOG_WARN, "%s: i don't know how to handle %s messages\n",
305                 __FUNCTION__, msgtypes[c->msgtype]);
306            return -EINVAL;
307        }
308    }
309#endif
310    if (c->msgtype == ICRQ)
311    {
312        struct call *tmp;
313        if (debug_avp)
314        {
315            if (DEBUG)
316                log (LOG_DEBUG, "%s: new incoming call\n", __FUNCTION__);
317        }
318        tmp = new_call (t);
319        if (!tmp)
320        {
321            log (LOG_WARN, "%s: unable to create new call\n", __FUNCTION__);
322            return -EINVAL;
323        }
324        tmp->next = t->call_head;
325        t->call_head = tmp;
326        t->count++;
327        /*
328           * Is this still safe to assume that the head will always
329           * be the most recent call being negotiated?
330           * Probably...  FIXME anyway...
331         */
332
333    }
334    return 0;
335}
336
337int rand_vector_avp (struct tunnel *t, struct call *c, void *data,
338                     int datalen)
339{
340    int size;
341    _u16 *raw = (_u16 *) data;
342    size = (raw[0] & 0x0FFF) - 6;
343    if (t->sanity)
344    {
345        if (size < 0)
346        {
347            if (DEBUG)
348                log (LOG_DEBUG, "%s: Random vector too small (%d < 0)\n",
349                     __FUNCTION__, size);
350            wrong_length (c, "Random Vector", 6, datalen, 1);
351            return -EINVAL;
352        }
353        if (size > MAX_VECTOR_SIZE)
354        {
355            if (DEBUG)
356                log (LOG_DEBUG, "%s: Random vector too large (%d > %d)\n",
357                     __FUNCTION__, datalen, MAX_VECTOR_SIZE);
358            wrong_length (c, "Random Vector", 6, datalen, 1);
359            return -EINVAL;
360        }
361    }
362    if (debug_avp)
363        log (LOG_DEBUG, "%s: Random Vector of %d octets\n", __FUNCTION__,
364             size);
365    t->chal_us.vector = (unsigned char *) &raw[3];
366    t->chal_us.vector_len = size;
367    return 0;
368}
369
370int ignore_avp (struct tunnel *t, struct call *c, void *data, int datalen)
371{
372    /*
373     * The spec says we have to accept authentication information
374     * even if we just ignore it, so that's exactly what
375     * we're going to do at this point.  Proxy authentication is such
376     * a rediculous security threat anyway except from local
377     * controled machines.
378     *
379     * FIXME: I need to handle proxy authentication as an option.
380     * One option is to simply change the options we pass to pppd.
381     *
382     */
383    if (debug_avp)
384    {
385        if (DEBUG)
386            log (LOG_DEBUG, "%s : Ignoring AVP\n", __FUNCTION__);
387    }
388    return 0;
389}
390
391int seq_reqd_avp (struct tunnel *t, struct call *c, void *data, int datalen)
392{
393#ifdef SANITY
394    if (t->sanity)
395    {
396        if (datalen != 6)
397        {
398            if (DEBUG)
399                log (LOG_DEBUG,
400                     "%s: avp is incorrect size.  %d != 6\n", __FUNCTION__,
401                     datalen);
402            wrong_length (c, "Sequencing Required", 6, datalen, 1);
403            return -EINVAL;
404        }
405        switch (c->msgtype)
406        {
407        case ICCN:
408            break;
409        default:
410            if (DEBUG)
411                log (LOG_DEBUG,
412                     "%s: sequencing required not appropriate for %s!\n",
413                     __FUNCTION__, msgtypes[c->msgtype]);
414            return -EINVAL;
415        }
416    }
417#endif
418    if (debug_avp)
419    {
420        if (DEBUG)
421            log (LOG_DEBUG, "%s: peer requires sequencing.\n", __FUNCTION__);
422    }
423    c->seq_reqd = -1;
424    return 0;
425}
426
427int result_code_avp (struct tunnel *t, struct call *c, void *data,
428                     int datalen)
429{
430    /*
431     * Find out what version of l2tp the other side is using.
432     * I'm not sure what we're supposed to do with this but whatever..
433     */
434
435    int error;
436    int result;
437    _u16 *raw = data;
438#ifdef SANITY
439    if (t->sanity)
440    {
441        if (datalen < 10)
442        {
443            if (DEBUG)
444                log (LOG_DEBUG,
445                     "%s: avp is incorrect size.  %d < 10\n", __FUNCTION__,
446                     datalen);
447            wrong_length (c, "Result Code", 10, datalen, 1);
448            return -EINVAL;
449        }
450        switch (c->msgtype)
451        {
452        case CDN:
453        case StopCCN:
454            break;
455        default:
456            if (DEBUG)
457                log (LOG_DEBUG,
458                     "%s: result code not appropriate for %s.  Ignoring.\n",
459                     __FUNCTION__, msgtypes[c->msgtype]);
460            return 0;
461        }
462    }
463#endif
464    result = ntohs (raw[3]);
465    error = ntohs (raw[4]);
466    if ((c->msgtype == StopCCN) && ((result > 7) || (result < 1)))
467    {
468        if (DEBUG)
469            log (LOG_DEBUG,
470                 "%s: result code out of range (%d %d %d).  Ignoring.\n",
471                 __FUNCTION__, result, error, datalen);
472        return 0;
473    }
474
475    if ((c->msgtype == CDN) && ((result > 11) || (result < 1)))
476    {
477        if (DEBUG)
478            log (LOG_DEBUG,
479                 "%s: result code out of range (%d %d %d).  Ignoring.\n",
480                 __FUNCTION__, result, error, datalen);
481        return 0;
482    }
483
484    c->error = error;
485    c->result = result;
486    safe_copy (c->errormsg, (char *) &raw[5], datalen - 10);
487    if (debug_avp)
488    {
489        if (DEBUG && (c->msgtype == StopCCN))
490        {
491            log (LOG_DEBUG,
492                 "%s: peer closing for reason %d (%s), error = %d (%s)\n",
493                 __FUNCTION__, result, stopccn_result_codes[result], error,
494                 c->errormsg);
495        }
496        else
497        {
498            log (LOG_DEBUG,
499                 "%s: peer closing for reason %d (%s), error = %d (%s)\n",
500                 __FUNCTION__, result, cdn_result_codes[result], error,
501                 c->errormsg);
502        }
503    }
504    return 0;
505}
506
507int protocol_version_avp (struct tunnel *t, struct call *c, void *data,
508                          int datalen)
509{
510    /*
511     * Find out what version of l2tp the other side is using.
512     * I'm not sure what we're supposed to do with this but whatever..
513     */
514
515    int ver;
516    _u16 *raw = data;
517#ifdef SANITY
518    if (t->sanity)
519    {
520        if (datalen != 8)
521        {
522            if (DEBUG)
523                log (LOG_DEBUG,
524                     "%s: avp is incorrect size.  %d != 8\n", __FUNCTION__,
525                     datalen);
526            wrong_length (c, "Protocol Version", 8, datalen, 1);
527            return -EINVAL;
528        }
529        switch (c->msgtype)
530        {
531        case SCCRP:
532        case SCCRQ:
533            break;
534        default:
535            if (DEBUG)
536                log (LOG_DEBUG,
537                     "%s: protocol version not appropriate for %s.  Ignoring.\n",
538                     __FUNCTION__, msgtypes[c->msgtype]);
539            return 0;
540        }
541    }
542#endif
543    ver = ntohs (raw[3]);
544    if (debug_avp)
545    {
546        if (DEBUG)
547            log (LOG_DEBUG,
548                 "%s: peer is using version %d, revision %d.\n", __FUNCTION__,
549                 (ver >> 8), ver & 0xFF);
550    }
551    return 0;
552}
553
554int framing_caps_avp (struct tunnel *t, struct call *c, void *data,
555                      int datalen)
556{
557    /*
558     * Retrieve the framing capabilities
559     * from the peer
560     */
561
562    int caps;
563    _u16 *raw = data;
564
565#ifdef SANITY
566    if (t->sanity)
567    {
568        switch (c->msgtype)
569        {
570        case SCCRP:
571        case SCCRQ:
572            break;
573        default:
574            if (DEBUG)
575                log (LOG_DEBUG,
576                     "%s: framing capabilities not appropriate for %s.  Ignoring.\n",
577                     __FUNCTION__, msgtypes[c->msgtype]);
578            return 0;
579        }
580        if (datalen != 10)
581        {
582            if (DEBUG)
583                log (LOG_DEBUG,
584                     "%s: avp is incorrect size.  %d != 10\n", __FUNCTION__,
585                     datalen);
586            wrong_length (c, "Framming Capabilities", 10, datalen, 0);
587            return -EINVAL;
588        }
589    }
590#endif
591    caps = ntohs (raw[4]);
592    if (debug_avp)
593        if (DEBUG)
594            log (LOG_DEBUG,
595                 "%s: supported peer frames:%s%s\n", __FUNCTION__,
596                 caps & ASYNC_FRAMING ? " async" : "",
597                 caps & SYNC_FRAMING ? " sync" : "");
598    t->fc = caps & (ASYNC_FRAMING | SYNC_FRAMING);
599    return 0;
600}
601
602int bearer_caps_avp (struct tunnel *t, struct call *c, void *data,
603                     int datalen)
604{
605    /*
606     * What kind of bearer channels does our peer support?
607     */
608    int caps;
609    _u16 *raw = data;
610
611#ifdef SANITY
612    if (t->sanity)
613    {
614        switch (c->msgtype)
615        {
616        case SCCRP:
617        case SCCRQ:
618            break;
619        default:
620            if (DEBUG)
621                log (LOG_DEBUG,
622                     "%s: bearer capabilities not appropriate for message %s.  Ignoring.\n",
623                     __FUNCTION__, msgtypes[c->msgtype]);
624            return 0;
625        }
626        if (datalen != 10)
627        {
628            if (DEBUG)
629                log (LOG_DEBUG,
630                     "%s: avp is incorrect size.  %d != 10\n", __FUNCTION__,
631                     datalen);
632            wrong_length (c, "Bearer Capabilities", 10, datalen, 0);
633            return -EINVAL;
634        }
635    }
636#endif
637    caps = ntohs (raw[4]);
638    if (debug_avp)
639    {
640        if (DEBUG)
641        {
642            log (LOG_DEBUG,
643                 "%s: supported peer bearers:%s%s\n",
644                 __FUNCTION__,
645                 caps & ANALOG_BEARER ? " analog" : "",
646                 caps & DIGITAL_BEARER ? " digital" : "");
647        }
648
649    }
650    t->bc = caps & (ANALOG_BEARER | DIGITAL_BEARER);
651    return 0;
652}
653
654
655/* FIXME: I need to handle tie breakers eventually */
656
657int firmware_rev_avp (struct tunnel *t, struct call *c, void *data,
658                      int datalen)
659{
660    /*
661     * Report and record remote firmware version
662     */
663    int ver;
664    _u16 *raw = data;
665
666#ifdef SANITY
667    if (t->sanity)
668    {
669        switch (c->msgtype)
670        {
671        case SCCRP:
672        case SCCRQ:
673            break;
674        default:
675            if (DEBUG)
676                log (LOG_DEBUG,
677                     "%s: firmware revision not appropriate for message %s.  Ignoring.\n",
678                     __FUNCTION__, msgtypes[c->msgtype]);
679            return 0;
680        }
681        if (datalen != 8)
682        {
683            if (DEBUG)
684                log (LOG_DEBUG,
685                     "%s: avp is incorrect size.  %d != 8\n", __FUNCTION__,
686                     datalen);
687            wrong_length (c, "Firmware Revision", 8, datalen, 0);
688            return -EINVAL;
689        }
690    }
691#endif
692    ver = ntohs (raw[3]);
693    if (debug_avp)
694    {
695        if (DEBUG)
696            log (LOG_DEBUG,
697                 "%s: peer reports firmware version %d (0x%.4x)\n",
698                 __FUNCTION__, ver, ver);
699    }
700    t->firmware = ver;
701    return 0;
702}
703
704int bearer_type_avp (struct tunnel *t, struct call *c, void *data,
705                     int datalen)
706{
707    /*
708     * What kind of bearer channel is the call on?
709     */
710    int b;
711    _u16 *raw = data;
712
713#ifdef SANITY
714    if (t->sanity)
715    {
716        switch (c->msgtype)
717        {
718        case ICRQ:
719        case OCRQ:
720            break;
721        default:
722            if (DEBUG)
723                log (LOG_DEBUG,
724                     "%s: bearer type not appropriate for message %s.  Ignoring.\n",
725                     __FUNCTION__, msgtypes[c->msgtype]);
726            return 0;
727        }
728        if (datalen != 10)
729        {
730            if (DEBUG)
731                log (LOG_DEBUG,
732                     "%s: avp is incorrect size.  %d != 10\n", __FUNCTION__,
733                     datalen);
734            wrong_length (c, "Bearer Type", 10, datalen, 0);
735            return -EINVAL;
736        }
737    }
738#endif
739    b = ntohs (raw[4]);
740    if (debug_avp)
741    {
742        if (DEBUG)
743            log (LOG_DEBUG,
744                 "%s: peer bears:%s\n", __FUNCTION__,
745                 b & ANALOG_BEARER ? " analog" : "digital");
746    }
747    t->call_head->bearer = b;
748    return 0;
749}
750
751int frame_type_avp (struct tunnel *t, struct call *c, void *data, int datalen)
752{
753    /*
754     * What kind of frame channel is the call on?
755     */
756    int b;
757    _u16 *raw = data;
758
759#ifdef SANITY
760    if (t->sanity)
761    {
762        switch (c->msgtype)
763        {
764        case ICCN:
765        case OCRQ:
766        case OCCN:
767            break;
768        default:
769            if (DEBUG)
770                log (LOG_DEBUG,
771                     "%s: frame type not appropriate for message %s.  Ignoring.\n",
772                     __FUNCTION__, msgtypes[c->msgtype]);
773            return 0;
774        }
775        if (datalen != 10)
776        {
777            if (DEBUG)
778                log (LOG_DEBUG,
779                     "%s: avp is incorrect size.  %d != 10\n", __FUNCTION__,
780                     datalen);
781            wrong_length (c, "Frame Type", 10, datalen, 0);
782            return -EINVAL;
783        }
784    }
785#endif
786    b = ntohs (raw[4]);
787    if (debug_avp)
788    {
789        if (DEBUG)
790            log (LOG_DEBUG,
791                 "%s: peer uses:%s frames\n", __FUNCTION__,
792                 b & ASYNC_FRAMING ? " async" : "sync");
793    }
794    c->frame = b;
795    return 0;
796}
797
798int hostname_avp (struct tunnel *t, struct call *c, void *data, int datalen)
799{
800    /*
801     * What is the peer's name?
802     */
803    int size;
804    _u16 *raw = data;
805
806#ifdef SANITY
807    if (t->sanity)
808    {
809        switch (c->msgtype)
810        {
811        case SCCRP:
812        case SCCRQ:
813            break;
814        default:
815            if (DEBUG)
816                log (LOG_DEBUG,
817                     "%s: hostname not appropriate for message %s.  Ignoring.\n",
818                     __FUNCTION__, msgtypes[c->msgtype]);
819            return 0;
820        }
821        if (datalen < 6)
822        {
823            if (DEBUG)
824                log (LOG_DEBUG,
825                     "%s: avp is too small.  %d < 6\n", __FUNCTION__,
826                     datalen);
827            wrong_length (c, "Hostname", 6, datalen, 1);
828            return -EINVAL;
829        }
830    }
831#endif
832    size = raw[0] & 0x0FFF;
833    if (size > MAXSTRLEN - 1)
834    {
835        if (DEBUG)
836            log (LOG_DEBUG, "%s: truncating reported hostname (size is %d)\n",
837                 __FUNCTION__, size);
838        size = MAXSTRLEN - 1;
839    }
840    safe_copy (t->hostname, (char *) &raw[3], size - 6);
841    if (debug_avp)
842    {
843        if (DEBUG)
844            log (LOG_DEBUG,
845                 "%s: peer reports hostname '%s'\n", __FUNCTION__,
846                 t->hostname);
847    }
848    return 0;
849}
850
851int dialing_number_avp (struct tunnel *t, struct call *c, void *data,
852                        int datalen)
853{
854    /*
855     * What is the peer's name?
856     */
857    int size;
858    _u16 *raw = data;
859
860#ifdef SANITY
861    if (t->sanity)
862    {
863        switch (c->msgtype)
864        {
865        case ICRQ:
866            break;
867        default:
868            if (DEBUG)
869                log (LOG_DEBUG,
870                     "%s: dialing number not appropriate for message %s.  Ignoring.\n",
871                     __FUNCTION__, msgtypes[c->msgtype]);
872            return 0;
873        }
874        if (datalen < 6)
875        {
876            if (DEBUG)
877                log (LOG_DEBUG,
878                     "%s: avp is too small.  %d < 6\n", __FUNCTION__,
879                     datalen);
880            wrong_length (c, "Dialing Number", 6, datalen, 1);
881            return -EINVAL;
882        }
883    }
884#endif
885    size = raw[0] & 0x0FFF;
886    if (size > MAXSTRLEN - 1)
887    {
888        if (DEBUG)
889            log (LOG_DEBUG,
890                 "%s: truncating reported dialing number (size is %d)\n",
891                 __FUNCTION__, size);
892        size = MAXSTRLEN - 1;
893    }
894    safe_copy (t->call_head->dialing, (char *) &raw[3], size);
895    if (debug_avp)
896    {
897        if (DEBUG)
898            log (LOG_DEBUG,
899                 "%s: peer reports dialing number '%s'\n", __FUNCTION__,
900                 t->call_head->dialing);
901    }
902    return 0;
903}
904
905int dialed_number_avp (struct tunnel *t, struct call *c, void *data,
906                       int datalen)
907{
908    /*
909     * What is the peer's name?
910     */
911    int size;
912    _u16 *raw = data;
913
914#ifdef SANITY
915    if (t->sanity)
916    {
917        switch (c->msgtype)
918        {
919        case OCRQ:
920        case ICRQ:
921            break;
922        default:
923            if (DEBUG)
924                log (LOG_DEBUG,
925                     "%s: dialed number not appropriate for message %s.  Ignoring.\n",
926                     __FUNCTION__, msgtypes[c->msgtype]);
927            return 0;
928        }
929        if (datalen < 6)
930        {
931            if (DEBUG)
932                log (LOG_DEBUG,
933                     "%s: avp is too small.  %d < 6\n", __FUNCTION__,
934                     datalen);
935            wrong_length (c, "Dialed Number", 6, datalen, 1);
936            return -EINVAL;
937        }
938    }
939#endif
940    size = raw[0] & 0x0FFF;
941    if (size > MAXSTRLEN - 1)
942    {
943        if (DEBUG)
944            log (LOG_DEBUG,
945                 "%s: truncating reported dialed number (size is %d)\n",
946                 __FUNCTION__, size);
947        size = MAXSTRLEN - 1;
948    }
949    safe_copy (t->call_head->dialed, (char *) &raw[3], size);
950    if (debug_avp)
951    {
952        if (DEBUG)
953            log (LOG_DEBUG,
954                 "%s: peer reports dialed number '%s'\n", __FUNCTION__,
955                 t->call_head->dialed);
956    }
957    return 0;
958}
959
960int sub_address_avp (struct tunnel *t, struct call *c, void *data,
961                     int datalen)
962{
963    /*
964     * What is the peer's name?
965     */
966    int size;
967    _u16 *raw = data;
968
969#ifdef SANITY
970    if (t->sanity)
971    {
972        switch (c->msgtype)
973        {
974        case OCRP:
975        case ICRQ:
976            break;
977        default:
978            if (DEBUG)
979                log (LOG_DEBUG,
980                     "%s: sub_address not appropriate for message %s.  Ignoring.\n",
981                     __FUNCTION__, msgtypes[c->msgtype]);
982            return 0;
983        }
984        if (datalen < 6)
985        {
986            if (DEBUG)
987                log (LOG_DEBUG,
988                     "%s: avp is too small.  %d < 6\n", __FUNCTION__,
989                     datalen);
990            wrong_length (c, "Sub-address", 6, datalen, 1);
991            return -EINVAL;
992        }
993    }
994#endif
995    size = raw[0] & 0x0FFF;
996    if (size > MAXSTRLEN - 1)
997    {
998        if (DEBUG)
999            log (LOG_DEBUG,
1000                 "%s: truncating reported sub address (size is %d)\n",
1001                 __FUNCTION__, size);
1002        size = MAXSTRLEN - 1;
1003    }
1004    safe_copy (t->call_head->subaddy, (char *) &raw[3], size);
1005    if (debug_avp)
1006    {
1007        if (DEBUG)
1008            log (LOG_DEBUG,
1009                 "%s: peer reports subaddress '%s'\n", __FUNCTION__,
1010                 t->call_head->subaddy);
1011    }
1012    return 0;
1013}
1014
1015int vendor_avp (struct tunnel *t, struct call *c, void *data, int datalen)
1016{
1017    /*
1018     * What vendor makes the other end?
1019     */
1020    int size;
1021    _u16 *raw = data;
1022
1023#ifdef SANITY
1024    if (t->sanity)
1025    {
1026        switch (c->msgtype)
1027        {
1028        case SCCRP:
1029        case SCCRQ:
1030            break;
1031        default:
1032            if (DEBUG)
1033                log (LOG_DEBUG,
1034                     "%s: vendor not appropriate for message %s.  Ignoring.\n",
1035                     __FUNCTION__, msgtypes[c->msgtype]);
1036            return 0;
1037        }
1038        if (datalen < 6)
1039        {
1040            if (DEBUG)
1041                log (LOG_DEBUG,
1042                     "%s: avp is too small.  %d < 6\n", __FUNCTION__,
1043                     datalen);
1044            wrong_length (c, "Vendor", 6, datalen, 1);
1045            return -EINVAL;
1046        }
1047    }
1048#endif
1049    size = raw[0] & 0x0FFF;
1050    if (size > MAXSTRLEN - 1)
1051    {
1052        if (DEBUG)
1053            log (LOG_DEBUG, "%s: truncating reported vendor (size is %d)\n",
1054                 __FUNCTION__, size);
1055        size = MAXSTRLEN - 1;
1056    }
1057    safe_copy (t->vendor, (char *) &raw[3], size);
1058    if (debug_avp)
1059    {
1060        if (DEBUG)
1061            log (LOG_DEBUG,
1062                 "%s: peer reports vendor '%s'\n", __FUNCTION__, t->vendor);
1063    }
1064    return 0;
1065}
1066
1067int challenge_avp (struct tunnel *t, struct call *c, void *data, int datalen)
1068{
1069    /*
1070     * We are sent a challenge
1071     */
1072    _u16 *raw = data;
1073    int size;
1074#ifdef SANITY
1075    if (t->sanity)
1076    {
1077        switch (c->msgtype)
1078        {
1079        case SCCRP:
1080        case SCCRQ:
1081            break;
1082        default:
1083            if (DEBUG)
1084                log (LOG_DEBUG,
1085                     "%s: challenge not appropriate for message %s.  Ignoring.\n",
1086                     __FUNCTION__, msgtypes[c->msgtype]);
1087            return 0;
1088        }
1089        if (datalen < 6)
1090        {
1091            if (DEBUG)
1092                log (LOG_DEBUG,
1093                     "%s: avp is too small.  %d < 6\n", __FUNCTION__,
1094                     datalen);
1095            wrong_length (c, "challenge", 6, datalen, 1);
1096            return -EINVAL;
1097        }
1098    }
1099#endif
1100    /* size = raw[0] & 0x0FFF; */
1101    /* length field of AVP's is only 10 bits long, not 12 */
1102    size = raw[0] & 0x03FF;
1103    size -= sizeof (struct avp_hdr);
1104    /* if (size != MD_SIG_SIZE)
1105    {
1106        log (LOG_DEBUG, "%s: Challenge is not the right length (%d != %d)\n",
1107             __FUNCTION__, size, MD_SIG_SIZE);
1108        return -EINVAL;
1109    } */
1110    t->chal_us.challenge = malloc(size+1);
1111    if (t->chal_us.challenge == NULL)
1112    {
1113        return -ENOMEM;
1114    }
1115    memset(t->chal_us.challenge, 0, size+1);
1116    bcopy (&raw[3], (t->chal_us.challenge), size);
1117    t->chal_us.state = STATE_CHALLENGED;
1118    if (debug_avp)
1119    {
1120        log (LOG_DEBUG, "%s: challenge avp found\n", __FUNCTION__);
1121    }
1122    return 0;
1123}
1124
1125int chalresp_avp (struct tunnel *t, struct call *c, void *data, int datalen)
1126{
1127    /*
1128     * We are sent a challenge
1129     */
1130    _u16 *raw = data;
1131    int size;
1132#ifdef SANITY
1133    if (t->sanity)
1134    {
1135        switch (c->msgtype)
1136        {
1137        case SCCRP:
1138        case SCCCN:
1139            break;
1140        default:
1141            if (DEBUG)
1142                log (LOG_DEBUG,
1143                     "%s: challenge response not appropriate for message %s.  Ignoring.\n",
1144                     __FUNCTION__, msgtypes[c->msgtype]);
1145            return 0;
1146        }
1147        if (datalen < 6)
1148        {
1149            if (DEBUG)
1150                log (LOG_DEBUG,
1151                     "%s: avp is too small.  %d < 6\n", __FUNCTION__,
1152                     datalen);
1153            wrong_length (c, "challenge", 6, datalen, 1);
1154            return -EINVAL;
1155        }
1156    }
1157#endif
1158    size = raw[0] & 0x0FFF;
1159    size -= sizeof (struct avp_hdr);
1160    if (size != MD_SIG_SIZE)
1161    {
1162        log (LOG_DEBUG, "%s: Challenge is not the right length (%d != %d)\n",
1163             __FUNCTION__, size, MD_SIG_SIZE);
1164        return -EINVAL;
1165    }
1166
1167    bcopy (&raw[3], t->chal_them.reply, MD_SIG_SIZE);
1168    if (debug_avp)
1169    {
1170        log (LOG_DEBUG, "%s: Challenge reply found\n", __FUNCTION__);
1171    }
1172    return 0;
1173}
1174
1175int assigned_tunnel_avp (struct tunnel *t, struct call *c, void *data,
1176                         int datalen)
1177{
1178    /*
1179     * What is their TID that we must use from now on?
1180     */
1181    _u16 *raw = data;
1182
1183#ifdef SANITY
1184    if (t->sanity)
1185    {
1186        switch (c->msgtype)
1187        {
1188        case SCCRP:
1189        case SCCRQ:
1190        case StopCCN:
1191            break;
1192        default:
1193            if (DEBUG)
1194                log (LOG_DEBUG,
1195                     "%s: tunnel ID not appropriate for message %s.  Ignoring.\n",
1196                     __FUNCTION__, msgtypes[c->msgtype]);
1197            return 0;
1198        }
1199        if (datalen != 8)
1200        {
1201            if (DEBUG)
1202                log (LOG_DEBUG,
1203                     "%s: avp is wrong size.  %d != 8\n", __FUNCTION__,
1204                     datalen);
1205            wrong_length (c, "Assigned Tunnel ID", 8, datalen, 0);
1206            return -EINVAL;
1207        }
1208    }
1209#endif
1210    if (c->msgtype == StopCCN)
1211    {
1212        t->qtid = ntohs (raw[3]);
1213    }
1214    else
1215    {
1216        t->tid = ntohs (raw[3]);
1217    }
1218    if (debug_avp)
1219    {
1220        if (DEBUG)
1221            log (LOG_DEBUG,
1222                 "%s: using peer's tunnel %d\n", __FUNCTION__,
1223                 ntohs (raw[3]));
1224    }
1225    return 0;
1226}
1227
1228int assigned_call_avp (struct tunnel *t, struct call *c, void *data,
1229                       int datalen)
1230{
1231    /*
1232     * What is their CID that we must use from now on?
1233     */
1234    _u16 *raw = data;
1235
1236#ifdef SANITY
1237    if (t->sanity)
1238    {
1239        switch (c->msgtype)
1240        {
1241        case CDN:
1242        case ICRP:
1243        case ICRQ:
1244        case OCRP:             /* jz: deleting the debug message */
1245            break;
1246        case OCRQ:
1247        default:
1248            if (DEBUG)
1249                log (LOG_DEBUG,
1250                     "%s: call ID not appropriate for message %s.  Ignoring.\n",
1251                     __FUNCTION__, msgtypes[c->msgtype]);
1252            return 0;
1253        }
1254        if (datalen != 8)
1255        {
1256            if (DEBUG)
1257                log (LOG_DEBUG,
1258                     "%s: avp is wrong size.  %d != 8\n", __FUNCTION__,
1259                     datalen);
1260            wrong_length (c, "Assigned Call ID", 8, datalen, 0);
1261            return -EINVAL;
1262        }
1263    }
1264#endif
1265    if (c->msgtype == CDN)
1266    {
1267        c->qcid = ntohs (raw[3]);
1268    }
1269    else if (c->msgtype == ICRQ)
1270    {
1271        t->call_head->cid = ntohs (raw[3]);
1272    }
1273    else if (c->msgtype == ICRP)
1274    {
1275        c->cid = ntohs (raw[3]);
1276    }
1277    else if (c->msgtype == OCRP)
1278    {                           /* jz: copy callid to c->cid */
1279        c->cid = ntohs (raw[3]);
1280    }
1281    else
1282    {
1283        log (LOG_DEBUG, "%s:  Dunno what to do when it's state %s!\n",
1284             __FUNCTION__, msgtypes[c->msgtype]);
1285    }
1286    if (debug_avp)
1287    {
1288        if (DEBUG)
1289            log (LOG_DEBUG,
1290                 "%s: using peer's call %d\n", __FUNCTION__, ntohs (raw[3]));
1291    }
1292    return 0;
1293}
1294
1295int packet_delay_avp (struct tunnel *t, struct call *c, void *data,
1296                      int datalen)
1297{
1298    /*
1299     * What is their CID that we must use from now on?
1300     */
1301    _u16 *raw = data;
1302
1303#ifdef SANITY
1304    if (t->sanity)
1305    {
1306        switch (c->msgtype)
1307        {
1308        case ICRP:
1309        case OCRQ:
1310        case ICCN:
1311        case OCRP:
1312        case OCCN:
1313            break;
1314        default:
1315            if (DEBUG)
1316                log (LOG_DEBUG,
1317                     "%s: packet delay not appropriate for message %s.  Ignoring.\n",
1318                     __FUNCTION__, msgtypes[c->msgtype]);
1319            return 0;
1320        }
1321        if (datalen != 8)
1322        {
1323            if (DEBUG)
1324                log (LOG_DEBUG,
1325                     "%s: avp is wrong size.  %d != 8\n", __FUNCTION__,
1326                     datalen);
1327            wrong_length (c, "Assigned Call ID", 8, datalen, 0);
1328            return -EINVAL;
1329        }
1330    }
1331#endif
1332    c->ppd = ntohs (raw[3]);
1333    if (debug_avp)
1334    {
1335        if (DEBUG)
1336            log (LOG_DEBUG,
1337                 "%s: peer's delay is %d 1/10's of a second\n", __FUNCTION__,
1338                 ntohs (raw[3]));
1339    }
1340    return 0;
1341}
1342
1343int call_serno_avp (struct tunnel *t, struct call *c, void *data, int datalen)
1344{
1345    /*
1346     * What is the serial number of the call?
1347     */
1348    _u16 *raw = data;
1349
1350#ifdef SANITY
1351    if (t->sanity)
1352    {
1353        switch (c->msgtype)
1354        {
1355        case ICRQ:
1356        case OCRQ:
1357            break;
1358        default:
1359            if (DEBUG)
1360                log (LOG_DEBUG,
1361                     "%s: call ID not appropriate for message %s.  Ignoring.\n",
1362                     __FUNCTION__, msgtypes[c->msgtype]);
1363            return 0;
1364        }
1365        if (datalen != 10)
1366        {
1367#ifdef STRICT
1368            if (DEBUG)
1369                log (LOG_DEBUG,
1370                     "%s: avp is wrong size.  %d != 10\n", __FUNCTION__,
1371                     datalen);
1372            wrong_length (c, "Serial Number", 10, datalen, 0);
1373            return -EINVAL;
1374#else
1375            log (LOG_DEBUG,
1376                 "%s: peer is using old style serial number.  Will be invalid.\n",
1377                 __FUNCTION__);
1378#endif
1379
1380        }
1381    }
1382#endif
1383    t->call_head->serno = (((unsigned int) ntohs (raw[3])) << 16) |
1384        ((unsigned int) ntohs (raw[4]));
1385    if (debug_avp)
1386    {
1387        if (DEBUG)
1388            log (LOG_DEBUG,
1389                 "%s: serial number is %d\n", __FUNCTION__,
1390                 t->call_head->serno);
1391    }
1392    return 0;
1393}
1394
1395int rx_speed_avp (struct tunnel *t, struct call *c, void *data, int datalen)
1396{
1397    /*
1398     * What is the received baud rate of the call?
1399     */
1400    _u16 *raw = data;
1401
1402#ifdef SANITY
1403    if (t->sanity)
1404    {
1405        switch (c->msgtype)
1406        {
1407        case ICCN:
1408        case OCCN:
1409        case OCRP:
1410            break;
1411        default:
1412            if (DEBUG)
1413                log (LOG_DEBUG,
1414                     "%s: rx connect speed not appropriate for message %s.  Ignoring.\n",
1415                     __FUNCTION__, msgtypes[c->msgtype]);
1416            return 0;
1417        }
1418        if (datalen != 10)
1419        {
1420            if (DEBUG)
1421                log (LOG_DEBUG,
1422                     "%s: avp is wrong size.  %d != 10\n", __FUNCTION__,
1423                     datalen);
1424            wrong_length (c, "Connect Speed (RX)", 10, datalen, 0);
1425            return -EINVAL;
1426        }
1427    }
1428#endif
1429    c->rxspeed = (((unsigned int) ntohs (raw[3])) << 16) |
1430        ((unsigned int) ntohs (raw[4]));
1431    if (debug_avp)
1432    {
1433        if (DEBUG)
1434            log (LOG_DEBUG,
1435                 "%s: receive baud rate is %d\n", __FUNCTION__, c->rxspeed);
1436    }
1437    return 0;
1438}
1439
1440int tx_speed_avp (struct tunnel *t, struct call *c, void *data, int datalen)
1441{
1442    /*
1443     * What is the tranmsit baud rate of the call?
1444     */
1445    _u16 *raw = data;
1446
1447#ifdef SANITY
1448    if (t->sanity)
1449    {
1450        switch (c->msgtype)
1451        {
1452        case ICCN:
1453        case OCCN:
1454        case OCRP:
1455            break;
1456        default:
1457            if (DEBUG)
1458                log (LOG_DEBUG,
1459                     "%s: tx connect speed not appropriate for message %s.  Ignoring.\n",
1460                     __FUNCTION__, msgtypes[c->msgtype]);
1461            return 0;
1462        }
1463        if (datalen != 10)
1464        {
1465            if (DEBUG)
1466                log (LOG_DEBUG,
1467                     "%s: avp is wrong size.  %d != 10\n", __FUNCTION__,
1468                     datalen);
1469            wrong_length (c, "Connect Speed (tx)", 10, datalen, 0);
1470            return -EINVAL;
1471        }
1472    }
1473#endif
1474    c->txspeed = (((unsigned int) ntohs (raw[3])) << 16) |
1475        ((unsigned int) ntohs (raw[4]));
1476    if (debug_avp)
1477    {
1478        if (DEBUG)
1479            log (LOG_DEBUG,
1480                 "%s: transmit baud rate is %d\n", __FUNCTION__, c->txspeed);
1481    }
1482    return 0;
1483}
1484int call_physchan_avp (struct tunnel *t, struct call *c, void *data,
1485                       int datalen)
1486{
1487    /*
1488     * What is the physical channel?
1489     */
1490    _u16 *raw = data;
1491
1492#ifdef SANITY
1493    if (t->sanity)
1494    {
1495        switch (c->msgtype)
1496        {
1497        case ICRQ:
1498        case OCRQ:
1499        case OCRP:
1500        case OCCN:
1501            break;
1502        default:
1503            if (DEBUG)
1504                log (LOG_DEBUG,
1505                     "%s: physical channel not appropriate for message %s.  Ignoring.\n",
1506                     __FUNCTION__, msgtypes[c->msgtype]);
1507            return 0;
1508        }
1509        if (datalen != 10)
1510        {
1511            if (DEBUG)
1512                log (LOG_DEBUG,
1513                     "%s: avp is wrong size.  %d != 10\n", __FUNCTION__,
1514                     datalen);
1515            wrong_length (c, "Physical Channel", 10, datalen, 0);
1516            return -EINVAL;
1517        }
1518    }
1519#endif
1520    t->call_head->physchan = (((unsigned int) ntohs (raw[3])) << 16) |
1521        ((unsigned int) ntohs (raw[4]));
1522    if (debug_avp)
1523    {
1524        if (DEBUG)
1525            log (LOG_DEBUG,
1526                 "%s: physical channel is %d\n", __FUNCTION__,
1527                 t->call_head->physchan);
1528    }
1529    return 0;
1530}
1531
1532int receive_window_size_avp (struct tunnel *t, struct call *c, void *data,
1533                             int datalen)
1534{
1535    /*
1536     * What is their RWS?
1537     */
1538    _u16 *raw = data;
1539
1540#ifdef SANITY
1541    if (t->sanity)
1542    {
1543        switch (c->msgtype)
1544        {
1545        case SCCRP:
1546        case SCCRQ:
1547        case OCRP:             /* jz */
1548        case OCCN:             /* jz */
1549        case StopCCN:
1550/*		case ICRP:
1551		case ICCN: */
1552            break;
1553        default:
1554            if (DEBUG)
1555                log (LOG_DEBUG,
1556                     "%s: RWS not appropriate for message %s.  Ignoring.\n",
1557                     __FUNCTION__, msgtypes[c->msgtype]);
1558            return 0;
1559        }
1560        if (datalen != 8)
1561        {
1562            if (DEBUG)
1563                log (LOG_DEBUG,
1564                     "%s: avp is wrong size.  %d != 8\n", __FUNCTION__,
1565                     datalen);
1566            wrong_length (c, "Receive Window Size", 8, datalen, 0);
1567            return -EINVAL;
1568        }
1569    }
1570#endif
1571    t->rws = ntohs (raw[3]);
1572/*	if (c->rws >= 0)
1573		c->fbit = FBIT; */
1574    if (debug_avp)
1575    {
1576        if (DEBUG)
1577            log (LOG_DEBUG,
1578                 "%s: peer wants RWS of %d.  Will use flow control.\n",
1579                 __FUNCTION__, t->rws);
1580    }
1581    return 0;
1582}
1583
1584
1585int handle_avps (struct buffer *buf, struct tunnel *t, struct call *c)
1586{
1587    /*
1588     * buf's start should point to the beginning of a packet. We assume it's
1589     * a valid packet and has had check_control done to it, so no error
1590     * checking is done at this point.
1591     */
1592
1593    struct avp_hdr *avp;
1594    int len = buf->len - sizeof (struct control_hdr);
1595    int firstavp = -1;
1596    int hidlen;
1597    char *data = buf->start + sizeof (struct control_hdr);
1598    avp = (struct avp_hdr *) data;
1599    if (debug_avp)
1600        log (LOG_DEBUG, "%s: handling avp's for tunnel %d, call %d\n",
1601             __FUNCTION__, t->ourtid, c->ourcid);
1602    while (len > 0)
1603    {
1604        /* Go ahead and byte-swap the header */
1605        swaps (avp, sizeof (struct avp_hdr));
1606        if (avp->attr > AVP_MAX)
1607        {
1608            if (AMBIT (avp->length))
1609            {
1610                log (LOG_WARN,
1611                     "%s:  dont know how to handle mandatory attribute %d.  Closing %s.\n",
1612                     __FUNCTION__, avp->attr,
1613                     (c != t->self) ? "call" : "tunnel");
1614                set_error (c, VENDOR_ERROR,
1615                           "mandatory attribute %d cannot be handled",
1616                           avp->attr);
1617                c->needclose = -1;
1618                return -EINVAL;
1619            }
1620            else
1621            {
1622                if (DEBUG)
1623                    log (LOG_WARN,
1624                         "%s:  dont know how to handle atribute %d.\n",
1625                         __FUNCTION__, avp->attr);
1626                goto next;
1627            }
1628        }
1629        if (ALENGTH (avp->length) > len)
1630        {
1631            log (LOG_WARN,
1632                 "%s: AVP received with length > remaining packet length!\n",
1633                 __FUNCTION__);
1634            set_error (c, ERROR_LENGTH, "Invalid AVP length");
1635            c->needclose = -1;
1636            return -EINVAL;
1637        }
1638        if (avp->attr && firstavp)
1639        {
1640            log (LOG_WARN, "%s: First AVP was not message type.\n",
1641                 __FUNCTION__);
1642            set_error (c, VENDOR_ERROR, "First AVP must be message type");
1643            c->needclose = -1;
1644            return -EINVAL;
1645        }
1646        if (ALENGTH (avp->length) < sizeof (struct avp_hdr))
1647        {
1648            log (LOG_WARN, "%s: AVP with too small of size (%d).\n",
1649                 __FUNCTION__, ALENGTH (avp->length));
1650            set_error (c, ERROR_LENGTH, "AVP too small");
1651            c->needclose = -1;
1652            return -EINVAL;
1653        }
1654        if (AZBITS (avp->length))
1655        {
1656            log (LOG_WARN, "%s: %sAVP has reserved bits set.\n", __FUNCTION__,
1657                 AMBIT (avp->length) ? "Mandatory " : "");
1658            if (AMBIT (avp->length))
1659            {
1660                set_error (c, ERROR_RESERVED, "reserved bits set in AVP");
1661                c->needclose = -1;
1662                return -EINVAL;
1663            }
1664            goto next;
1665        }
1666        if (AHBIT (avp->length))
1667        {
1668#ifdef DEBUG_HIDDEN
1669            log (LOG_DEBUG, "%s: Hidden bit set on AVP.\n", __FUNCTION__);
1670#endif
1671            /* We want to rewrite the AVP as an unhidden AVP
1672               and then pass it along as normal.  Remeber how
1673               long the AVP was in the first place though! */
1674            hidlen = avp->length;
1675            if (decrypt_avp (data, t))
1676            {
1677                if (debug_avp)
1678                    log (LOG_WARN, "%s: Unable to handle hidden %sAVP\n:",
1679                         __FUNCTION__,
1680                         (AMBIT (avp->length) ? "mandatory " : ""));
1681                if (AMBIT (avp->length))
1682                {
1683                    set_error (c, VENDOR_ERROR, "Invalid Hidden AVP");
1684                    c->needclose = -1;
1685                    return -EINVAL;
1686                }
1687                goto next;
1688            };
1689            len -= 2;
1690            hidlen -= 2;
1691            data += 2;
1692            avp = (struct avp_hdr *) data;
1693            /* Now we should look like a normal AVP */
1694        }
1695        else
1696            hidlen = 0;
1697        if (avps[avp->attr].handler)
1698        {
1699            if (avps[avp->attr].handler (t, c, avp, ALENGTH (avp->length)))
1700            {
1701                if (AMBIT (avp->length))
1702                {
1703                    log (LOG_WARN,
1704                         "%s: Bad exit status handling attribute %d (%s) on mandatory packet.\n",
1705                         __FUNCTION__, avp->attr,
1706                         avps[avp->attr].description);
1707                    c->needclose = -1;
1708                    return -EINVAL;
1709                }
1710                else
1711                {
1712                    if (DEBUG)
1713                        log (LOG_DEBUG,
1714                             "%s: Bad exit status handling attribute %d (%s).\n",
1715                             __FUNCTION__, avp->attr,
1716                             avps[avp->attr].description);
1717                }
1718            }
1719        }
1720        else
1721        {
1722            if (AMBIT (avp->length))
1723            {
1724                log (LOG_WARN,
1725                     "%s:  No handler for mandatory attribute %d (%s).  Closing %s.\n",
1726                     __FUNCTION__, avp->attr, avps[avp->attr].description,
1727                     (c != t->self) ? "call" : "tunnel");
1728                set_error (c, VENDOR_ERROR, "No handler for attr %d (%s)\n",
1729                           avp->attr, avps[avp->attr].description);
1730                return -EINVAL;
1731            }
1732            else
1733            {
1734                if (DEBUG)
1735                    log (LOG_WARN, "%s:  no handler for atribute %d (%s).\n",
1736                         __FUNCTION__, avp->attr,
1737                         avps[avp->attr].description);
1738            }
1739        }
1740      next:
1741        if (hidlen)
1742        {
1743            /* Skip over the complete length of the hidden AVP */
1744            len -= ALENGTH (hidlen);
1745            data += ALENGTH (hidlen);
1746        }
1747        else
1748        {
1749            len -= ALENGTH (avp->length);
1750            data += ALENGTH (avp->length);      /* Next AVP, please */
1751        }
1752        avp = (struct avp_hdr *) data;
1753        firstavp = 0;
1754    }
1755    if (len != 0)
1756    {
1757        log (LOG_WARN, "%s: negative overall packet length\n", __FUNCTION__);
1758        return -EINVAL;
1759    }
1760    return 0;
1761}
1762