📄 pana_udp_transport.h
字号:
/* BEGIN_COPYRIGHT *//* *//* Open Diameter: Open-source software for the Diameter and *//* Diameter related protocols *//* *//* Copyright (C) 2002-2004 Open Diameter Project *//* *//* This library is free software; you can redistribute it and/or modify *//* it under the terms of the GNU Lesser General Public License as *//* published by the Free Software Foundation; either version 2.1 of the *//* License, or (at your option) any later version. *//* *//* This library is distributed in the hope that it will be useful, *//* but WITHOUT ANY WARRANTY; without even the implied warranty of *//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *//* Lesser General Public License for more details. *//* *//* You should have received a copy of the GNU Lesser General Public *//* License along with this library; if not, write to the Free Software *//* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *//* USA. *//* *//* In addition, when you copy and redistribute some or the entire part of *//* the source code of this software with or without modification, you *//* MUST include this copyright notice in each copy. *//* *//* If you make any changes that are appeared to be useful, please send *//* sources that include the changed part to *//* diameter-developers@lists.sourceforge.net so that we can reflect your *//* changes to one unified version of this software. *//* *//* END_COPYRIGHT */#ifndef __PANA_UDP_TRANSPORT_H__#define __PANA_UDP_TRANSPORT_H__#include <string>#include "ace/SOCK_IO.h"#include "ace/ace_wchar.h"#include "ace/Handle_Set.h"#include "ace/Log_Msg.h"#include "pana_io.h"// #define PANA_UDP_ADDR_DEBUG#if defined(PANA_UDP_ADDR_DEBUG)#define PANA_DUMP_TXADDR(x) { char localBuf[64]; \ (x).addr_to_string(localBuf, \ sizeof(localBuf)); \ printf("Send: %s\n", localBuf); } #define PANA_DUMP_RXADDR(x) { char localBuf[64]; \ (x).addr_to_string(localBuf, \ sizeof(localBuf)); \ printf("Recv: %s\n", localBuf); } #else#define PANA_DUMP_TXADDR(x)#define PANA_DUMP_RXADDR(x)#endif#if defined(HAVE_GETIFADDRS) && defined(HAVE_IFADDRS_H)#include <ifaddrs.h>#endif#if defined(HAVE_NET_IF_DL_H)#include <net/if_dl.h>#endif#if !defined(ACE_WIN32)#include <net/if.h>#endifclass PANA_IfName{ public: std::string &Ifname() { return m_Ifname; } private: std::string m_Ifname;};#if defined(ACE_WIN32)#include "windows.h"#include "Iphlpapi.h"#include "ace/ace_wchar.h"class PANA_EXPORT PANA_IfAdapterInfo : public PANA_IfName{ public: PANA_IfAdapterInfo() { m_pAddresses = (IP_ADAPTER_ADDRESSES*)ACE_OS::malloc (sizeof(IP_ADAPTER_ADDRESSES)); ULONG outBufLen = 0; DWORD dwRetVal = 0;#if defined(ACE_HAS_IPV6) ULONG Family = (bool)PANA_CFG_GENERAL().m_IPv6Enabled ? AF_INET6 : AF_INET;#else ULONG Family = AF_INET;#endif if (GetAdaptersAddresses(Family, 0, NULL, m_pAddresses, &outBufLen) == ERROR_BUFFER_OVERFLOW) { ACE_OS::free(m_pAddresses); m_pAddresses = (IP_ADAPTER_ADDRESSES*)ACE_OS::malloc(outBufLen); } if ((dwRetVal = GetAdaptersAddresses(Family, 0, NULL, m_pAddresses, &outBufLen)) != NO_ERROR) { ACE_OS::free(m_pAddresses); m_pAddresses = NULL; } } ~PANA_IfAdapterInfo() { if (m_pAddresses) { ACE_OS::free(m_pAddresses); m_pAddresses = NULL; } } ACE_INT32 get_local_addr(PANA_DeviceIdContainer &localDevices) { PIP_ADAPTER_ADDRESSES pCurrAddresses = m_pAddresses; while (pCurrAddresses) { ACE_Wide_To_Ascii charDesc(pCurrAddresses->Description); if (! ACE_OS::strncmp(Ifname().data(), charDesc.char_rep(), Ifname().length())) { PIP_ADAPTER_UNICAST_ADDRESS pAddr = pCurrAddresses->FirstUnicastAddress; while (pAddr) { ACE_INET_Addr aceIpAddr((sockaddr_in*)pAddr->Address.lpSockaddr, pAddr->Address.iSockaddrLength); PANA_DeviceId *devId = PANA_DeviceIdConverter::CreateFromAddr (aceIpAddr); if (devId) { localDevices.push_back(devId); } pAddr = pAddr->Next; } PANA_DeviceId *hw = PANA_DeviceIdConverter::CreateFromLinkLayer (pCurrAddresses->PhysicalAddress, pCurrAddresses->PhysicalAddressLength); localDevices.push_back(hw); break; } pCurrAddresses = pCurrAddresses->Next; } return (pCurrAddresses) ? (0) : (-1); } ACE_UINT32 get_adapter_index(const char *ifname) { PIP_ADAPTER_ADDRESSES pCurrAddresses = m_pAddresses; while (pCurrAddresses) { ACE_Wide_To_Ascii charDesc(pCurrAddresses->Description); if (! ACE_OS::strncmp(Ifname().data(), charDesc.char_rep(), Ifname().length())) {#if defined(ACE_HAS_IPV6) return PANA_CFG_GENERAL().m_IPv6Enabled ? pCurrAddresses->Ipv6IfIndex : pCurrAddresses->IfIndex;#else return pCurrAddresses->IfIndex;#endif } pCurrAddresses = pCurrAddresses->Next; } return (-1); } private: PIP_ADAPTER_ADDRESSES m_pAddresses;};#elif defined(HAVE_GETIFADDRS) && defined(HAVE_IFADDRS_H)class PANA_EXPORT PANA_IfAdapterInfo : public PANA_IfName{ public: ACE_INT32 get_local_addr(PANA_DeviceIdContainer &localDevices) { int rc = (-1); struct ifaddrs *ifap, *ifn; if (getifaddrs(&ifap) == 0) { for (ifn = ifap; ifn != NULL; ifn = ifn->ifa_next) { if (ACE_OS::strcmp(ifn->ifa_name, Ifname().data())) { continue; } if ((ifn->ifa_addr == 0)) { continue; } ACE_INET_Addr addr; switch (ifn->ifa_addr->sa_family) { case AF_INET: addr.set_addr(ifn->ifa_addr, sizeof(sockaddr_in), 0); break; case AF_INET6: addr.set_addr(ifn->ifa_addr, sizeof(sockaddr_in6), 0); break;#if defined(AF_LINK) case AF_LINK: { struct sockaddr_dl *dl = (struct sockaddr_dl*)ifn->ifa_addr; PANA_DeviceId *hw = PANA_DeviceIdConverter::CreateFromLinkLayer (dl->sdl_data + dl->sdl_nlen, dl->sdl_alen);#endif#if defined(AF_PACKET)#include <linux/if_packet.h> case AF_PACKET: { struct sockaddr_ll *ll = (struct sockaddr_ll*)ifn->ifa_addr; PANA_DeviceId *hw = PANA_DeviceIdConverter::CreateFromLinkLayer (ll->sll_addr, ll->sll_halen); #endif if (hw) { localDevices.push_back(hw); rc = 0; } } default: continue; } PANA_DeviceId *id = PANA_DeviceIdConverter::CreateFromAddr (addr); if (id) { localDevices.push_back(id); rc = 0; } } freeifaddrs(ifap); } else { ACE_DEBUG((LM_ERROR, "(%P|%t) Get address failure\n")); } return (rc); } ACE_UINT32 get_adapter_index(const char *ifname) { return if_nametoindex(ifname); }};#else#if defined(ACE_HAS_IPV6)#error "You are compiling PANA with ACE_HAS_IPV6 enabled but your glibc does not support getifaddrs()"#endif#include <net/if_arp.h>class PANA_EXPORT PANA_IfAdapterInfo : public PANA_IfName{ public: ACE_INT32 get_local_addr(PANA_DeviceIdContainer &localDevices) { #define inaddrr(x) (*(struct in_addr *) &ifr->x[sizeof sa.sin_port]) #define IFRSIZE(sz) ((int)((sz) * sizeof (struct ifreq))) int ssize = 1, rc = (-1); struct ifreq *ifr; struct ifreq ifr_hw; struct ifconf ifc; struct sockaddr_in *sa; ifc.ifc_len = IFRSIZE(ssize); ifc.ifc_req = NULL; ACE_SOCK_IO querySo; if (querySo.open(SOCK_DGRAM, PF_INET, IPPROTO_UDP, 0) < 0) { ACE_DEBUG((LM_ERROR, "(%P|%t) Interface query socket failed to open\n")); return rc; } do { ++ssize; /* realloc buffer size until no overflow occurs */ ifc.ifc_req = (struct ifreq*)realloc(ifc.ifc_req, IFRSIZE(ssize)); if (ifc.ifc_req == NULL) { ACE_ERROR_RETURN((LM_ERROR, "(%P|%t) Allocation failure\n"), (-1)); } ifc.ifc_len = IFRSIZE(ssize); /* attempt to retrieve IF conf */ if (querySo.control(SIOCGIFCONF, &ifc)) { ACE_ERROR_RETURN((LM_ERROR, "(%P|%t) IOCTL error\n"), (-1)); } } while (IFRSIZE(ssize) <= ifc.ifc_len); ifr = ifc.ifc_req; for (;(char *) ifr < (char *) ifc.ifc_req + ifc.ifc_len; ++ifr) { if (ifr->ifr_addr.sa_data == (ifr+1)->ifr_addr.sa_data) { continue; /* duplicate, skip it */ } sa = (sockaddr_in*)&ifr->ifr_addr; if (sa->sin_addr.s_addr == 0) { continue; /* skip 0 address */ } if (ACE_OS::strcmp(ifr->ifr_name, Ifname().data())) { continue; /* skip this interface */ } if ((ifr->ifr_addr.sa_family != AF_INET) && (ifr->ifr_addr.sa_family != AF_INET6)) { continue; /* skip non IP interface */ } PANA_DeviceId *ip = PANA_DeviceIdConverter::CreateFromAddr (&ifr->ifr_addr, (ifr->ifr_addr.sa_family == AF_INET) ? sizeof(sockaddr_in) : sizeof(sockaddr_in6)); if (ip) { localDevices.push_back(ip); } ACE_OS::strcpy(ifr_hw.ifr_name, ifr->ifr_name); if (querySo.control(SIOCGIFHWADDR, &ifr_hw)) { continue; /* failed to get flags, skip it */ } PANA_DeviceId *hw; switch (ifr_hw.ifr_hwaddr.sa_family) { case ARPHRD_ETHER: hw = PANA_DeviceIdConverter::CreateFromLinkLayer (ifr_hw.ifr_hwaddr.sa_data, 6); localDevices.push_back(hw); break; default: // TBD: Add others here delete hw; break; } rc = 0; break; } if (ifc.ifc_req) { free(ifc.ifc_req); } return (rc); } ACE_UINT32 get_adapter_index(const char *ifname) { return if_nametoindex(ifname); }};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -