📄 socket.cxx
字号:
BOOL PSocket::os_sendto( const void * buf, // Data to be written as URGENT TCP data. PINDEX len, // Number of bytes pointed to by <CODE>buf</CODE>. int flags, sockaddr * addr, // Address to which the datagram is sent. PINDEX addrlen) { lastWriteCount = 0; if (!IsOpen()) { lastError = NotOpen; return FALSE; } // attempt to read data int writeResult; if (addr != NULL) writeResult = ::sendto(os_handle, (char *)buf, len, flags, (sockaddr *)addr, addrlen); else writeResult = ::send(os_handle, (char *)buf, len, flags); if (writeResult > 0) { PThread::Yield(); lastWriteCount = writeResult; return TRUE; } if (errno != EWOULDBLOCK) return ConvertOSError(-1); if (!PXSetIOBlock(PXWriteBlock, writeTimeout)) { lastError = Timeout; return FALSE; } // attempt to read data if (addr != NULL) lastWriteCount = ::sendto(os_handle, (char *)buf, len, flags, (sockaddr *)addr, addrlen); else lastWriteCount = ::send(os_handle, (char *)buf, len, flags); if (ConvertOSError(lastWriteCount)) return lastWriteCount > 0; return FALSE;}BOOL PSocket::Read(void * buf, PINDEX len){ if (os_handle < 0) { lastError = NotOpen; return FALSE; } if (!PXSetIOBlock(PXReadBlock, readTimeout)) return FALSE; if (ConvertOSError(lastReadCount = ::recv(os_handle, (char *)buf, len, 0))) return lastReadCount > 0; lastReadCount = 0; return FALSE;}////////////////////////////////////////////////////////////////////// PEthSocket//PEthSocket::PEthSocket(PINDEX, PINDEX, PINDEX){ medium = MediumUnknown; filterMask = FilterDirected|FilterBroadcast; filterType = TypeAll; fakeMacHeader = FALSE; ipppInterface = FALSE;}PEthSocket::~PEthSocket(){ Close();}BOOL PEthSocket::Connect(const PString & interfaceName){ Close(); fakeMacHeader = FALSE; ipppInterface = FALSE; if (strncmp("eth", interfaceName, 3) == 0) medium = Medium802_3; else if (strncmp("lo", interfaceName, 2) == 0) medium = MediumLoop; else if (strncmp("sl", interfaceName, 2) == 0) { medium = MediumWan; fakeMacHeader = TRUE; } else if (strncmp("ppp", interfaceName, 3) == 0) { medium = MediumWan; fakeMacHeader = TRUE; } else if (strncmp("ippp", interfaceName, 4) == 0) { medium = MediumWan; ipppInterface = TRUE; } else { lastError = NotFound; osError = ENOENT; return FALSE; }#if defined(SIO_Get_MAC_Address) && !defined(__BEOS__) PUDPSocket ifsock; struct ifreq ifr; ifr.ifr_addr.sa_family = AF_INET; strcpy(ifr.ifr_name, interfaceName); if (!ConvertOSError(ioctl(ifsock.GetHandle(), SIO_Get_MAC_Address, &ifr))) return FALSE; memcpy(&macAddress, ifr.ifr_macaddr, sizeof(macAddress));#endif channelName = interfaceName; return OpenSocket();}BOOL PEthSocket::OpenSocket(){#ifdef SOCK_PACKET if (!ConvertOSError(os_handle = os_socket(AF_INET, SOCK_PACKET, htons(filterType)))) return FALSE; struct sockaddr addr; memset(&addr, 0, sizeof(addr)); addr.sa_family = AF_INET; strcpy(addr.sa_data, channelName); if (!ConvertOSError(bind(os_handle, &addr, sizeof(addr)))) { os_close(); os_handle = -1; return FALSE; }#endif return TRUE;}BOOL PEthSocket::Close(){ SetFilter(FilterDirected, filterType); // Turn off promiscuous mode return PSocket::Close();}BOOL PEthSocket::EnumInterfaces(PINDEX idx, PString & name){#ifndef __BEOS__ PUDPSocket ifsock; ifreq ifreqs[20]; // Maximum of 20 interfaces ifconf ifc; ifc.ifc_len = sizeof(ifreqs); ifc.ifc_buf = (caddr_t)ifreqs; if (!ConvertOSError(ioctl(ifsock.GetHandle(), SIOCGIFCONF, &ifc))) return FALSE; int ifcount = ifc.ifc_len/sizeof(ifreq); int ifidx; for (ifidx = 0; ifidx < ifcount; ifidx++) { if (strchr(ifreqs[ifidx].ifr_name, ':') == NULL) { ifreq ifr; strcpy(ifr.ifr_name, ifreqs[ifidx].ifr_name); if (ioctl(ifsock.GetHandle(), SIOCGIFFLAGS, &ifr) == 0 && (ifr.ifr_flags & IFF_UP) != 0 && idx-- == 0) { name = ifreqs[ifidx].ifr_name; return TRUE; } } }#endif //!__BEOS__ return FALSE;}BOOL PEthSocket::GetAddress(Address & addr){ if (!IsOpen()) return FALSE; addr = macAddress; return TRUE;}BOOL PEthSocket::EnumIpAddress(PINDEX idx, PIPSocket::Address & addr, PIPSocket::Address & net_mask){ if (!IsOpen()) return FALSE;#ifndef __BEOS__ PUDPSocket ifsock; struct ifreq ifr; ifr.ifr_addr.sa_family = AF_INET; if (idx == 0) strcpy(ifr.ifr_name, channelName); else sprintf(ifr.ifr_name, "%s:%u", (const char *)channelName, (int)(idx-1)); if (!ConvertOSError(ioctl(os_handle, SIOCGIFADDR, &ifr))) return FALSE; sockaddr_in *sin = (struct sockaddr_in *)&ifr.ifr_addr; addr = sin->sin_addr; if (!ConvertOSError(ioctl(os_handle, SIOCGIFNETMASK, &ifr))) return FALSE; net_mask = sin->sin_addr; return TRUE;#else return FALSE;#endif //!__BEOS__}BOOL PEthSocket::GetFilter(unsigned & mask, WORD & type){ if (!IsOpen()) return FALSE;#ifndef __BEOS__ ifreq ifr; memset(&ifr, 0, sizeof(ifr)); strcpy(ifr.ifr_name, channelName); if (!ConvertOSError(ioctl(os_handle, SIOCGIFFLAGS, &ifr))) return FALSE; if ((ifr.ifr_flags&IFF_PROMISC) != 0) filterMask |= FilterPromiscuous; else filterMask &= ~FilterPromiscuous; mask = filterMask; type = filterType; return TRUE;#else return FALSE;#endif //!__BEOS__}BOOL PEthSocket::SetFilter(unsigned filter, WORD type){ if (!IsOpen()) return FALSE; if (filterType != type) { os_close(); filterType = type; if (!OpenSocket()) return FALSE; }#ifndef __BEOS__ ifreq ifr; memset(&ifr, 0, sizeof(ifr)); strcpy(ifr.ifr_name, channelName); if (!ConvertOSError(ioctl(os_handle, SIOCGIFFLAGS, &ifr))) return FALSE; if ((filter&FilterPromiscuous) != 0) ifr.ifr_flags |= IFF_PROMISC; else ifr.ifr_flags &= ~IFF_PROMISC; if (!ConvertOSError(ioctl(os_handle, SIOCSIFFLAGS, &ifr))) return FALSE; filterMask = filter; return TRUE;#else return FALSE;#endif //!__BEOS__}PEthSocket::MediumTypes PEthSocket::GetMedium(){ return medium;}BOOL PEthSocket::ResetAdaptor(){ // No implementation return TRUE;}BOOL PEthSocket::Read(void * buf, PINDEX len){ static const BYTE macHeader[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 8, 0 }; BYTE * bufptr = (BYTE *)buf; if (fakeMacHeader) { if (len <= sizeof(macHeader)) { memcpy(bufptr, macHeader, len); lastReadCount = len; return TRUE; } memcpy(bufptr, macHeader, sizeof(macHeader)); bufptr += sizeof(macHeader); len -= sizeof(macHeader); } for (;;) { sockaddr from; PINDEX fromlen = sizeof(from); if (!os_recvfrom(bufptr, len, 0, &from, &fromlen)) return FALSE; if (channelName != from.sa_data) continue; if (ipppInterface) { if (lastReadCount <= 10) return FALSE; if (memcmp(bufptr+6, "\xff\x03\x00\x21", 4) != 0) { memmove(bufptr+sizeof(macHeader), bufptr, lastReadCount); lastReadCount += sizeof(macHeader); } else { memmove(bufptr+sizeof(macHeader), bufptr+10, lastReadCount); lastReadCount += sizeof(macHeader)-10; } memcpy(bufptr, macHeader, sizeof(macHeader)); break; } if (fakeMacHeader) { lastReadCount += sizeof(macHeader); break; } if ((filterMask&FilterPromiscuous) != 0) break; if ((filterMask&FilterDirected) != 0 && macAddress == bufptr) break; static const Address broadcast; if ((filterMask&FilterBroadcast) != 0 && broadcast == bufptr) break; } return lastReadCount > 0;}BOOL PEthSocket::Write(const void * buf, PINDEX len){ sockaddr to; strcpy(to.sa_data, channelName); return os_sendto(buf, len, 0, &to, sizeof(to)) && lastWriteCount >= len;}///////////////////////////////////////////////////////////////////////////////BOOL PIPSocket::GetGatewayAddress(Address & addr){ RouteTable table; if (GetRouteTable(table)) { for (PINDEX i = 0; i < table.GetSize(); i++) { if (table[i].GetNetwork() == 0) { addr = table[i].GetDestination(); return TRUE; } } } return FALSE;}PString PIPSocket::GetGatewayInterface(){ RouteTable table; if (GetRouteTable(table)) { for (PINDEX i = 0; i < table.GetSize(); i++) { if (table[i].GetNetwork() == 0) return table[i].GetInterface(); } } return PString();}BOOL PIPSocket::GetRouteTable(RouteTable & table){#if defined(P_LINUX) || defined (P_AIX) PTextFile procfile; if (!procfile.Open("/proc/net/route", PFile::ReadOnly)) return FALSE; for (;;) { // Ignore heading line or remainder of route line procfile.ignore(1000, '\n'); if (procfile.eof()) return TRUE; char iface[20]; long net_addr, dest_addr, net_mask; int flags, refcnt, use, metric; procfile >> iface >> ::hex >> net_addr >> dest_addr >> flags >> ::dec >> refcnt >> use >> metric >> ::hex >> net_mask; if (procfile.bad()) return FALSE; RouteEntry * entry = new RouteEntry(net_addr); entry->net_mask = net_mask; entry->destination = dest_addr; entry->interfaceName = iface; entry->metric = metric; table.Append(entry); }#else#warning Platform requires implemetation of GetRouteTable() return FALSE;#endif}BOOL PIPSocket::GetInterfaceTable(InterfaceTable & list){ PUDPSocket sock;#ifndef __BEOS__ // get number of interfaces int ifNum;#ifdef SIOCGIFNUM PAssert(::ioctl(sock.GetHandle(), SIOCGIFNUM, &ifNum) >= 0, "could not do ioctl for ifNum");#else ifNum = 100;#endif PBYTEArray buffer; struct ifconf ifConf; ifConf.ifc_len = ifNum * sizeof(ifreq); ifConf.ifc_req = (struct ifreq *)buffer.GetPointer(ifConf.ifc_len); if (ioctl(sock.GetHandle(), SIOCGIFCONF, &ifConf) >= 0) {#ifndef SIOCGIFNUM ifNum = ifConf.ifc_len / sizeof(ifreq);#endif int num = 0; for (num = 0; num < ifNum; num++) { ifreq * ifName = ifConf.ifc_req + num; struct ifreq ifReq; strcpy(ifReq.ifr_name, ifName->ifr_name); if (ioctl(sock.GetHandle(), SIOCGIFFLAGS, &ifReq) >= 0) { int flags = ifReq.ifr_flags; if (flags & IFF_UP) { PString name(ifReq.ifr_name); PString macAddr; PIPSocket::Address addr;#ifdef SIO_Get_MAC_Address if (ioctl(sock.GetHandle(), SIO_Get_MAC_Address, &ifReq) >= 0) { BYTE * p = (BYTE *)ifReq.ifr_macaddr; PEthSocket::Address a(p); macAddr = (PString)a; }#endif if (ioctl(sock.GetHandle(), SIOCGIFADDR, &ifReq) >= 0) addr = PIPSocket::Address(((sockaddr_in *)&ifReq.ifr_addr)->sin_addr); list.Append(PNEW InterfaceEntry(name, addr, macAddr)); } } } }#endif //!__BEOS__ return TRUE;}#include "../common/pethsock.cxx"///////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -