|
reSIProcate/stack
9694
|
00001 #if defined(HAVE_CONFIG_H) 00002 #include "config.h" 00003 #endif 00004 00005 #include "resip/stack/Tuple.hxx" 00006 #include "rutil/compat.hxx" 00007 00008 #include <iostream> 00009 #include <string.h> 00010 #include <sys/types.h> 00011 #include <cassert> 00012 00013 #if !defined (WIN32) 00014 #include <arpa/inet.h> 00015 #include <netinet/in.h> 00016 #if defined(__APPLE__) && !defined(s6_addr16) 00017 #define s6_addr16 __u6_addr.__u6_addr16 00018 #endif 00019 #endif 00020 00021 #include "rutil/Data.hxx" 00022 #include "rutil/DnsUtil.hxx" 00023 #include "rutil/GenericIPAddress.hxx" 00024 #include "rutil/HashMap.hxx" 00025 #include "rutil/MD5Stream.hxx" 00026 #include "rutil/Logger.hxx" 00027 #include "resip/stack/Transport.hxx" 00028 00029 00030 using namespace resip; 00031 00032 #define RESIPROCATE_SUBSYSTEM Subsystem::DNS 00033 00034 Tuple::Tuple() : 00035 mFlowKey(0), 00036 transportKey(0), 00037 transport(0), 00038 onlyUseExistingConnection(false), 00039 mTransportType(UNKNOWN_TRANSPORT) 00040 { 00041 sockaddr_in* addr4 = (sockaddr_in*)&mSockaddr; 00042 memset(addr4, 0, sizeof(sockaddr_in)); 00043 mSockaddr.sa_family = AF_INET; 00044 } 00045 00046 Tuple::Tuple(const GenericIPAddress& genericAddress, TransportType type, 00047 const Data& targetDomain) : 00048 mFlowKey(0), 00049 transportKey(0), 00050 transport(0), 00051 onlyUseExistingConnection(false), 00052 mTransportType(type), 00053 mTargetDomain(targetDomain) 00054 { 00055 setSockaddr(genericAddress); 00056 } 00057 00058 00059 Tuple::Tuple(const Data& printableAddr, 00060 int port, 00061 IpVersion ipVer, 00062 TransportType type, 00063 const Data& targetDomain) : 00064 mFlowKey(0), 00065 transportKey(0), 00066 transport(0), 00067 onlyUseExistingConnection(false), 00068 mTransportType(type), 00069 mTargetDomain(targetDomain) 00070 { 00071 if (ipVer == V4) 00072 { 00073 memset(&m_anonv4, 0, sizeof(m_anonv4)); 00074 m_anonv4.sin_family = AF_INET; 00075 m_anonv4.sin_port = htons(port); 00076 00077 if (printableAddr.empty()) 00078 { 00079 m_anonv4.sin_addr.s_addr = htonl(INADDR_ANY); 00080 } 00081 else 00082 { 00083 DnsUtil::inet_pton( printableAddr, m_anonv4.sin_addr); 00084 } 00085 } 00086 else 00087 { 00088 #ifdef USE_IPV6 00089 memset(&m_anonv6, 0, sizeof(m_anonv6)); 00090 m_anonv6.sin6_family = AF_INET6; 00091 m_anonv6.sin6_port = htons(port); 00092 if (printableAddr.empty()) 00093 { 00094 m_anonv6.sin6_addr = in6addr_any; 00095 } 00096 else 00097 { 00098 DnsUtil::inet_pton( printableAddr, m_anonv6.sin6_addr); 00099 } 00100 #else 00101 assert(0); 00102 #endif 00103 } 00104 } 00105 00106 Tuple::Tuple(const Data& printableAddr, 00107 int port, 00108 TransportType ptype, 00109 const Data& targetDomain) : 00110 mFlowKey(0), 00111 transportKey(0), 00112 transport(0), 00113 onlyUseExistingConnection(false), 00114 mTransportType(ptype), 00115 mTargetDomain(targetDomain) 00116 { 00117 if (DnsUtil::isIpV4Address(printableAddr)) 00118 { 00119 memset(&m_anonv4, 0, sizeof(m_anonv4)); 00120 00121 DnsUtil::inet_pton( printableAddr, m_anonv4.sin_addr); 00122 m_anonv4.sin_family = AF_INET; 00123 m_anonv4.sin_port = htons(port); 00124 } 00125 else 00126 { 00127 #ifdef USE_IPV6 00128 memset(&m_anonv6, 0, sizeof(m_anonv6)); 00129 DnsUtil::inet_pton( printableAddr, m_anonv6.sin6_addr); 00130 m_anonv6.sin6_family = AF_INET6; 00131 m_anonv6.sin6_port = htons(port); 00132 #else 00133 assert(0); 00134 #endif 00135 } 00136 } 00137 00138 Tuple::Tuple(const in_addr& ipv4, 00139 int port, 00140 TransportType ptype, 00141 const Data& targetDomain) 00142 :mFlowKey(0), 00143 transportKey(0), 00144 transport(0), 00145 onlyUseExistingConnection(false), 00146 mTransportType(ptype), 00147 mTargetDomain(targetDomain) 00148 { 00149 memset(&m_anonv4, 0, sizeof(sockaddr_in)); 00150 m_anonv4.sin_addr = ipv4; 00151 m_anonv4.sin_port = htons(port); 00152 m_anonv4.sin_family = AF_INET; 00153 } 00154 00155 #ifdef USE_IPV6 00156 Tuple::Tuple(const in6_addr& ipv6, 00157 int port, 00158 TransportType ptype, 00159 const Data& targetDomaina) 00160 :mFlowKey(0), 00161 transportKey(0), 00162 transport(0), 00163 onlyUseExistingConnection(false), 00164 mTransportType(ptype), 00165 mTargetDomain(targetDomaina) 00166 { 00167 memset(&m_anonv6, 0, sizeof(sockaddr_in6)); 00168 m_anonv6.sin6_addr = ipv6; 00169 m_anonv6.sin6_port = htons(port); 00170 m_anonv6.sin6_family = AF_INET6; 00171 } 00172 #endif 00173 00174 Tuple::Tuple(const struct sockaddr& addr, 00175 TransportType ptype, 00176 const Data& targetDomain) : 00177 mFlowKey(0), 00178 transportKey(0), 00179 transport(0), 00180 onlyUseExistingConnection(false), 00181 mSockaddr(addr), 00182 mTransportType(ptype), 00183 mTargetDomain(targetDomain) 00184 { 00185 if (addr.sa_family == AF_INET) 00186 { 00187 m_anonv4 = (sockaddr_in&)(addr); 00188 } 00189 #ifdef USE_IPV6 00190 else if (addr.sa_family == AF_INET6) 00191 { 00192 m_anonv6 = (sockaddr_in6&)(addr); 00193 } 00194 #endif 00195 else 00196 { 00197 assert(0); 00198 } 00199 } 00200 00201 void 00202 Tuple::setSockaddr(const GenericIPAddress& addr) 00203 { 00204 if (addr.isVersion4()) 00205 { 00206 m_anonv4 = addr.v4Address; 00207 } 00208 else 00209 #ifdef USE_IPV6 00210 { 00211 m_anonv6 = addr.v6Address; 00212 } 00213 #else 00214 { 00215 assert(0); 00216 } 00217 #endif 00218 } 00219 00220 void 00221 Tuple::writeBinaryToken(const resip::Tuple& tuple, resip::Data& container, const Data& salt) 00222 { 00223 // .bwc. Maybe should just write the raw sockaddr into a buffer, and tack 00224 // on the flowid and onlyUseExistingConnection flag. Would require 10 extra 00225 // bytes for V6, and 14 extra bytes for V4. 00226 // V6: sin6_len(1), sin6_flowinfo(4), flowId(4), onlyUseExistingConnection(1) 00227 // V4: sin_family(2 instead of 1), sin_zero(8), flowId(4), onlyUseExistingConnection(1) 00228 UInt32 rawToken[7]; 00229 memset(&rawToken, 0, 28); 00230 00231 rawToken[0] = tuple.mFlowKey; 00232 00233 rawToken[1] = tuple.transportKey; 00234 00235 // 0xXXXX0000 00236 rawToken[2] += (tuple.getPort() << 16); 00237 00238 // 0x0000XX00 00239 rawToken[2] += (tuple.getType() << 8); 00240 00241 // 0x000000X0 00242 if(tuple.onlyUseExistingConnection) 00243 { 00244 rawToken[2] += 0x00000010; 00245 } 00246 00247 #ifdef USE_IPV6 00248 if(tuple.ipVersion()==V6) 00249 { 00250 // 0x0000000X 00251 rawToken[2] += 0x00000001; 00252 in6_addr address = reinterpret_cast<const sockaddr_in6&>(tuple.getSockaddr()).sin6_addr; 00253 assert(sizeof(address)==16); 00254 memcpy(&rawToken[3],&address,16); 00255 } 00256 else 00257 #endif 00258 { 00259 in_addr address = reinterpret_cast<const sockaddr_in&>(tuple.getSockaddr()).sin_addr; 00260 assert(sizeof(address)==4); 00261 memcpy(&rawToken[3],&address,4); 00262 } 00263 00264 container.clear(); 00265 container.reserve(((tuple.ipVersion()==V6) ? 28 : 16) + (salt.empty() ? 0 : 32)); 00266 container.append((char*)&rawToken[0],(tuple.ipVersion()==V6) ? 28 : 16); 00267 00268 if(!salt.empty()) 00269 { 00270 // TODO - potentially use SHA1 HMAC if USE_SSL is defined for stronger encryption 00271 MD5Stream ms; 00272 ms << container << salt; 00273 container += ms.getHex(); 00274 } 00275 } 00276 00277 00278 Tuple 00279 Tuple::makeTupleFromBinaryToken(const resip::Data& binaryFlowToken, const Data& salt) 00280 { 00281 // To check if size is valid, we first need the IP version, so make sure the token is at least 00282 // the size of an IPv4 token 00283 if(binaryFlowToken.size()<16) 00284 { 00285 // !bwc! Should not assert here, since this sort of thing 00286 // can come off the wire easily. 00287 // TODO Throw an exception here? 00288 DebugLog(<<"binary flow token was too small: " << binaryFlowToken.size()); 00289 return Tuple(); 00290 } 00291 00292 const UInt32* rawToken=reinterpret_cast<const UInt32*>(binaryFlowToken.data()); 00293 00294 FlowKey mFlowKey=rawToken[0]; 00295 TransportKey transportKey=rawToken[1]; 00296 00297 IpVersion version = (rawToken[2] & 0x00000001 ? V6 : V4); 00298 00299 bool isRealFlow = (rawToken[2] & 0x00000010 ? true : false); 00300 00301 UInt8 temp = (TransportType)((rawToken[2] & 0x00000F00) >> 8); 00302 if(temp >= MAX_TRANSPORT) 00303 { 00304 DebugLog(<<"Garbage transport type in flow token: " << temp ); 00305 return Tuple(); 00306 } 00307 TransportType type = (TransportType)temp; 00308 00309 UInt16 port= (rawToken[2] >> 16); 00310 00311 // Now that we have the version we can do a more accurate check on the size 00312 if(!((version==V4 && salt.empty() && binaryFlowToken.size()==16) || 00313 (version==V4 && !salt.empty() && binaryFlowToken.size()==48) || 00314 (version==V6 && salt.empty() && binaryFlowToken.size()==28) || 00315 (version==V6 && !salt.empty() && binaryFlowToken.size()==60))) 00316 { 00317 DebugLog(<<"Binary flow token is the wrong size for its IP version."); 00318 return Tuple(); 00319 } 00320 00321 // If salt is specified, validate HMAC 00322 if(!salt.empty()) 00323 { 00324 unsigned int tokenSizeLessHMAC = version == V4 ? 16 : 28; 00325 Data flowTokenLessHMAC(Data::Share, binaryFlowToken.data(), tokenSizeLessHMAC); 00326 Data flowTokenHMAC(Data::Share, binaryFlowToken.data()+tokenSizeLessHMAC, 32); 00327 MD5Stream ms; 00328 ms << flowTokenLessHMAC << salt; 00329 if(ms.getHex() != flowTokenHMAC) 00330 { 00331 DebugLog(<<"Binary flow token has invalid HMAC, not our token"); 00332 return Tuple(); 00333 } 00334 } 00335 00336 if(version==V6) 00337 { 00338 #ifdef USE_IPV6 00339 in6_addr address; 00340 assert(sizeof(address)==16); 00341 memcpy(&address,&rawToken[3],16); 00342 Tuple result(address,port,type); 00343 #else 00344 Tuple result(resip::Data::Empty, port, type); 00345 #endif 00346 result.mFlowKey=(FlowKey)mFlowKey; 00347 result.transportKey = (TransportKey)transportKey; 00348 result.onlyUseExistingConnection=isRealFlow; 00349 return result; 00350 } 00351 00352 in_addr address; 00353 assert(sizeof(address)==4); 00354 memcpy(&address,&rawToken[3],4); 00355 Tuple result(address,port,type); 00356 result.mFlowKey=(FlowKey)mFlowKey; 00357 result.transportKey = (TransportKey)transportKey; 00358 result.onlyUseExistingConnection=isRealFlow; 00359 return result; 00360 } 00361 00362 Data 00363 Tuple::presentationFormat() const 00364 { 00365 #ifdef USE_IPV6 00366 if (isV4()) 00367 { 00368 return Tuple::inet_ntop(*this); 00369 } 00370 else if (IN6_IS_ADDR_V4MAPPED(&m_anonv6.sin6_addr)) 00371 { 00372 return DnsUtil::inet_ntop(*(reinterpret_cast<const in_addr*>( 00373 (reinterpret_cast<const unsigned char*>(&m_anonv6.sin6_addr) + 12)))); 00374 } 00375 else 00376 { 00377 return Tuple::inet_ntop(*this); 00378 } 00379 #else 00380 return Tuple::inet_ntop(*this); 00381 #endif 00382 00383 } 00384 00385 void 00386 Tuple::setPort(int port) 00387 { 00388 if (mSockaddr.sa_family == AF_INET) // v4 00389 { 00390 m_anonv4.sin_port = htons(port); 00391 } 00392 else 00393 { 00394 #ifdef USE_IPV6 00395 m_anonv6.sin6_port = htons(port); 00396 #else 00397 assert(0); 00398 #endif 00399 } 00400 } 00401 00402 int 00403 Tuple::getPort() const 00404 { 00405 if (mSockaddr.sa_family == AF_INET) // v4 00406 { 00407 return ntohs(m_anonv4.sin_port); 00408 } 00409 else 00410 { 00411 #ifdef USE_IPV6 00412 return ntohs(m_anonv6.sin6_port); 00413 #else 00414 assert(0); 00415 #endif 00416 } 00417 00418 return -1; 00419 } 00420 00421 bool 00422 Tuple::isAnyInterface() const 00423 { 00424 if (isV4()) 00425 { 00426 return m_anonv4.sin_addr.s_addr == htonl(INADDR_ANY); 00427 } 00428 #if defined (USE_IPV6) 00429 else 00430 { 00431 return memcmp(&m_anonv6.sin6_addr, &in6addr_any, sizeof(in6_addr)) == 0; 00432 } 00433 #else 00434 return false; 00435 #endif 00436 } 00437 00438 static Tuple loopbackv4("127.0.0.1",0,UNKNOWN_TRANSPORT); 00439 bool 00440 Tuple::isLoopback() const 00441 { 00442 if(ipVersion()==V4) 00443 { 00444 return isEqualWithMask(loopbackv4,8,true,true); 00445 } 00446 else if (ipVersion()==V6) 00447 { 00448 #ifdef USE_IPV6 00449 #if defined(__linux__) || defined(__APPLE__) || defined(WIN32) 00450 return IN6_IS_ADDR_LOOPBACK(&(m_anonv6.sin6_addr)) != 0; 00451 #else 00452 return ((*(const __uint32_t *)(const void *)(&(m_anonv6.sin6_addr.s6_addr[0])) == 0) && 00453 (*(const __uint32_t *)(const void *)(&(m_anonv6.sin6_addr.s6_addr[4])) == 0) && 00454 (*(const __uint32_t *)(const void *)(&(m_anonv6.sin6_addr.s6_addr[8])) == 0) && 00455 (*(const __uint32_t *)(const void *)(&(m_anonv6.sin6_addr.s6_addr[12])) == ntohl(1))); 00456 #endif 00457 #endif 00458 } 00459 else 00460 { 00461 assert(0); 00462 } 00463 00464 return false; 00465 } 00466 00467 bool 00468 Tuple::isV4() const 00469 { 00470 return mSockaddr.sa_family == AF_INET; 00471 } 00472 00473 IpVersion 00474 Tuple::ipVersion() const 00475 { 00476 return mSockaddr.sa_family == AF_INET ? V4 : V6; 00477 } 00478 00479 static Tuple v4privateaddrbase1("10.0.0.0",0,UNKNOWN_TRANSPORT); 00480 static Tuple v4privateaddrbase2("172.16.0.0",0,UNKNOWN_TRANSPORT); 00481 static Tuple v4privateaddrbase3("192.168.0.0",0,UNKNOWN_TRANSPORT); 00482 00483 #ifdef USE_IPV6 00484 static Tuple v6privateaddrbase("fc00::",0,UNKNOWN_TRANSPORT); 00485 #endif 00486 00487 bool 00488 Tuple::isPrivateAddress() const 00489 { 00490 if(ipVersion()==V4) 00491 { 00492 // RFC 1918 00493 return isEqualWithMask(v4privateaddrbase1,8,true,true) || // 10.0.0.0 - 10.255.255.255 (10/8 prefix) 00494 isEqualWithMask(v4privateaddrbase2,12,true,true) || // 172.16.0.0 - 172.31.255.255 (172.16/12 prefix) 00495 isEqualWithMask(v4privateaddrbase3,16,true,true) || // 192.168.0.0 - 192.168.255.255 (192.168/16 prefix) 00496 isLoopback(); 00497 } 00498 #ifdef USE_IPV6 00499 else if (ipVersion()==V6) 00500 { 00501 // RFC 4193 00502 // ?slg? should we look specifically for ipv4 mapped/compatible address and apply V4 rules to them? 00503 return isEqualWithMask(v6privateaddrbase,7,true,true) || // fc00::/7 00504 isLoopback(); 00505 } 00506 #endif 00507 else 00508 { 00509 assert(0); 00510 } 00511 00512 return false; 00513 } 00514 00515 socklen_t 00516 Tuple::length() const 00517 { 00518 if (mSockaddr.sa_family == AF_INET) // v4 00519 { 00520 return sizeof(sockaddr_in); 00521 } 00522 #ifdef USE_IPV6 00523 else if (mSockaddr.sa_family == AF_INET6) // v6 00524 { 00525 return sizeof(sockaddr_in6); 00526 } 00527 #endif 00528 00529 assert(0); 00530 return 0; 00531 } 00532 00533 00534 bool Tuple::operator==(const Tuple& rhs) const 00535 { 00536 if (mSockaddr.sa_family == rhs.mSockaddr.sa_family) 00537 { 00538 if (mSockaddr.sa_family == AF_INET) // v4 00539 { 00540 return (m_anonv4.sin_port == rhs.m_anonv4.sin_port && 00541 mTransportType == rhs.mTransportType && 00542 memcmp(&m_anonv4.sin_addr, &rhs.m_anonv4.sin_addr, sizeof(in_addr)) == 0); 00543 } 00544 else // v6 00545 { 00546 #ifdef USE_IPV6 00547 return (m_anonv6.sin6_port == rhs.m_anonv6.sin6_port && 00548 mTransportType == rhs.mTransportType && 00549 memcmp(&m_anonv6.sin6_addr, &rhs.m_anonv6.sin6_addr, sizeof(in6_addr)) == 0); 00550 #else 00551 assert(0); 00552 return false; 00553 #endif 00554 } 00555 } 00556 else 00557 { 00558 return false; 00559 } 00560 00561 // !dlb! don't include connection 00562 } 00563 00564 bool 00565 Tuple::operator<(const Tuple& rhs) const 00566 { 00567 if (mTransportType < rhs.mTransportType) 00568 { 00569 return true; 00570 } 00571 else if (mTransportType > rhs.mTransportType) 00572 { 00573 return false; 00574 } 00575 else if (mSockaddr.sa_family == AF_INET && rhs.mSockaddr.sa_family == AF_INET) 00576 { 00577 int c=memcmp(&m_anonv4.sin_addr, 00578 &rhs.m_anonv4.sin_addr, 00579 sizeof(in_addr)); 00580 00581 if (c < 0) 00582 { 00583 return true; 00584 } 00585 else if (c > 0) 00586 { 00587 return false; 00588 } 00589 else if (m_anonv4.sin_port < rhs.m_anonv4.sin_port) 00590 { 00591 return true; 00592 } 00593 else 00594 { 00595 return false; 00596 } 00597 } 00598 #ifdef USE_IPV6 00599 else if (mSockaddr.sa_family == AF_INET6 && 00600 rhs.mSockaddr.sa_family == AF_INET6) 00601 { 00602 int c = memcmp(&m_anonv6.sin6_addr, 00603 &rhs.m_anonv6.sin6_addr, 00604 sizeof(in6_addr)); 00605 if (c < 0) 00606 { 00607 return true; 00608 } 00609 else if (c > 0) 00610 { 00611 return false; 00612 } 00613 else if (m_anonv6.sin6_port < rhs.m_anonv6.sin6_port) 00614 { 00615 return true; 00616 } 00617 else 00618 { 00619 return false; 00620 } 00621 } 00622 else if (mSockaddr.sa_family == AF_INET6 && 00623 rhs.mSockaddr.sa_family == AF_INET) 00624 { 00625 return true; 00626 } 00627 else if (mSockaddr.sa_family == AF_INET && 00628 rhs.mSockaddr.sa_family == AF_INET6) 00629 { 00630 return false; 00631 } 00632 #endif 00633 else 00634 { 00635 //assert(0); 00636 return false; 00637 } 00638 } 00639 00640 EncodeStream& 00641 resip::operator<<(EncodeStream& ostrm, const Tuple& tuple) 00642 { 00643 ostrm << "[ " ; 00644 00645 #ifdef USE_IPV6 00646 if (tuple.mSockaddr.sa_family == AF_INET6) 00647 { 00648 ostrm << "V6 " << DnsUtil::inet_ntop(tuple.m_anonv6.sin6_addr) << " port=" << tuple.getPort(); 00649 } 00650 else 00651 #endif 00652 if (tuple.mSockaddr.sa_family == AF_INET) 00653 { 00654 ostrm << "V4 " << Tuple::inet_ntop(tuple) << ":" << tuple.getPort(); 00655 } 00656 else 00657 { 00658 assert(0); 00659 } 00660 00661 ostrm << " " << Tuple::toData(tuple.mTransportType); 00662 ostrm << " target domain="; 00663 if (tuple.mTargetDomain.empty()) ostrm << "unspecified"; 00664 else ostrm << tuple.mTargetDomain; 00665 00666 ostrm << " mFlowKey=" << tuple.mFlowKey 00667 << " ]"; 00668 00669 return ostrm; 00670 } 00671 00672 size_t 00673 Tuple::hash() const 00674 { 00675 // !dlb! do not include the connection 00676 #ifdef USE_IPV6 00677 if (mSockaddr.sa_family == AF_INET6) 00678 { 00679 const sockaddr_in6& in6 = 00680 reinterpret_cast<const sockaddr_in6&>(mSockaddr); 00681 00682 return size_t(Data(Data::Share, (const char *)&in6.sin6_addr.s6_addr, sizeof(in6.sin6_addr.s6_addr)).hash() + 00683 5*in6.sin6_port + 00684 25*mTransportType); 00685 } 00686 else 00687 #endif 00688 { 00689 const sockaddr_in& in4 = 00690 reinterpret_cast<const sockaddr_in&>(mSockaddr); 00691 00692 return size_t(in4.sin_addr.s_addr + 00693 5*in4.sin_port + 00694 25*mTransportType); 00695 } 00696 } 00697 00698 HashValueImp(resip::Tuple, data.hash()); 00699 00700 TransportType 00701 Tuple::toTransport(const Data& transportName) 00702 { 00703 return resip::toTransportType(transportName); // TransportTypes.hxx 00704 }; 00705 00706 const Data& 00707 Tuple::toData(TransportType type) 00708 { 00709 return resip::toData(type); // TransportTypes.hxx 00710 } 00711 00712 const Data& 00713 Tuple::toDataLower(TransportType type) 00714 { 00715 return resip::toDataLower(type); // TransportTypes.hxx 00716 } 00717 00718 Data 00719 Tuple::inet_ntop(const Tuple& tuple) 00720 { 00721 #ifdef USE_IPV6 00722 if (!tuple.isV4()) 00723 { 00724 const sockaddr_in6& addr = reinterpret_cast<const sockaddr_in6&>(tuple.getSockaddr()); 00725 return DnsUtil::inet_ntop(addr.sin6_addr); 00726 } 00727 else 00728 #endif 00729 { 00730 const sockaddr_in& addr = reinterpret_cast<const sockaddr_in&>(tuple.getSockaddr()); 00731 return DnsUtil::inet_ntop(addr.sin_addr); 00732 } 00733 } 00734 00735 00736 bool 00737 Tuple::isEqualWithMask(const Tuple& compare, short mask, bool ignorePort, bool ignoreTransport) const 00738 { 00739 if(ignoreTransport || getType() == compare.getType()) // check if transport type matches 00740 { 00741 if (mSockaddr.sa_family == compare.getSockaddr().sa_family && mSockaddr.sa_family == AF_INET) // v4 00742 { 00743 sockaddr_in* addr1 = (sockaddr_in*)&mSockaddr; 00744 sockaddr_in* addr2 = (sockaddr_in*)&compare.getSockaddr(); 00745 00746 return ((ignorePort || addr1->sin_port == addr2->sin_port) && 00747 (addr1->sin_addr.s_addr & htonl((0xFFFFFFFF << (32 - mask)))) == 00748 (addr2->sin_addr.s_addr & htonl((0xFFFFFFFF << (32 - mask))))); 00749 } 00750 #ifdef USE_IPV6 00751 else if (mSockaddr.sa_family == compare.getSockaddr().sa_family && mSockaddr.sa_family == AF_INET6) // v6 00752 { 00753 sockaddr_in6* addr1 = (sockaddr_in6*)&mSockaddr; 00754 sockaddr_in6* addr2 = (sockaddr_in6*)&compare.getSockaddr(); 00755 00756 if(ignorePort || addr1->sin6_port == addr2->sin6_port) 00757 { 00758 unsigned long mask6part; 00759 unsigned long temp; 00760 bool match=true; 00761 for(int i = 3; i >= 0; i--) 00762 { 00763 if(mask <= 32*i) 00764 { 00765 mask6part = 0; 00766 } 00767 else 00768 { 00769 temp = mask - 32*i; 00770 if(temp >= 32) 00771 { 00772 mask6part = 0xffffffff; 00773 } 00774 else 00775 { 00776 mask6part = 0xffffffff << (32 - temp); 00777 } 00778 } 00779 #ifdef WIN32 00780 if((*((unsigned long*)&addr1->sin6_addr.u.Word[i*2]) & htonl(mask6part)) != 00781 (*((unsigned long*)&addr2->sin6_addr.u.Word[i*2]) & htonl(mask6part))) 00782 #elif defined(sun) 00783 // sun has no s6_addr16 00784 if((*((unsigned long*)&addr1->sin6_addr._S6_un._S6_u32[i]) & htonl(mask6part)) != 00785 (*((unsigned long*)&addr2->sin6_addr._S6_un._S6_u32[i]) & htonl(mask6part))) 00786 #elif defined(__APPLE__) || defined(__OpenBSD__) || defined(__FreeBSD__) 00787 // bsd has no s6_addr16 00788 if((*((unsigned long*)&addr1->sin6_addr.__u6_addr.__u6_addr32[i]) & htonl(mask6part)) != 00789 (*((unsigned long*)&addr2->sin6_addr.__u6_addr.__u6_addr32[i]) & htonl(mask6part))) 00790 #else 00791 if((*((unsigned long*)&addr1->sin6_addr.s6_addr16[i*2]) & htonl(mask6part)) != 00792 (*((unsigned long*)&addr2->sin6_addr.s6_addr16[i*2]) & htonl(mask6part))) 00793 #endif 00794 { 00795 match=false; 00796 break; 00797 } 00798 } 00799 if(match) 00800 { 00801 return true; 00802 } 00803 } 00804 } 00805 #endif 00806 } 00807 return false; 00808 } 00809 00810 00811 // special comparitors 00812 bool 00813 Tuple::AnyInterfaceCompare::operator()(const Tuple& lhs, 00814 const Tuple& rhs) const 00815 { 00816 if (lhs.mTransportType < rhs.mTransportType) 00817 { 00818 return true; 00819 } 00820 else if (lhs.mTransportType > rhs.mTransportType) 00821 { 00822 return false; 00823 } 00824 else if (lhs.mSockaddr.sa_family == AF_INET && rhs.mSockaddr.sa_family == AF_INET) 00825 { 00826 if (lhs.m_anonv4.sin_port < rhs.m_anonv4.sin_port) 00827 { 00828 return true; 00829 } 00830 else 00831 { 00832 return false; 00833 } 00834 } 00835 #ifdef USE_IPV6 00836 else if (lhs.mSockaddr.sa_family == AF_INET6 && 00837 rhs.mSockaddr.sa_family == AF_INET6) 00838 { 00839 if (lhs.m_anonv6.sin6_port < rhs.m_anonv6.sin6_port) 00840 { 00841 return true; 00842 } 00843 else 00844 { 00845 return false; 00846 } 00847 } 00848 else if (lhs.mSockaddr.sa_family == AF_INET6 && 00849 rhs.mSockaddr.sa_family == AF_INET) 00850 { 00851 return true; 00852 } 00853 else if (lhs.mSockaddr.sa_family == AF_INET && 00854 rhs.mSockaddr.sa_family == AF_INET6) 00855 { 00856 return false; 00857 } 00858 #endif 00859 else 00860 { 00861 return false; 00862 } 00863 }; 00864 00865 bool 00866 Tuple::AnyPortCompare::operator()(const Tuple& lhs, 00867 const Tuple& rhs) const 00868 { 00869 if (lhs.mTransportType < rhs.mTransportType) 00870 { 00871 return true; 00872 } 00873 else if (lhs.mTransportType > rhs.mTransportType) 00874 { 00875 return false; 00876 } 00877 else if (lhs.mSockaddr.sa_family == AF_INET && rhs.mSockaddr.sa_family == AF_INET) 00878 { 00879 int c = memcmp(&lhs.m_anonv4.sin_addr, 00880 &rhs.m_anonv4.sin_addr, 00881 sizeof(in_addr)); 00882 00883 if (c < 0) 00884 { 00885 return true; 00886 } 00887 else if (c > 0) 00888 { 00889 return false; 00890 } 00891 } 00892 #ifdef USE_IPV6 00893 else if (lhs.mSockaddr.sa_family == AF_INET6 && 00894 rhs.mSockaddr.sa_family == AF_INET6) 00895 { 00896 int c = memcmp(&lhs.m_anonv6.sin6_addr, 00897 &rhs.m_anonv6.sin6_addr, 00898 sizeof(in6_addr)); 00899 if (c < 0) 00900 { 00901 return true; 00902 } 00903 else if (c > 0) 00904 { 00905 return false; 00906 } 00907 } 00908 else if (lhs.mSockaddr.sa_family == AF_INET6 && 00909 rhs.mSockaddr.sa_family == AF_INET) 00910 { 00911 return true; 00912 } 00913 else if (lhs.mSockaddr.sa_family == AF_INET && 00914 rhs.mSockaddr.sa_family == AF_INET6) 00915 { 00916 return false; 00917 } 00918 #endif 00919 00920 return false; 00921 } 00922 00923 bool 00924 Tuple::FlowKeyCompare::operator()(const Tuple& lhs, 00925 const Tuple& rhs) const 00926 { 00927 if (lhs == rhs) 00928 { 00929 return lhs.mFlowKey < rhs.mFlowKey; 00930 } 00931 return lhs < rhs; 00932 }; 00933 00934 GenericIPAddress 00935 Tuple::toGenericIPAddress() const 00936 { 00937 if (isV4()) 00938 { 00939 return GenericIPAddress(m_anonv4); 00940 } 00941 else 00942 #ifdef USE_IPV6 00943 { 00944 return GenericIPAddress(m_anonv6); 00945 } 00946 #else 00947 { 00948 assert(0); 00949 return m_anonv4; //bogus 00950 } 00951 #endif 00952 } 00953 00954 bool 00955 Tuple::AnyPortAnyInterfaceCompare::operator()(const Tuple& lhs, 00956 const Tuple& rhs) const 00957 { 00958 if (lhs.mTransportType < rhs.mTransportType) 00959 { 00960 return true; 00961 } 00962 else if (lhs.mTransportType > rhs.mTransportType) 00963 { 00964 return false; 00965 } 00966 #ifdef USE_IPV6 00967 else if (lhs.mSockaddr.sa_family == AF_INET6 && 00968 rhs.mSockaddr.sa_family == AF_INET) 00969 { 00970 return true; 00971 } 00972 else if (lhs.mSockaddr.sa_family == AF_INET && 00973 rhs.mSockaddr.sa_family == AF_INET6) 00974 { 00975 return false; 00976 } 00977 #endif 00978 else 00979 { 00980 return false; 00981 } 00982 }; 00983 00984 /* ==================================================================== 00985 * The Vovida Software License, Version 1.0 00986 * 00987 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. 00988 * 00989 * Redistribution and use in source and binary forms, with or without 00990 * modification, are permitted provided that the following conditions 00991 * are met: 00992 * 00993 * 1. Redistributions of source code must retain the above copyright 00994 * notice, this list of conditions and the following disclaimer. 00995 * 00996 * 2. Redistributions in binary form must reproduce the above copyright 00997 * notice, this list of conditions and the following disclaimer in 00998 * the documentation and/or other materials provided with the 00999 * distribution. 01000 * 01001 * 3. The names "VOCAL", "Vovida Open Communication Application Library", 01002 * and "Vovida Open Communication Application Library (VOCAL)" must 01003 * not be used to endorse or promote products derived from this 01004 * software without prior written permission. For written 01005 * permission, please contact vocal@vovida.org. 01006 * 01007 * 4. Products derived from this software may not be called "VOCAL", nor 01008 * may "VOCAL" appear in their name, without prior written 01009 * permission of Vovida Networks, Inc. 01010 * 01011 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 01012 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 01013 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND 01014 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA 01015 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES 01016 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, 01017 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 01018 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 01019 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 01020 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 01021 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 01022 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 01023 * DAMAGE. 01024 * 01025 * ==================================================================== 01026 * 01027 * This software consists of voluntary contributions made by Vovida 01028 * Networks, Inc. and many individuals on behalf of Vovida Networks, 01029 * Inc. For more information on Vovida Networks, Inc., please see 01030 * <http://www.vovida.org/>. 01031 * 01032 */
1.7.5.1