Statistics
| Branch: | Revision:

ml / util / stun.h @ 52f7925a

History | View | Annotate | Download (16.6 KB)

1
/*
2
 *          NEC Europe Ltd. PROPRIETARY INFORMATION
3
 *
4
 * This software is supplied under the terms of a license agreement
5
 * or nondisclosure agreement with NEC Europe Ltd. and may not be
6
 * copied or disclosed except in accordance with the terms of that
7
 * agreement.
8
 *
9
 *      Copyright (c) 2009 NEC Europe Ltd. All Rights Reserved.
10
 *
11
 * Authors: Kristian Beckers  <beckers@nw.neclab.eu>
12
 *    Sebastian Kiesel  <kiesel@nw.neclab.eu>
13
 *          
14
 *
15
 * NEC Europe Ltd. DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED,
16
 * INCLUDING BUT NOT LIMITED TO IMPLIED WARRANTIES OF MERCHANTABILITY
17
 * AND FITNESS FOR A PARTICULAR PURPOSE AND THE WARRANTY AGAINST LATENT
18
 * DEFECTS, WITH RESPECT TO THE PROGRAM AND THE ACCOMPANYING
19
 * DOCUMENTATION.
20
 *
21
 * No Liability For Consequential Damages IN NO EVENT SHALL NEC Europe
22
 * Ltd., NEC Corporation OR ANY OF ITS SUBSIDIARIES BE LIABLE FOR ANY
23
 * DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS
24
 * OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF INFORMATION, OR
25
 * OTHER PECUNIARY LOSS AND INDIRECT, CONSEQUENTIAL, INCIDENTAL,
26
 * ECONOMIC OR PUNITIVE DAMAGES) ARISING OUT OF THE USE OF OR INABILITY
27
 * TO USE THIS PROGRAM, EVEN IF NEC Europe Ltd. HAS BEEN ADVISED OF THE
28
 * POSSIBILITY OF SUCH DAMAGES.
29
 *
30
 *     THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY.
31
 */
32

    
33
/**
34
 * @file stun.h
35
 * @brief This file holds functions for the NAT traversal with STUN. 
36
 *
37
 * The functionality in this is used by the messaging layer to implement a STUN client. This client can send STUN request and parse STUN responses. 
38
 * @author Kristian Beckers  <beckers@nw.neclab.eu>                             
39
 * @author Sebastian Kiesel  <kiesel@nw.neclab.eu>                              
40
 *                                                                              
41
 * @date 7/28/2009 
42
 *
43
 * @note Policy Management
44
 */
45

    
46

    
47

    
48
#ifndef STUN_H
49
#define STUN_H
50

    
51
#include <stdio.h> 
52
#include <time.h>
53
#include <netinet/in.h>
54
#include <string.h>
55
#include <stdbool.h>
56

    
57
#define LOG_MODULE "[ml] "
58
#include "grapes_log.h"
59

    
60
/**
61
 * The maximum size of a STUN string 
62
 */
63
#define STUN_MAX_STRING 256
64

    
65
/**
66
 * The maximum number of unkown attributs
67
 */
68
#define STUN_MAX_UNKNOWN_ATTRIBUTES 8
69

    
70
/**
71
 * The maximum length of a STUN message
72
 */
73
#define STUN_MAX_MESSAGE_SIZE 576
74

    
75
/**
76
 * The standard STUN port
77
 */
78
#define STUN_PORT 3478
79

    
80
#ifndef false
81
/**
82
  * Boolean define 0 as false
83
  */
84
#define false 0
85
#endif
86
#ifndef true
87
/**
88
  * Boolean define 1 as true
89
  */
90
#define true 1
91
#endif
92
//@}
93

    
94
/**
95
 * define basic type UInt8 
96
 */
97
typedef unsigned char  UInt8;
98

    
99
/**                                                                         
100
 * define basic type UInt16
101
 */
102
typedef unsigned short UInt16;
103

    
104
/**
105
 * define basic type UInt32
106
 */
107
typedef unsigned int UInt32;
108

    
109
/**
110
 * define basic type UInt64
111
 */
112
typedef unsigned long long UInt64;
113

    
114
/**
115
 * define basic type UInt128
116
 */
117
typedef struct { unsigned char octet[16]; ///< char array  
118
}  UInt128;
119

    
120
/**
121
 * STUN message header
122
 */
123
typedef struct 
124
{
125
      UInt16 msgType; ///< stun message type
126
      UInt16 msgLength; ///< stun message length
127
      UInt128 id; ///< the stun ID of the message
128
} StunMsgHdr;
129

    
130
/** 
131
 * STUN attribute header           
132
 */
133
typedef struct
134
{
135
      UInt16 type; ///< the attribute type
136
      UInt16 length; ///< the attribute length
137
} StunAtrHdr;
138

    
139
/**
140
 * The stun ipv4 address
141
 */
142
typedef struct
143
{
144
      UInt16 port; ///< the port 
145
      UInt32 addr; ///< the ip address
146
} StunAddress4;
147

    
148
/**
149
 * the stun attribute address
150
 */
151
typedef struct
152
{
153
      UInt8 pad; ///< padding
154
      UInt8 family; ///< address family
155
      StunAddress4 ipv4; ///< stun ipv4 address
156
} StunAtrAddress4; 
157

    
158
/**
159
 * the stun change request
160
 */
161
typedef struct
162
{
163
      UInt32 value; ///< the value of the change request
164
} StunAtrChangeRequest; 
165

    
166
/**
167
 * stun attribute error 
168
 */
169
typedef struct
170
{
171
      UInt16 pad; ///< padding with 0
172
      UInt8 errorClass; ///< stun error class
173
      UInt8 number; ///< stun error number
174
      char reason[STUN_MAX_STRING]; ///< the error reason
175
      UInt16 sizeReason; ///< the reason size
176
} StunAtrError;
177

    
178
/**
179
 * stun attribute unknown
180
 */
181
typedef struct
182
{
183
      UInt16 attrType[STUN_MAX_UNKNOWN_ATTRIBUTES]; ///< attribute type 
184
      UInt16 numAttributes; ///< number of attributes
185
} StunAtrUnknown;
186

    
187
/**
188
 * stun attribute string
189
 */
190
typedef struct
191
{
192
      char value[STUN_MAX_STRING]; ///< the value of the string      
193
      UInt16 sizeValue; ///< the size of the string
194
} StunAtrString;
195

    
196
/**
197
 * stun attribute integrity 
198
 */
199
typedef struct
200
{
201
      char hash[20]; ///< a hash value 
202
} StunAtrIntegrity; 
203

    
204
/**
205
 * stun HMAC status
206
 */
207
typedef enum 
208
{
209
   HmacUnkown=0, ///< HMAC is unknown
210
   HmacOK, ///< HMAC is ok
211
   HmacBadUserName, ///< HAMC has a bad username
212
   HmacUnkownUserName, ///< HMAC has an unkown username
213
   HmacFailed, ///< HMAC failed
214
} StunHmacStatus;
215

    
216
/**
217
 * a stun message
218
 */
219
typedef struct
220
{
221
      StunMsgHdr msgHdr; ///< stun message header
222
        
223
      bool hasMappedAddress; ///< boolean if a mapped address is present
224
      StunAtrAddress4  mappedAddress; ///< stun mapped address 
225
        
226
      bool hasResponseAddress; ///< boolean if a response address is present
227
      StunAtrAddress4  responseAddress; ///< stun response address
228
        
229
      bool hasChangeRequest; ///< boolean if a change request is present
230
      StunAtrChangeRequest changeRequest; ///< change request
231
        
232
      bool hasSourceAddress; ///< boolean if a source address is present
233
      StunAtrAddress4 sourceAddress; ///< source address
234
        
235
      bool hasChangedAddress;///< boolean if a changed address is present
236
      StunAtrAddress4 changedAddress; ///< changed address
237
        
238
      bool hasUsername;///< boolean if a username is present
239
      StunAtrString username; ///< username
240
        
241
      bool hasPassword;///< boolean if a password is present
242
      StunAtrString password; ///< password
243
        
244
      bool hasMessageIntegrity;///< boolean if a message integrity check is present
245
      StunAtrIntegrity messageIntegrity; ///< message integrity check
246
        
247
      bool hasErrorCode;///< boolean if a error code is present
248
      StunAtrError errorCode; ///< stun error code
249
        
250
      bool hasUnknownAttributes;///< boolean if an unkown attribute is present
251
      StunAtrUnknown unknownAttributes; ///< unkown stun attributes
252
        
253
      bool hasReflectedFrom;///< boolean if a reflected from is present
254
      StunAtrAddress4 reflectedFrom; ///< reflected from
255

    
256
      bool hasXorMappedAddress;///< boolean if a xor mapped address is present
257
      StunAtrAddress4  xorMappedAddress; ///< xor mapped address
258
        
259
      bool xorOnly;///< boolean if the mapping is XOR only
260

    
261
      bool hasServerName;///< boolean if a server name is present
262
      StunAtrString serverName; ///< stun server name
263
      
264
      bool hasSecondaryAddress;///< boolean if a secondary address is present
265
      StunAtrAddress4 secondaryAddress;///< secondary address
266
} StunMessage; 
267

    
268
/**
269
 * Define enum with different types of NAT 
270
 */
271
typedef enum 
272
{
273
   StunTypeUnknown=0,
274
   StunTypeFailure,
275
   StunTypeOpen,
276
   StunTypeBlocked,
277

    
278
   StunTypeIndependentFilter,
279
   StunTypeDependentFilter,
280
   StunTypePortDependedFilter,
281
   StunTypeDependentMapping,
282

    
283
   //StunTypeConeNat,
284
   //StunTypeRestrictedNat,
285
   //StunTypePortRestrictedNat,
286
   //StunTypeSymNat,
287
   
288
   StunTypeFirewall,
289
} NatType;
290

    
291
/**
292
 * Define socket file descriptor
293
 */
294
typedef int Socket;
295

    
296
/**
297
 * Define the maximum ammount of media relays
298
 */
299
#define MAX_MEDIA_RELAYS 500
300

    
301
/**
302
 * Define the maximum rtp message size
303
 */
304
#define MAX_RTP_MSG_SIZE 1500
305

    
306
/**
307
 * Define the media replay timeout
308
 */
309
#define MEDIA_RELAY_TIMEOUT 3*60
310

    
311
/**
312
 * stun media relay
313
 */
314
typedef struct 
315
{
316
      int relayPort;       ///< media relay port
317
      int fd;              ///< media relay file descriptor
318
      StunAddress4 destination; ///< NAT IP:port
319
      time_t expireTime;      ///< if no activity after time, close the socket 
320
} StunMediaRelay;
321

    
322
/**
323
 * stun server information
324
 */
325
typedef struct
326
{
327
      StunAddress4 myAddr; ///< server address
328
      StunAddress4 altAddr; ///< alternative server address
329
      Socket myFd; ///< socket file descriptor
330
      Socket altPortFd; ///< alternative port 
331
      Socket altIpFd; ///< altertnative ip address
332
      Socket altIpPortFd; ///< port and ip address
333
      bool relay; ///< true if media relaying is to be done
334
      StunMediaRelay relays[MAX_MEDIA_RELAYS]; ///< stun media relays
335
} StunServerInfo;
336

    
337
/**
338
 * A callback for pmtu error messages. These are used by the udpSocket to tell the stun client that the send stun request had a too big pmtu size.  
339
 * @param *buf for retruned message
340
 * @param bufsize returned message size
341
 */
342
void pmtu_error_cb_stun(char *buf,int bufsize);
343

    
344
/**
345
 * Send a stun request to a stun server
346
 * @param udpSocket a file descriptor for a udp socket
347
 * @param *stunServ the address of the stun server
348
 * @return 0 if successful
349
 */
350
int send_stun_request(const int udpSocket,struct sockaddr_in *stunServ);
351

    
352
/**
353
 * Send a stun keep alive message
354
 * @param udpSocket a file descriptor for a udp socket
355
 * @param *stunServ the address of the stun server
356
 * @return 0 if successful
357
 */
358
int send_stun_keep_alive(const int udpSocket,struct sockaddr_in *stunServ);
359

    
360
/**
361
 * Receive a stun message
362
 * @param *msg pointer to a stun message
363
 * @param msgLen stun message length
364
 * @param *response a pointer to a stun response
365
 * @return 0 if successful
366
 */
367
int recv_stun_message(char *msg, int msgLen,StunMessage *response);
368

    
369
/**
370
 * Parse a stun attribute address
371
 * @param body a pointer to a buffer that contains a stun message body
372
 * @param hdrLen the length of the header
373
 * @param *result the stun ipv4 address
374
 * @param verbose A boolean that tells if debug output shall be displayed
375
 * @return true if parsing was sussessful otherwise false
376
 */
377
bool
378
stunParseAtrAddress(char* body, unsigned int hdrLen,StunAtrAddress4 *result,bool verbose);
379

    
380
/**
381
 * Parse a stun message
382
 * @param *buf a buffer that contains the stun message
383
 * @param bufLen the length of the buffer
384
 * @param *msg A pointer to a StunMessage struct
385
 * @param verbose A boolean that tells if debug output shall be displayed
386
 * @return true if parsing was sussessful otherwise false
387
 */
388
bool
389
stunParseMessage( char* buf, 
390
                  unsigned int bufLen, 
391
                  StunMessage *msg, 
392
                  bool verbose );
393

    
394
/**
395
 * Build a very simple stun request
396
 * @param *msg A pointer to a StunMessage struct
397
 * @param username A stun username
398
 * @param changePort The change port
399
 * @param changeIp The change IP
400
 * @param id A stun id
401
 */
402
void
403
stunBuildReqSimple( StunMessage* msg, const StunAtrString username,
404
                    bool changePort, bool changeIp, unsigned int id );
405

    
406
/**
407
 * Encode stun message
408
 * @param message A pointer to a StunMessage struct
409
 * @param buf a buffer that contains the stun message
410
 * @param bufLen the length of the buffer
411
 * @param password A stun password
412
 * @param verbose A boolean that tells if debug output shall be displayed
413
 * @return true if parsing was sussessful otherwise false
414
 */
415
unsigned int
416
stunEncodeMessage( const StunMessage message, 
417
                   char* buf, 
418
                   unsigned int bufLen, 
419
                   const StunAtrString password,
420
                   bool verbose);
421

    
422
/**
423
 * create a random stun int 
424
 * @return random int 
425
 */
426
int 
427
stunRand();
428

    
429
/**
430
 * Get the system time in seconds 
431
 * @return system time in seconds 
432
 */
433
UInt64
434
stunGetSystemTimeSecs();
435

    
436
/**
437
 * Find the IP address of a the specified stun server
438
 * @return false if parse failse
439
 */
440
bool  
441
stunParseServerName( char* serverName, StunAddress4 stunServerAddr);
442

    
443
/**
444
 * Parse the stun hostname
445
 * @param peerName A pointer to a buffer that contains the peer name.
446
 * @param ip The ip address of the hostname  
447
 * @param portVal The port of the hostname 
448
 * @param defaultPort The default port of the hostname 
449
 * @return true if parsing was sussessful otherwise false 
450
 */
451
bool 
452
stunParseHostName(char* peerName,
453
                   UInt32 ip,
454
                   UInt16 portVal,
455
                   UInt16 defaultPort );
456

    
457
/**
458
 * Parse a stun change request
459
 * @param body A pointer to a buffer that contains the stun change request
460
 * @param hdrLen The length of the buffer
461
 * @param *result A pointer to a StunAtrChangeRequest struct. 
462
 * @return true if parsing was sussessful otherwise false
463
 */
464
bool
465
stunParseAtrChangeRequest(char* body,unsigned int hdrLen,StunAtrChangeRequest *result);
466

    
467
/**
468
 * Parse an unkown attribute
469
 * @param body A pointer to a stun message body that has an unkown attribute
470
 * @param hdrLen The length of that header
471
 * @param *result A pointer to a StunAtrUnknown struct.
472
 * @return true if parsing was sussessful otherwise false
473
 */
474
bool
475
stunParseAtrUnknown( char* body, unsigned int hdrLen,  StunAtrUnknown *result );
476

    
477
/**
478
 * Parse a stun attribute string
479
 * @param body A pointer to a stun message body that has a stun string
480
 * @param hdrLen The length of that string
481
 * @param *result A pointer to a StunAtrString struct. 
482
 * @return true if parsing was sussessful otherwise false
483
 */
484
bool
485
stunParseAtrString( char* body, unsigned int hdrLen,  StunAtrString *result );
486

    
487
/**
488
 * Parse stun attribute integrity
489
 * @param body A pointer to a stun body that holds an attribute
490
 * @param hdrLen The length of that attribute
491
 * @param *result A pointer to a StunAtrIntegrity struct. 
492
 * @return true if parsing was sussessful otherwise false
493
 */
494
bool
495
stunParseAtrIntegrity( char* body, unsigned int hdrLen,  StunAtrIntegrity *result );
496

    
497
/**
498
 * Create a stun error response 
499
 * @param response A StunMessage struct
500
 * @param cl The error class
501
 * @param number The error number
502
 * @param *msg A pointer to the stun message
503
 */
504
void
505
stunCreateErrorResponse(StunMessage response, int cl, int number, const char* msg);
506

    
507
/**
508
 * Parse a stun attribute error 
509
 * @param body A pointer to a stun body that holds an attribute
510
 * @param hdrLen The length of that attribute
511
 * @param *result A pointer to a StunAtrError struct.
512
 * @return true if parsing was sussessful otherwise false
513
 */
514
bool
515
stunParseAtrError( char* body, unsigned int hdrLen,StunAtrError *result);
516

    
517
/**
518
 * Encode stun attribute string 
519
 * @param ptr A pointer to the string
520
 * @param type The attribute type
521
 * @param atr A struct from type StunAtrString
522
 * @return encoded attribute string
523
 */
524
char*
525
encodeAtrString(char* ptr, UInt16 type, const StunAtrString atr);
526

    
527
/**
528
 * Encode attribute integrity
529
 * @param ptr A pointer to the string
530
 * @param atr A struct from type StunAtrString
531
 * @return encoded attribute integrity value 
532
 */
533
char*
534
encodeAtrIntegrity(char* ptr, const StunAtrIntegrity atr);
535

    
536
/**
537
 * Encode attribute error
538
 * @param ptr a pointer to a buffer
539
 * @param atr A StunAtrError struct
540
 * @result a pointer to an encoded attribute error  
541
 */
542
char*
543
encodeAtrError(char* ptr, const StunAtrError atr);
544

    
545
/**
546
 * Encode an unkown attribute
547
 * @param ptr a pointer to a buffer
548
 * @param atr A StunAtrUnkown struct
549
 * @result a pointer to an encoded unkown attribute
550
 */
551
char*
552
encodeAtrUnknown(char* ptr, const StunAtrUnknown atr);
553

    
554
/**
555
 * Encode a stun ipv4 address
556
 * @param ptr a pointer to a buffer
557
 * @param type a attribute type
558
 * @param atr A StunAtrAddress4 struct        
559
 * @result a pointer to an encoded attribute ipv4 address
560
 */
561
char*
562
encodeAtrAddress4(char* ptr, UInt16 type, const StunAtrAddress4 atr);
563

    
564
/**
565
 * Encode a change request stun attribute
566
 * @param ptr a pointer to a buffer
567
 * @param atr A StunAtrChangeRequest struct
568
 * @result a pointer to an encoded unkown attribute
569
 */
570
char*
571
encodeAtrChangeRequest(char* ptr, const StunAtrChangeRequest atr);
572

    
573
/**
574
 * Encode an XOR only
575
 * @param ptr a pointer to a buffer
576
 * @result a pointer to an xor only   
577
 */
578
char* encodeXorOnly(char* ptr);
579

    
580
/**
581
 * Encode data into a buffer
582
 * @param buf a buffer pointer
583
 * @param data the data to encode into the buffer 
584
 * @param length the length of the data
585
 * @return pointer to the buffer position behind the data
586
 */
587
char* encode(char* buf, const char* data, unsigned int length);
588

    
589
/**
590
 * Encode data into network byte order and use a UInt16 slot of a buffer 
591
 * @param buf a buffer pointer
592
 * @param data the data to encode into the buffer 
593
 * @return pointer to the buffer position behind the data
594
 */
595
char* encode16(char* buf, UInt16 data);
596

    
597
/**
598
 * Encode data into network byte order and use a UInt32 slot of a buffer
599
 * @param buf a buffer pointer
600
 * @param data the data to encode into the buffer 
601
 * @return pointer to the buffer position behind the data
602
 */
603
char* encode32(char* buf, UInt32 data);
604

    
605
/**
606
 * Get a random port number
607
 * @return return a random number to use as a port 
608
 */
609
int
610
stunRandomPort();
611

    
612
/**
613
 * Convert to Hex
614
 * @param buffer A pointer to a buffer with the data to convert
615
 * @param bufferSize The length of the buffer
616
 * @param output A pointer to the output buffer
617
 */
618
void
619
toHex(const char* buffer, int bufferSize, char* output);
620

    
621
#endif