error handling
[oweals/gnunet.git] / src / nat / nat_stun.h
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2009, 2015, 2016 GNUnet e.V.
4
5      GNUnet is free software: you can redistribute it and/or modify it
6      under the terms of the GNU Affero General Public License as published
7      by the Free Software Foundation, either version 3 of the License,
8      or (at your option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      Affero General Public License for more details.
14
15      You should have received a copy of the GNU Affero General Public License
16      along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18      SPDX-License-Identifier: AGPL3.0-or-later
19  */
20 /**
21  * Message types for STUN server resolution
22  *
23  * @file nat/nat_stun.h
24  * @brief Testcase for STUN library
25  * @author Bruno Souza Cabral
26  * @autor Mark Spencer (Original code borrowed from Asterisk)
27  * @author Christian Grothoff
28  */
29
30
31 #define STUN_IGNORE             (0)
32 #define STUN_ACCEPT             (1)
33
34 #define STUN_MAGIC_COOKIE       0x2112A442
35
36 typedef struct
37 {
38   uint32_t id[3];
39 } GNUNET_PACKED stun_trans_id;
40
41
42 struct stun_header
43 {
44   uint16_t msgtype;
45   uint16_t msglen;
46   uint32_t magic;
47   stun_trans_id id;
48 } GNUNET_PACKED;
49
50
51 struct stun_attr
52 {
53   uint16_t attr;
54   uint16_t len;
55 } GNUNET_PACKED;
56
57
58 /**
59  * The format normally used for addresses carried by STUN messages.
60  */
61 struct stun_addr
62 {
63   uint8_t unused;
64
65   /**
66    * Address family, we expect AF_INET.
67    */
68   uint8_t family;
69
70   /**
71    * Port number.
72    */
73   uint16_t port;
74
75   /**
76    * IPv4 address. Should this be "struct in_addr"?
77    */
78   uint32_t addr;
79 } GNUNET_PACKED;
80
81
82 /**
83  * STUN message classes
84  */
85 enum StunClasses
86 {
87   INVALID_CLASS = 0,
88   STUN_REQUEST = 0x0000,
89   STUN_INDICATION = 0x0001,
90   STUN_RESPONSE = 0x0002,
91   STUN_ERROR_RESPONSE = 0x0003
92 };
93
94 enum StunMethods
95 {
96   INVALID_METHOD = 0,
97   STUN_BINDING = 0x0001,
98   STUN_SHARED_SECRET = 0x0002,
99   STUN_ALLOCATE = 0x0003,
100   STUN_REFRESH = 0x0004,
101   STUN_SEND = 0x0006,
102   STUN_DATA = 0x0007,
103   STUN_CREATE_PERMISSION = 0x0008,
104   STUN_CHANNEL_BIND = 0x0009
105 };
106
107
108 /**
109  * Basic attribute types in stun messages.
110  * Messages can also contain custom attributes (codes above 0x7fff)
111  */
112 enum StunAttributes
113 {
114   STUN_MAPPED_ADDRESS = 0x0001,
115   STUN_RESPONSE_ADDRESS = 0x0002,
116   STUN_CHANGE_ADDRESS = 0x0003,
117   STUN_SOURCE_ADDRESS = 0x0004,
118   STUN_CHANGED_ADDRESS = 0x0005,
119   STUN_USERNAME = 0x0006,
120   STUN_PASSWORD = 0x0007,
121   STUN_MESSAGE_INTEGRITY = 0x0008,
122   STUN_ERROR_CODE = 0x0009,
123   STUN_UNKNOWN_ATTRIBUTES = 0x000a,
124   STUN_REFLECTED_FROM = 0x000b,
125   STUN_REALM = 0x0014,
126   STUN_NONCE = 0x0015,
127   STUN_XOR_MAPPED_ADDRESS = 0x0020,
128   STUN_MS_VERSION = 0x8008,
129   STUN_MS_XOR_MAPPED_ADDRESS = 0x8020,
130   STUN_SOFTWARE = 0x8022,
131   STUN_ALTERNATE_SERVER = 0x8023,
132   STUN_FINGERPRINT = 0x8028
133 };
134
135
136 /**
137  * Convert a message to a StunClass
138  *
139  * @param msg the received message
140  * @return the converted StunClass
141  */
142 static enum StunClasses
143 decode_class (int msg)
144 {
145   /* Sorry for the magic, but this maps the class according to rfc5245 */
146   return (enum StunClasses) ((msg & 0x0010) >> 4) | ((msg & 0x0100) >> 7);
147 }
148
149
150 /**
151  * Convert a message to a StunMethod
152  *
153  * @param msg the received message
154  * @return the converted StunMethod
155  */
156 static enum StunMethods
157 decode_method (int msg)
158 {
159   return (enum StunMethods) (msg & 0x000f) | ((msg & 0x00e0) >> 1) | ((msg
160                                                                        & 0x3e00)
161                                                                       >> 2);
162 }
163
164
165 /**
166  * Print a class and method from a STUN message
167  *
168  * @param msg
169  * @return string with the message class and method
170  */
171 GNUNET_UNUSED
172 static const char *
173 stun_msg2str (int msg)
174 {
175   static const struct
176   {
177     enum StunClasses value;
178     const char *name;
179   } classes[] = {
180     { STUN_REQUEST, "Request" },
181     { STUN_INDICATION, "Indication" },
182     { STUN_RESPONSE, "Response" },
183     { STUN_ERROR_RESPONSE, "Error Response" },
184     { INVALID_CLASS, NULL }
185   };
186   static const struct
187   {
188     enum StunMethods value;
189     const char *name;
190   } methods[] = {
191     { STUN_BINDING, "Binding" },
192     { INVALID_METHOD, NULL }
193   };
194   static char result[64];
195   const char *msg_class = NULL;
196   const char *method = NULL;
197   enum StunClasses cvalue;
198   enum StunMethods mvalue;
199
200   cvalue = decode_class (msg);
201   for (unsigned int i = 0; classes[i].name; i++)
202     if (classes[i].value == cvalue)
203     {
204       msg_class = classes[i].name;
205       break;
206     }
207   mvalue = decode_method (msg);
208   for (unsigned int i = 0; methods[i].name; i++)
209     if (methods[i].value == mvalue)
210     {
211       method = methods[i].name;
212       break;
213     }
214   GNUNET_snprintf (result,
215                    sizeof(result),
216                    "%s %s",
217                    method ? : "Unknown Method",
218                    msg_class ? : "Unknown Class Message");
219   return result;
220 }
221
222
223 /**
224  * Print attribute name
225  *
226  * @param msg with a attribute type
227  * @return string with the attribute name
228  */
229 GNUNET_UNUSED
230 static const char *
231 stun_attr2str (enum StunAttributes msg)
232 {
233   static const struct
234   {
235     enum StunAttributes value;
236     const char *name;
237   } attrs[] = {
238     { STUN_MAPPED_ADDRESS, "Mapped Address" },
239     { STUN_RESPONSE_ADDRESS, "Response Address" },
240     { STUN_CHANGE_ADDRESS, "Change Address" },
241     { STUN_SOURCE_ADDRESS, "Source Address" },
242     { STUN_CHANGED_ADDRESS, "Changed Address" },
243     { STUN_USERNAME, "Username" },
244     { STUN_PASSWORD, "Password" },
245     { STUN_MESSAGE_INTEGRITY, "Message Integrity" },
246     { STUN_ERROR_CODE, "Error Code" },
247     { STUN_UNKNOWN_ATTRIBUTES, "Unknown Attributes" },
248     { STUN_REFLECTED_FROM, "Reflected From" },
249     { STUN_REALM, "Realm" },
250     { STUN_NONCE, "Nonce" },
251     { STUN_XOR_MAPPED_ADDRESS, "XOR Mapped Address" },
252     { STUN_MS_VERSION, "MS Version" },
253     { STUN_MS_XOR_MAPPED_ADDRESS, "MS XOR Mapped Address" },
254     { STUN_SOFTWARE, "Software" },
255     { STUN_ALTERNATE_SERVER, "Alternate Server" },
256     { STUN_FINGERPRINT, "Fingerprint" },
257     { 0, NULL }
258   };
259
260   for (unsigned int i = 0; attrs[i].name; i++)
261     if (attrs[i].value == msg)
262       return attrs[i].name;
263   return "Unknown Attribute";
264 }
265
266
267 /* end of nat_stun.h */