doc: gnunet-c-tutorial: Add nodes.
[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
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      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      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18      Boston, MA 02110-1301, USA.
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   uint32_t id[3];
38 } GNUNET_PACKED stun_trans_id;
39
40
41 struct stun_header
42 {
43   uint16_t msgtype;
44   uint16_t msglen;
45   uint32_t magic;
46   stun_trans_id id;
47 } GNUNET_PACKED;
48
49
50 struct stun_attr
51 {
52   uint16_t attr;
53   uint16_t len;
54 } GNUNET_PACKED;
55
56
57 /**
58  * The format normally used for addresses carried by STUN messages.
59  */
60 struct stun_addr
61 {
62   uint8_t  unused;
63
64   /**
65    * Address family, we expect AF_INET.
66    */
67   uint8_t  family;
68
69   /**
70    * Port number.
71    */
72   uint16_t port;
73
74   /**
75    * IPv4 address. Should this be "struct in_addr"?
76    */
77   uint32_t   addr;
78 } GNUNET_PACKED;
79
80
81 /**
82  * STUN message classes
83  */
84 enum StunClasses {
85   INVALID_CLASS = 0,
86   STUN_REQUEST = 0x0000,
87   STUN_INDICATION = 0x0001,
88   STUN_RESPONSE = 0x0002,
89   STUN_ERROR_RESPONSE = 0x0003
90 };
91
92 enum StunMethods {
93   INVALID_METHOD = 0,
94   STUN_BINDING = 0x0001,
95   STUN_SHARED_SECRET = 0x0002,
96   STUN_ALLOCATE = 0x0003,
97   STUN_REFRESH = 0x0004,
98   STUN_SEND = 0x0006,
99   STUN_DATA = 0x0007,
100   STUN_CREATE_PERMISSION = 0x0008,
101   STUN_CHANNEL_BIND = 0x0009
102 };
103
104
105 /**
106  * Basic attribute types in stun messages.
107  * Messages can also contain custom attributes (codes above 0x7fff)
108  */
109 enum StunAttributes {
110   STUN_MAPPED_ADDRESS = 0x0001,
111   STUN_RESPONSE_ADDRESS = 0x0002,
112   STUN_CHANGE_ADDRESS = 0x0003,
113   STUN_SOURCE_ADDRESS = 0x0004,
114   STUN_CHANGED_ADDRESS = 0x0005,
115   STUN_USERNAME = 0x0006,
116   STUN_PASSWORD = 0x0007,
117   STUN_MESSAGE_INTEGRITY = 0x0008,
118   STUN_ERROR_CODE = 0x0009,
119   STUN_UNKNOWN_ATTRIBUTES = 0x000a,
120   STUN_REFLECTED_FROM = 0x000b,
121   STUN_REALM = 0x0014,
122   STUN_NONCE = 0x0015,
123   STUN_XOR_MAPPED_ADDRESS = 0x0020,
124   STUN_MS_VERSION = 0x8008,
125   STUN_MS_XOR_MAPPED_ADDRESS = 0x8020,
126   STUN_SOFTWARE = 0x8022,
127   STUN_ALTERNATE_SERVER = 0x8023,
128   STUN_FINGERPRINT = 0x8028
129 };
130
131
132 /**
133  * Convert a message to a StunClass
134  *
135  * @param msg the received message
136  * @return the converted StunClass
137  */
138 static enum StunClasses
139 decode_class (int msg)
140 {
141   /* Sorry for the magic, but this maps the class according to rfc5245 */
142   return (enum StunClasses) ((msg & 0x0010) >> 4) | ((msg & 0x0100) >> 7);
143 }
144
145
146 /**
147  * Convert a message to a StunMethod
148  *
149  * @param msg the received message
150  * @return the converted StunMethod
151  */
152 static enum StunMethods
153 decode_method (int msg)
154 {
155   return (enum StunMethods) (msg & 0x000f) | ((msg & 0x00e0) >> 1) | ((msg & 0x3e00) >> 2);
156 }
157
158
159 /**
160  * Print a class and method from a STUN message
161  *
162  * @param msg
163  * @return string with the message class and method
164  */
165 GNUNET_UNUSED
166 static const char *
167 stun_msg2str (int msg)
168 {
169   static const struct {
170     enum StunClasses value;
171     const char *name;
172   } classes[] = {
173     { STUN_REQUEST, "Request" },
174     { STUN_INDICATION, "Indication" },
175     { STUN_RESPONSE, "Response" },
176     { STUN_ERROR_RESPONSE, "Error Response" },
177     { INVALID_CLASS, NULL }
178   };
179   static const struct {
180     enum StunMethods value;
181     const char *name;
182   } methods[] = {
183     { STUN_BINDING, "Binding" },
184     { INVALID_METHOD, NULL }
185   };
186   static char result[64];
187   const char *msg_class = NULL;
188   const char *method = NULL;
189   enum StunClasses cvalue;
190   enum StunMethods mvalue;
191
192   cvalue = decode_class (msg);
193   for (unsigned int i = 0; classes[i].name; i++)
194     if (classes[i].value == cvalue)
195     {
196       msg_class = classes[i].name;
197       break;
198     }
199   mvalue = decode_method (msg);
200   for (unsigned int i = 0; methods[i].name; i++)
201     if (methods[i].value == mvalue)
202     {
203       method = methods[i].name;
204       break;
205     }
206   GNUNET_snprintf (result,
207                    sizeof(result),
208                    "%s %s",
209                    method ? : "Unknown Method",
210                    msg_class ? : "Unknown Class Message");
211   return result;
212 }
213
214
215 /**
216  * Print attribute name
217  *
218  * @param msg with a attribute type
219  * @return string with the attribute name
220  */
221 GNUNET_UNUSED
222 static const char *
223 stun_attr2str (enum StunAttributes msg)
224 {
225   static const struct {
226     enum StunAttributes value;
227     const char *name;
228   } attrs[] = {
229     { STUN_MAPPED_ADDRESS, "Mapped Address" },
230     { STUN_RESPONSE_ADDRESS, "Response Address" },
231     { STUN_CHANGE_ADDRESS, "Change Address" },
232     { STUN_SOURCE_ADDRESS, "Source Address" },
233     { STUN_CHANGED_ADDRESS, "Changed Address" },
234     { STUN_USERNAME, "Username" },
235     { STUN_PASSWORD, "Password" },
236     { STUN_MESSAGE_INTEGRITY, "Message Integrity" },
237     { STUN_ERROR_CODE, "Error Code" },
238     { STUN_UNKNOWN_ATTRIBUTES, "Unknown Attributes" },
239     { STUN_REFLECTED_FROM, "Reflected From" },
240     { STUN_REALM, "Realm" },
241     { STUN_NONCE, "Nonce" },
242     { STUN_XOR_MAPPED_ADDRESS, "XOR Mapped Address" },
243     { STUN_MS_VERSION, "MS Version" },
244     { STUN_MS_XOR_MAPPED_ADDRESS, "MS XOR Mapped Address" },
245     { STUN_SOFTWARE, "Software" },
246     { STUN_ALTERNATE_SERVER, "Alternate Server" },
247     { STUN_FINGERPRINT, "Fingerprint" },
248     { 0, NULL }
249   };
250
251   for (unsigned int i = 0; attrs[i].name; i++)
252     if (attrs[i].value == msg)
253       return attrs[i].name;
254   return "Unknown Attribute";
255 }
256
257
258 /* end of nat_stun.h */