xref: /openbsd/usr.sbin/npppd/l2tp/l2tp_subr.h (revision 9d93772b)
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