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