1 #ifndef STUN_H 2 #define STUN_H 3 4 #include <iostream> 5 #include <time.h> 6 7 // if you change this version, change in makefile too 8 #define STUN_VERSION "0.96" 9 10 #define STUN_MAX_STRING 256 11 #define STUN_MAX_UNKNOWN_ATTRIBUTES 8 12 #define STUN_MAX_MESSAGE_SIZE 2048 13 14 #define STUN_PORT 3478 15 16 // define some basic types 17 typedef unsigned char UInt8; 18 typedef unsigned short UInt16; 19 typedef unsigned int UInt32; 20 #if defined( WIN32 ) 21 typedef unsigned __int64 UInt64; 22 #else 23 typedef unsigned long long UInt64; 24 #endif 25 typedef struct { unsigned char octet[16]; } UInt128; 26 27 /// define a structure to hold a stun address 28 const UInt8 IPv4Family = 0x01; 29 const UInt8 IPv6Family = 0x02; 30 31 // define flags 32 const UInt32 ChangeIpFlag = 0x04; 33 const UInt32 ChangePortFlag = 0x02; 34 35 // define stun attribute 36 const UInt16 MappedAddress = 0x0001; 37 const UInt16 ResponseAddress = 0x0002; 38 const UInt16 ChangeRequest = 0x0003; 39 const UInt16 SourceAddress = 0x0004; 40 const UInt16 ChangedAddress = 0x0005; 41 const UInt16 Username = 0x0006; 42 const UInt16 Password = 0x0007; 43 const UInt16 MessageIntegrity = 0x0008; 44 const UInt16 ErrorCode = 0x0009; 45 const UInt16 UnknownAttribute = 0x000A; 46 const UInt16 ReflectedFrom = 0x000B; 47 const UInt16 XorMappedAddress = 0x8020; 48 const UInt16 XorOnly = 0x0021; 49 const UInt16 ServerName = 0x8022; 50 const UInt16 SecondaryAddress = 0x8050; // Non standard extention 51 52 // define types for a stun message 53 const UInt16 BindRequestMsg = 0x0001; 54 const UInt16 BindResponseMsg = 0x0101; 55 const UInt16 BindErrorResponseMsg = 0x0111; 56 const UInt16 SharedSecretRequestMsg = 0x0002; 57 const UInt16 SharedSecretResponseMsg = 0x0102; 58 const UInt16 SharedSecretErrorResponseMsg = 0x0112; 59 60 typedef struct 61 { 62 UInt16 msgType; 63 UInt16 msgLength; 64 UInt128 id; 65 } StunMsgHdr; 66 67 68 typedef struct 69 { 70 UInt16 type; 71 UInt16 length; 72 } StunAtrHdr; 73 74 typedef struct 75 { 76 UInt16 port; 77 UInt32 addr; 78 } StunAddress4; 79 80 typedef struct 81 { 82 UInt8 pad; 83 UInt8 family; 84 StunAddress4 ipv4; 85 } StunAtrAddress4; 86 87 typedef struct 88 { 89 UInt32 value; 90 } StunAtrChangeRequest; 91 92 typedef struct 93 { 94 UInt16 pad; // all 0 95 UInt8 errorClass; 96 UInt8 number; 97 char reason[STUN_MAX_STRING]; 98 UInt16 sizeReason; 99 } StunAtrError; 100 101 typedef struct 102 { 103 UInt16 attrType[STUN_MAX_UNKNOWN_ATTRIBUTES]; 104 UInt16 numAttributes; 105 } StunAtrUnknown; 106 107 typedef struct 108 { 109 char value[STUN_MAX_STRING]; 110 UInt16 sizeValue; 111 } StunAtrString; 112 113 typedef struct 114 { 115 char hash[20]; 116 } StunAtrIntegrity; 117 118 typedef enum 119 { 120 HmacUnkown=0, 121 HmacOK, 122 HmacBadUserName, 123 HmacUnkownUserName, 124 HmacFailed, 125 } StunHmacStatus; 126 127 typedef struct 128 { 129 StunMsgHdr msgHdr; 130 131 bool hasMappedAddress; 132 StunAtrAddress4 mappedAddress; 133 134 bool hasResponseAddress; 135 StunAtrAddress4 responseAddress; 136 137 bool hasChangeRequest; 138 StunAtrChangeRequest changeRequest; 139 140 bool hasSourceAddress; 141 StunAtrAddress4 sourceAddress; 142 143 bool hasChangedAddress; 144 StunAtrAddress4 changedAddress; 145 146 bool hasUsername; 147 StunAtrString username; 148 149 bool hasPassword; 150 StunAtrString password; 151 152 bool hasMessageIntegrity; 153 StunAtrIntegrity messageIntegrity; 154 155 bool hasErrorCode; 156 StunAtrError errorCode; 157 158 bool hasUnknownAttributes; 159 StunAtrUnknown unknownAttributes; 160 161 bool hasReflectedFrom; 162 StunAtrAddress4 reflectedFrom; 163 164 bool hasXorMappedAddress; 165 StunAtrAddress4 xorMappedAddress; 166 167 bool xorOnly; 168 169 bool hasServerName; 170 StunAtrString serverName; 171 172 bool hasSecondaryAddress; 173 StunAtrAddress4 secondaryAddress; 174 } StunMessage; 175 176 177 // Define enum with different types of NAT 178 typedef enum 179 { 180 StunTypeUnknown=0, 181 StunTypeFailure, 182 StunTypeOpen, 183 StunTypeBlocked, 184 185 StunTypeIndependentFilter, 186 StunTypeDependentFilter, 187 StunTypePortDependedFilter, 188 StunTypeDependentMapping, 189 190 //StunTypeConeNat, 191 //StunTypeRestrictedNat, 192 //StunTypePortRestrictedNat, 193 //StunTypeSymNat, 194 195 StunTypeFirewall, 196 } NatType; 197 198 #ifdef WIN32 199 typedef SOCKET Socket; 200 #else 201 typedef int Socket; 202 #endif 203 204 #define MAX_MEDIA_RELAYS 500 205 #define MAX_RTP_MSG_SIZE 1500 206 #define MEDIA_RELAY_TIMEOUT 3*60 207 208 typedef struct 209 { 210 int relayPort; // media relay port 211 int fd; // media relay file descriptor 212 StunAddress4 destination; // NAT IP:port 213 time_t expireTime; // if no activity after time, close the socket 214 } StunMediaRelay; 215 216 typedef struct 217 { 218 StunAddress4 myAddr; 219 StunAddress4 altAddr; 220 Socket myFd; 221 Socket altPortFd; 222 Socket altIpFd; 223 Socket altIpPortFd; 224 bool relay; // true if media relaying is to be done 225 StunMediaRelay relays[MAX_MEDIA_RELAYS]; 226 } StunServerInfo; 227 228 bool 229 stunParseMessage( char* buf, 230 unsigned int bufLen, 231 StunMessage& message, 232 bool verbose ); 233 234 void 235 stunBuildReqSimple( StunMessage* msg, 236 const StunAtrString& username, 237 bool changePort, bool changeIp, unsigned int id=0 ); 238 239 unsigned int 240 stunEncodeMessage( const StunMessage& message, 241 char* buf, 242 unsigned int bufLen, 243 const StunAtrString& password, 244 bool verbose); 245 246 void 247 stunCreateUserName(const StunAddress4& addr, StunAtrString* username); 248 249 void 250 stunGetUserNameAndPassword( const StunAddress4& dest, 251 StunAtrString* username, 252 StunAtrString* password); 253 254 void 255 stunCreatePassword(const StunAtrString& username, StunAtrString* password); 256 257 int 258 stunRand(); 259 260 UInt64 261 stunGetSystemTimeSecs(); 262 263 /// find the IP address of a the specified stun server - return false is fails parse 264 bool 265 stunParseServerName( char* serverName, StunAddress4& stunServerAddr); 266 267 bool 268 stunParseHostName( char* peerName, 269 UInt32& ip, 270 UInt16& portVal, 271 UInt16 defaultPort ); 272 273 /// return true if all is OK 274 /// Create a media relay and do the STERN thing if startMediaPort is non-zero 275 bool 276 stunInitServer(StunServerInfo& info, 277 const StunAddress4& myAddr, 278 const StunAddress4& altAddr, 279 int startMediaPort, 280 bool verbose); 281 282 void 283 stunStopServer(StunServerInfo& info); 284 285 /// return true if all is OK 286 bool 287 stunServerProcess(StunServerInfo& info, bool verbose); 288 289 /// returns number of address found - take array or addres 290 int 291 stunFindLocalInterfaces(UInt32* addresses, int maxSize ); 292 293 void 294 stunTest( StunAddress4& dest, int testNum, bool verbose, StunAddress4* srcAddr=0 ); 295 296 NatType 297 stunNatType( StunAddress4& dest, bool verbose, 298 bool* preservePort=0, // if set, is return for if NAT preservers ports or not 299 bool* hairpin=0 , // if set, is the return for if NAT will hairpin packets 300 int port=0, // port to use for the test, 0 to choose random port 301 StunAddress4* sAddr=0 // NIC to use 302 ); 303 304 /// prints a StunAddress 305 std::ostream& 306 operator<<( std::ostream& strm, const StunAddress4& addr); 307 308 std::ostream& 309 operator<< ( std::ostream& strm, const UInt128& ); 310 311 312 bool 313 stunServerProcessMsg( char* buf, 314 unsigned int bufLen, 315 StunAddress4& from, 316 StunAddress4& myAddr, 317 StunAddress4& altAddr, 318 StunMessage* resp, 319 StunAddress4* destination, 320 StunAtrString* hmacPassword, 321 bool* changePort, 322 bool* changeIp, 323 bool verbose); 324 325 int 326 stunOpenSocket( StunAddress4& dest, 327 StunAddress4* mappedAddr, 328 int port=0, 329 StunAddress4* srcAddr=0, 330 bool verbose=false ); 331 332 bool 333 stunOpenSocketPair( StunAddress4& dest, StunAddress4* mappedAddr, 334 int* fd1, int* fd2, 335 int srcPort=0, StunAddress4* srcAddr=0, 336 bool verbose=false); 337 338 int 339 stunRandomPort(); 340 341 #endif 342 343 344 /* ==================================================================== 345 * The Vovida Software License, Version 1.0 346 * 347 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. 348 * 349 * Redistribution and use in source and binary forms, with or without 350 * modification, are permitted provided that the following conditions 351 * are met: 352 * 353 * 1. Redistributions of source code must retain the above copyright 354 * notice, this list of conditions and the following disclaimer. 355 * 356 * 2. Redistributions in binary form must reproduce the above copyright 357 * notice, this list of conditions and the following disclaimer in 358 * the documentation and/or other materials provided with the 359 * distribution. 360 * 361 * 3. The names "VOCAL", "Vovida Open Communication Application Library", 362 * and "Vovida Open Communication Application Library (VOCAL)" must 363 * not be used to endorse or promote products derived from this 364 * software without prior written permission. For written 365 * permission, please contact vocal@vovida.org. 366 * 367 * 4. Products derived from this software may not be called "VOCAL", nor 368 * may "VOCAL" appear in their name, without prior written 369 * permission of Vovida Networks, Inc. 370 * 371 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 372 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 373 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND 374 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA 375 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES 376 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, 377 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 378 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 379 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 380 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 381 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 382 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 383 * DAMAGE. 384 * 385 * ==================================================================== 386 * 387 * This software consists of voluntary contributions made by Vovida 388 * Networks, Inc. and many individuals on behalf of Vovida Networks, 389 * Inc. For more information on Vovida Networks, Inc., please see 390 * <http://www.vovida.org/>. 391 * 392 */ 393 394 // Local Variables: 395 // mode:c++ 396 // c-file-style:"ellemtel" 397 // c-file-offsets:((case-label . +)) 398 // indent-tabs-mode:nil 399 // End: 400 401