Statistics
| Branch: | Revision:

ml / util / stun.h @ 372c2c31

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
#ifndef _WIN32
54
#include <netinet/in.h>
55
#endif
56
#include <string.h>
57
#include <stdbool.h>
58

    
59
#define LOG_MODULE "[ml] "
60
#include "ml_log.h"
61

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

    
67
/**
68
 * The maximum number of unkown attributs
69
 */
70
#define STUN_MAX_UNKNOWN_ATTRIBUTES 8
71

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

    
77
/**
78
 * The standard STUN port
79
 */
80
#define STUN_PORT 3478
81

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

    
96
/**
97
 * define basic type UInt8 
98
 */
99
typedef unsigned char  UInt8;
100

    
101
/**                                                                         
102
 * define basic type UInt16
103
 */
104
typedef unsigned short UInt16;
105

    
106
/**
107
 * define basic type UInt32
108
 */
109
typedef unsigned int UInt32;
110

    
111
/**
112
 * define basic type UInt64
113
 */
114
typedef unsigned long long UInt64;
115

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
280
   StunTypeIndependentFilter,
281
   StunTypeDependentFilter,
282
   StunTypePortDependedFilter,
283
   StunTypeDependentMapping,
284

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

    
293
/**
294
 * Define socket file descriptor
295
 */
296
typedef int Socket;
297

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

    
303
/**
304
 * Define the maximum rtp message size
305
 */
306
#define MAX_RTP_MSG_SIZE 1500
307

    
308
/**
309
 * Define the media replay timeout
310
 */
311
#define MEDIA_RELAY_TIMEOUT 3*60
312

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

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

    
339
/**
340
 * 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.  
341
 * @param *buf for retruned message
342
 * @param bufsize returned message size
343
 */
344
void pmtu_error_cb_stun(char *buf,int bufsize);
345

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
623
#endif