📄 socket.cxx
字号:
} else if (strncmp("ippp", interfaceName, 4) == 0) { medium = MediumWan; ipppInterface = TRUE; }#ifdef P_RTEMS else if (strncmp(RTEMS_BSP_NETWORK_DRIVER_NAME, interfaceName, 3) == 0) medium = Medium802_3;#endif else return SetErrorValues(NotFound, ENOENT);#if defined(SIO_Get_MAC_Address) 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){ PUDPSocket ifsock; ifreq ifreqs[20]; // Maximum of 20 interfaces struct 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; } } } 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; 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;}BOOL PEthSocket::GetFilter(unsigned & mask, WORD & type){ if (!IsOpen()) return FALSE; 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;}BOOL PEthSocket::SetFilter(unsigned filter, WORD type){ if (!IsOpen()) return FALSE; if (filterType != type) { os_close(); filterType = type; if (!OpenSocket()) return FALSE; } 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;}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 <= (PINDEX)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((char *)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();}#if defined(P_LINUX) || defined (P_AIX)BOOL PIPSocket::GetRouteTable(RouteTable & table){ 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]; unsigned 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); }}#elif defined(P_FREEBSD) || defined(P_OPENBSD) || defined(P_NETBSD) || defined(P_MACOSX) || defined(P_QNX) BOOL process_rtentry(struct rt_msghdr *rtm, char *ptr, unsigned long *p_net_addr, unsigned long *p_net_mask, unsigned long *p_dest_addr, int *p_metric);BOOL get_ifname(int index, char *name);BOOL PIPSocket::GetRouteTable(RouteTable & table){ int mib[6]; size_t space_needed; char *limit, *buf, *ptr; struct rt_msghdr *rtm; InterfaceTable if_table; // Read the Routing Table mib[0] = CTL_NET; mib[1] = PF_ROUTE; mib[2] = 0; mib[3] = 0; mib[4] = NET_RT_DUMP; mib[5] = 0; if (sysctl(mib, 6, NULL, &space_needed, NULL, 0) < 0) { printf("sysctl: net.route.0.0.dump estimate"); return FALSE; } if ((buf = (char *)malloc(space_needed)) == NULL) { printf("malloc(%lu)", (unsigned long)space_needed); return FALSE; } // read the routing table data if (sysctl(mib, 6, buf, &space_needed, NULL, 0) < 0) { printf("sysctl: net.route.0.0.dump"); free(buf); return FALSE; } // Read the interface table if (!GetInterfaceTable(if_table)) { printf("Interface Table Invalid\n"); return FALSE; } // Process the Routing Table data limit = buf + space_needed; for (ptr = buf; ptr < limit; ptr += rtm->rtm_msglen) { unsigned long net_addr, dest_addr, net_mask; int metric; char name[16]; rtm = (struct rt_msghdr *)ptr; if ( process_rtentry(rtm,ptr, &net_addr, &net_mask, &dest_addr, &metric) ){ RouteEntry * entry = new RouteEntry(net_addr); entry->net_mask = net_mask; entry->destination = dest_addr; if ( get_ifname(rtm->rtm_index,name) ) entry->interfaceName = name; entry->metric = metric; table.Append(entry); } // end if } // end for loop free(buf); return TRUE;}BOOL process_rtentry(struct rt_msghdr *rtm, char *ptr, unsigned long *p_net_addr, unsigned long *p_net_mask, unsigned long *p_dest_addr, int *p_metric) { struct sockaddr_in *sa_in; unsigned long net_addr, dest_addr, net_mask; int metric; sa_in = (struct sockaddr_in *)(rtm + 1); // Check for zero length entry if (rtm->rtm_msglen == 0) { printf("zero length message\n"); return FALSE; } if ((~rtm->rtm_flags&RTF_LLINFO)#if defined(P_NETBSD) || defined(P_QNX) && (~rtm->rtm_flags&RTF_CLONED) // Net BSD has flag one way#elif !defined(P_OPENBSD) && (~rtm->rtm_flags&RTF_WASCLONED) // Free BSD/MAC has it another#else // Open BSD does not have it at all!#endif ) { //strcpy(name, if_table[rtm->rtm_index].GetName); net_addr=dest_addr=net_mask=metric=0; // NET_ADDR if(rtm->rtm_addrs&RTA_DST ) { if(sa_in->sin_family == AF_INET) net_addr = sa_in->sin_addr.s_addr; sa_in = (struct sockaddr_in *)((char *)sa_in + ROUNDUP(sa_in->sin_len)); } // DEST_ADDR if(rtm->rtm_addrs&RTA_GATEWAY) { if(sa_in->sin_family == AF_INET) dest_addr = sa_in->sin_addr.s_addr; sa_in = (struct sockaddr_in *)((char *)sa_in + ROUNDUP(sa_in->sin_len)); } // NETMASK if(rtm->rtm_addrs&RTA_NETMASK && sa_in->sin_len) net_mask = sa_in->sin_addr.s_addr; if( rtm->rtm_flags&RTF_HOST) net_mask = 0xffffffff; *p_metric = metric; *p_net_addr = net_addr; *p_dest_addr = dest_addr; *p_net_mask = net_mask; return TRUE; } else { return FALSE; }}BOOL get_ifname(int index, char *name) { int mib[6]; size_t needed; char *lim, *buf, *next; struct if_msghdr *ifm; struct sockaddr_dl *sdl; mib[0] = CTL_NET; mib[1] = PF_ROUTE; mib[2] = 0; mib[3] = AF_INET; mib[4] = NET_RT_IFLIST; mib[5] = index; if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) { printf("ERR route-sysctl-estimate"); return FALSE; } if ((buf = (char *)malloc(needed)) == NULL) { printf("ERR malloc"); return FALSE; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -