1 /* $OpenBSD: l2tp_subr.h,v 1.6 2013/09/20 07:26:23 yasuoka Exp $ */
2
3 /*-
4 * Copyright (c) 2009 Internet Initiative Japan Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28 #ifndef L2TP_SUBR_H
29 #define L2TP_SUBR_H 1
30 /* $Id: l2tp_subr.h,v 1.6 2013/09/20 07:26:23 yasuoka Exp $ */
31
32 /**
33 * structure of L2TP Attribute Value Pair (AVP) packet header
34 */
35 struct l2tp_avp
36 {
37 #if BYTE_ORDER == LITTLE_ENDIAN
38 uint16_t length:10,
39 rsvd:4,
40 is_hidden:1,
41 is_mandatory:1;
42 #else
43 uint16_t is_mandatory:1,
44 is_hidden:1,
45 rsvd:4,
46 length:10;
47 #endif
48 uint16_t vendor_id;
49 uint16_t attr_type;
50 u_char attr_value[0];
51 } __attribute__((__packed__)) ;
52
53 #define avp_attr_length(avp) ((avp)->length - 6)
54
55 static inline uint16_t
avp_get_val16(struct l2tp_avp * avp)56 avp_get_val16(struct l2tp_avp *avp)
57 {
58 return (avp->attr_value[0] << 8) | avp->attr_value[1];
59 }
60 static inline uint32_t
avp_get_val32(struct l2tp_avp * avp)61 avp_get_val32(struct l2tp_avp *avp)
62 {
63 return (avp->attr_value[0] << 24) | (avp->attr_value[1] << 16) |
64 (avp->attr_value[2] << 8) | avp->attr_value[3];
65 }
66
67 static inline void
avp_set_val16(struct l2tp_avp * avp,uint16_t val)68 avp_set_val16(struct l2tp_avp *avp, uint16_t val)
69 {
70 avp->attr_value[0] = val >> 8;
71 avp->attr_value[1] = val & 0xff;
72 }
73
74 static inline void
avp_set_val32(struct l2tp_avp * avp,uint32_t val)75 avp_set_val32(struct l2tp_avp *avp, uint32_t val)
76 {
77 avp->attr_value[0] = val >> 24;
78 avp->attr_value[1] = val >> 16;
79 avp->attr_value[2] = val >> 8;
80 avp->attr_value[3] = val & 0xff;
81 }
82
83 static inline int
short_cmp(const void * m,const void * n)84 short_cmp(const void *m, const void *n)
85 {
86 return ((intptr_t)m - (intptr_t)n);
87 }
88
89 static inline uint32_t
short_hash(const void * v,int sz)90 short_hash(const void *v, int sz)
91 {
92 return ((uintptr_t)v % sz);
93 }
94
95 /*
96 * macro to check AVP size.
97 * Prepare 1) char array `emes' for error message, 2) size_check_failed label
98 * before use this macro.
99 */
100 #define AVP_SIZE_CHECK(_avp, _op, _exp) \
101 do { \
102 if (!((_avp)->length _op (_exp))) { \
103 snprintf(emes, sizeof(emes), \
104 "invalid packet size %s %d" #_op "%d)", \
105 avp_attr_type_string((_avp)->attr_type), \
106 (_avp)->length, (_exp)); \
107 goto size_check_failed; \
108 } \
109 } while (/* CONSTCOND */0)
110 #define AVP_MAXLEN_CHECK(_avp, _maxlen) \
111 do { \
112 if ((_avp)->length > (_maxlen) + 6) { \
113 snprintf(emes, sizeof(emes), \
114 "Attribute value is too long %s %d > %d", \
115 avp_attr_type_string((_avp)->attr_type), \
116 (_avp)->length - 6, (int)(_maxlen)); \
117 goto size_check_failed; \
118 } \
119 } while (/* CONSTCOND */0)
120
121 #ifdef __cplusplus
122 extern "C" {
123 #endif
124
125 int avp_enum (struct l2tp_avp *, const u_char *, int, int);
126 const char *avp_attr_type_string (int);
127 struct l2tp_avp *avp_find_message_type_avp(struct l2tp_avp *, const u_char *, int);
128 struct l2tp_avp *avp_find(struct l2tp_avp *, const u_char *, int, uint16_t, uint16_t, int);
129 int bytebuf_add_avp (bytebuffer *, struct l2tp_avp *, int);
130 const char *avp_mes_type_string (int);
131 const char * l2tp_cdn_rcode_string(int);
132 const char * l2tp_stopccn_rcode_string(int);
133 const char * l2tp_ecode_string(int);
134
135 #ifdef __cplusplus
136 }
137 #endif
138
139 #endif
140