BadVPN – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 /**
2 * @file addr.h
3 * @author Ambroz Bizjak <ambrop7@gmail.com>
4 *
5 * @section LICENSE
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the author nor the
15 * names of its contributors may be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * @section DESCRIPTION
30 *
31 * AddrProto, a protocol for encoding network addresses.
32 *
33 * AddrProto is built with BProto, the protocol and code generator for building
34 * custom message protocols. The BProto specification file is addr.bproto.
35 */
36  
37 #ifndef BADVPN_PROTOCOL_ADDR_H
38 #define BADVPN_PROTOCOL_ADDR_H
39  
40 #include <stdint.h>
41 #include <string.h>
42  
43 #include <misc/debug.h>
44 #include <system/BAddr.h>
45 #include <base/BLog.h>
46  
47 #include <generated/bproto_addr.h>
48  
49 #include <generated/blog_channel_addr.h>
50  
51 #define ADDR_TYPE_IPV4 1
52 #define ADDR_TYPE_IPV6 2
53  
54 #define ADDR_SIZE_IPV4 (addr_SIZEtype + addr_SIZEip_port + addr_SIZEipv4_addr)
55 #define ADDR_SIZE_IPV6 (addr_SIZEtype + addr_SIZEip_port + addr_SIZEipv6_addr)
56  
57 /**
58 * Determines if the given address is supported by AddrProto.
59 * Depends only on the type of the address.
60 *
61 * @param addr address to check. Must be recognized according to {@link BAddr_IsRecognized}.
62 * @return 1 if supported, 0 if not
63 */
64 static int addr_supported (BAddr addr);
65  
66 /**
67 * Determines the size of the given address when encoded by AddrProto.
68 * Depends only on the type of the address.
69 *
70 * @param addr address to check. Must be supported according to {@link addr_supported}.
71 * @return encoded size
72 */
73 static int addr_size (BAddr addr);
74  
75 /**
76 * Encodes an address according to AddrProto.
77 *
78 * @param out output buffer. Must have at least addr_size(addr) space.
79 * @param addr address to encode. Must be supported according to {@link addr_supported}.
80 */
81 static void addr_write (uint8_t *out, BAddr addr);
82  
83 /**
84 * Decodes an address according to AddrProto.
85 *
86 * @param data input buffer containing the address to decode
87 * @param data_len size of input. Must be >=0.
88 * @param out_addr the decoded address will be stored here on success
89 * @return 1 on success, 0 on failure
90 */
91 static int addr_read (uint8_t *data, int data_len, BAddr *out_addr) WARN_UNUSED;
92  
93 int addr_supported (BAddr addr)
94 {
95 BAddr_Assert(&addr);
96  
97 switch (addr.type) {
98 case BADDR_TYPE_IPV4:
99 case BADDR_TYPE_IPV6:
100 return 1;
101 default:
102 return 0;
103 }
104 }
105  
106 int addr_size (BAddr addr)
107 {
108 ASSERT(addr_supported(addr))
109  
110 switch (addr.type) {
111 case BADDR_TYPE_IPV4:
112 return ADDR_SIZE_IPV4;
113 case BADDR_TYPE_IPV6:
114 return ADDR_SIZE_IPV6;
115 default:
116 ASSERT(0)
117 return 0;
118 }
119 }
120  
121 void addr_write (uint8_t *out, BAddr addr)
122 {
123 ASSERT(addr_supported(addr))
124  
125 addrWriter writer;
126 addrWriter_Init(&writer, out);
127  
128 switch (addr.type) {
129 case BADDR_TYPE_IPV4: {
130 addrWriter_Addtype(&writer, ADDR_TYPE_IPV4);
131 uint8_t *out_port = addrWriter_Addip_port(&writer);
132 memcpy(out_port, &addr.ipv4.port, sizeof(addr.ipv4.port));
133 uint8_t *out_addr = addrWriter_Addipv4_addr(&writer);
134 memcpy(out_addr, &addr.ipv4.ip, sizeof(addr.ipv4.ip));
135 } break;
136 case BADDR_TYPE_IPV6: {
137 addrWriter_Addtype(&writer, ADDR_TYPE_IPV6);
138 uint8_t *out_port = addrWriter_Addip_port(&writer);
139 memcpy(out_port, &addr.ipv6.port, sizeof(addr.ipv6.port));
140 uint8_t *out_addr = addrWriter_Addipv6_addr(&writer);
141 memcpy(out_addr, addr.ipv6.ip, sizeof(addr.ipv6.ip));
142 } break;
143 default:
144 ASSERT(0);
145 }
146  
147 int len = addrWriter_Finish(&writer);
148 B_USE(len)
149  
150 ASSERT(len == addr_size(addr))
151 }
152  
153 int addr_read (uint8_t *data, int data_len, BAddr *out_addr)
154 {
155 ASSERT(data_len >= 0)
156  
157 addrParser parser;
158 if (!addrParser_Init(&parser, data, data_len)) {
159 BLog(BLOG_ERROR, "failed to parse addr");
160 return 0;
161 }
162  
163 uint8_t type = 0; // to remove warning
164 addrParser_Gettype(&parser, &type);
165  
166 switch (type) {
167 case ADDR_TYPE_IPV4: {
168 uint8_t *port_data;
169 if (!addrParser_Getip_port(&parser, &port_data)) {
170 BLog(BLOG_ERROR, "port missing for IPv4 address");
171 return 0;
172 }
173 uint8_t *addr_data;
174 if (!addrParser_Getipv4_addr(&parser, &addr_data)) {
175 BLog(BLOG_ERROR, "address missing for IPv4 address");
176 return 0;
177 }
178 uint16_t port;
179 uint32_t addr;
180 memcpy(&port, port_data, sizeof(port));
181 memcpy(&addr, addr_data, sizeof(addr));
182 BAddr_InitIPv4(out_addr, addr, port);
183 } break;
184 case ADDR_TYPE_IPV6: {
185 uint8_t *port_data;
186 if (!addrParser_Getip_port(&parser, &port_data)) {
187 BLog(BLOG_ERROR, "port missing for IPv6 address");
188 return 0;
189 }
190 uint8_t *addr_data;
191 if (!addrParser_Getipv6_addr(&parser, &addr_data)) {
192 BLog(BLOG_ERROR, "address missing for IPv6 address");
193 return 0;
194 }
195 uint16_t port;
196 memcpy(&port, port_data, sizeof(port));
197 BAddr_InitIPv6(out_addr, addr_data, port);
198 } break;
199 default:
200 BLog(BLOG_ERROR, "unknown address type %d", (int)type);
201 return 0;
202 }
203  
204 return 1;
205 }
206  
207 #endif