📄 socket.cxx
字号:
if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) { printf("ERR actual retrieval of routing table"); free(buf); return FALSE; } lim = buf + needed; next = buf; if (next < lim) { ifm = (struct if_msghdr *)next; if (ifm->ifm_type == RTM_IFINFO) { sdl = (struct sockaddr_dl *)(ifm + 1); } else { printf("out of sync parsing NET_RT_IFLIST\n"); return FALSE; } next += ifm->ifm_msglen; strncpy(name, sdl->sdl_data, sdl->sdl_nlen); name[sdl->sdl_nlen] = '\0'; free(buf); return TRUE; } else { free(buf); return FALSE; }}#elif defined(P_SOLARIS)/* jpd@louisiana.edu - influenced by Merit.edu's Gated 3.6 routine: krt_rtread_sunos5.c */#include <sys/stream.h>#include <stropts.h>#include <sys/tihdr.h>#include <sys/tiuser.h>#include <inet/common.h>#include <inet/mib2.h>#include <inet/ip.h>#ifndef T_CURRENT#define T_CURRENT MI_T_CURRENT#endifBOOL PIPSocket::GetRouteTable(RouteTable & table){#define task_pagesize 512 char buf[task_pagesize]; /* = task_block_malloc(task_pagesize);*/ int flags; int j = 0; int sd, i, rc; struct strbuf strbuf; struct T_optmgmt_req *tor = (struct T_optmgmt_req *) buf; struct T_optmgmt_ack *toa = (struct T_optmgmt_ack *) buf; struct T_error_ack *tea = (struct T_error_ack *) buf; struct opthdr *req; sd = open("/dev/ip", O_RDWR); if (sd < 0) {#ifdef SOL_COMPLAIN perror("can't open mib stream");#endif goto Return; } strbuf.buf = buf; tor->PRIM_type = T_OPTMGMT_REQ; tor->OPT_offset = sizeof(struct T_optmgmt_req); tor->OPT_length = sizeof(struct opthdr); tor->MGMT_flags = T_CURRENT; req = (struct opthdr *) (tor + 1); req->level = MIB2_IP; /* any MIB2_xxx value ok here */ req->name = 0; req->len = 0; strbuf.len = tor->OPT_length + tor->OPT_offset; flags = 0; rc = putmsg(sd, &strbuf, (struct strbuf *) 0, flags); if (rc == -1) {#ifdef SOL_COMPLAIN perror("putmsg(ctl)");#endif goto Return; } /* * each reply consists of a ctl part for one fixed structure * or table, as defined in mib2.h. The format is a T_OPTMGMT_ACK, * containing an opthdr structure. level/name identify the entry, * len is the size of the data part of the message. */ req = (struct opthdr *) (toa + 1); strbuf.maxlen = task_pagesize; while (++j) { flags = 0; rc = getmsg(sd, &strbuf, (struct strbuf *) 0, &flags); if (rc == -1) {#ifdef SOL_COMPLAIN perror("getmsg(ctl)");#endif goto Return; } if (rc == 0 && strbuf.len >= (int)sizeof(struct T_optmgmt_ack) && toa->PRIM_type == T_OPTMGMT_ACK && toa->MGMT_flags == T_SUCCESS && req->len == 0) { errno = 0; /* just to be darned sure it's 0 */ goto Return; /* this is EOD msg */ } if (strbuf.len >= (int)sizeof(struct T_error_ack) && tea->PRIM_type == T_ERROR_ACK) { errno = (tea->TLI_error == TSYSERR) ? tea->UNIX_error : EPROTO;#ifdef SOL_COMPLAIN perror("T_ERROR_ACK in mibget");#endif goto Return; } if (rc != MOREDATA || strbuf.len < (int)sizeof(struct T_optmgmt_ack) || toa->PRIM_type != T_OPTMGMT_ACK || toa->MGMT_flags != T_SUCCESS) { errno = ENOMSG; goto Return; } if (req->level != MIB2_IP#if P_SOLARIS > 7 || req->name != MIB2_IP_ROUTE#endif ) { /* == 21 */ /* If this is not the routing table, skip it */ /* Note we don't bother with IPv6 (MIB2_IP6_ROUTE) ... */ strbuf.maxlen = task_pagesize; do { rc = getmsg(sd, (struct strbuf *) 0, &strbuf, &flags); } while (rc == MOREDATA) ; continue; } strbuf.maxlen = (task_pagesize / sizeof (mib2_ipRouteEntry_t)) * sizeof (mib2_ipRouteEntry_t); strbuf.len = 0; flags = 0; do { rc = getmsg(sd, (struct strbuf * ) 0, &strbuf, &flags); switch (rc) { case -1:#ifdef SOL_COMPLAIN perror("mibget getmsg(data) failed.");#endif goto Return; default:#ifdef SOL_COMPLAIN fprintf(stderr,"mibget getmsg(data) returned %d, strbuf.maxlen = %d, strbuf.len = %d", rc, strbuf.maxlen, strbuf.len);#endif goto Return; case MOREDATA: case 0: { mib2_ipRouteEntry_t *rp = (mib2_ipRouteEntry_t *) strbuf.buf; mib2_ipRouteEntry_t *lp = (mib2_ipRouteEntry_t *) (strbuf.buf + strbuf.len); do { char name[256];#ifdef SOL_DEBUG_RT printf("%s -> %s mask %s metric %d %d %d %d %d ifc %.*s type %d/%x/%x\n", inet_ntoa(rp->ipRouteDest), inet_ntoa(rp->ipRouteNextHop), inet_ntoa(rp->ipRouteMask), rp->ipRouteMetric1, rp->ipRouteMetric2, rp->ipRouteMetric3, rp->ipRouteMetric4, rp->ipRouteMetric5, rp->ipRouteIfIndex.o_length, rp->ipRouteIfIndex.o_bytes, rp->ipRouteType, rp->ipRouteInfo.re_ire_type, rp->ipRouteInfo.re_flags );#endif if (rp->ipRouteInfo.re_ire_type & (IRE_BROADCAST|IRE_CACHE|IRE_LOCAL)) continue; RouteEntry * entry = new RouteEntry(rp->ipRouteDest); entry->net_mask = rp->ipRouteMask; entry->destination = rp->ipRouteNextHop; unsigned len = rp->ipRouteIfIndex.o_length; if (len >= sizeof(name)) len = sizeof(name)-1; strncpy(name, rp->ipRouteIfIndex.o_bytes, len); name[len] = '\0'; entry->interfaceName = name; entry->metric = rp->ipRouteMetric1; table.Append(entry); } while (++rp < lp) ; } break; } } while (rc == MOREDATA) ; } Return: i = errno; (void) close(sd); errno = i; /*task_block_reclaim(task_pagesize, buf);*/ if (errno) return (FALSE); else return (TRUE);}#elif defined(P_VXWORKS)BOOL PIPSocket::GetRouteTable(RouteTable & table){ PAssertAlways("PIPSocket::GetRouteTable()"); for(;;){ char iface[20]; unsigned long net_addr, dest_addr, net_mask; int metric; RouteEntry * entry = new RouteEntry(net_addr); entry->net_mask = net_mask; entry->destination = dest_addr; entry->interfaceName = iface; entry->metric = metric; table.Append(entry); return TRUE; }}#else // unsupported platform#if 0 BOOL PIPSocket::GetRouteTable(RouteTable & table){ // Most of this code came from the source code for the "route" command // so it should work on other platforms too. // However, it is not complete (the "address-for-interface" function doesn't exist) and not tested! route_table_req_t reqtable; route_req_t *rrtp; int i,ret; ret = get_route_table(&reqtable); if (ret < 0) { return FALSE; } for (i=reqtable.cnt, rrtp = reqtable.rrtp;i>0;i--, rrtp++) { //the datalink doesn't save addresses/masks for host and default //routes, so the route_req_t may not be filled out completely if (rrtp->flags & RTF_DEFAULT) { //the IP default route is 0/0 ((struct sockaddr_in *)&rrtp->dst)->sin_addr.s_addr = 0; ((struct sockaddr_in *)&rrtp->mask)->sin_addr.s_addr = 0; } else if (rrtp->flags & RTF_HOST) { //host routes are addr/32 ((struct sockaddr_in *)&rrtp->mask)->sin_addr.s_addr = 0xffffffff; } RouteEntry * entry = new RouteEntry(/* address_for_interface(rrtp->iface) */); entry->net_mask = rrtp->mask; entry->destination = rrtp->dst; entry->interfaceName = rrtp->iface; entry->metric = rrtp->refcnt; table.Append(entry); } free(reqtable.rrtp); return TRUE; #endif // 0BOOL PIPSocket::GetRouteTable(RouteTable & table){#warning Platform requires implemetation of GetRouteTable() return FALSE;}#endif// fe800000000000000202e3fffe1ee330 02 40 20 80 eth0// 00000000000000000000000000000001 01 80 10 80 loBOOL PIPSocket::GetInterfaceTable(InterfaceTable & list){#ifdef P_HAS_IPV6 // build a table of IPV6 interface addresses typedef std::map<PString, PString> IP6ListType; IP6ListType ip6Ifaces; { FILE * file; int dummy; int addr[16]; char ifaceName[9]; if ((file = fopen("/proc/net/if_inet6", "r")) != NULL) { while (fscanf(file, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x %02x %02x %02x %02x %8s\n", &addr[0], &addr[1], &addr[2], &addr[3], &addr[4], &addr[5], &addr[6], &addr[7], &addr[8], &addr[9], &addr[10], &addr[11], &addr[12], &addr[13], &addr[14], &addr[15], &dummy, &dummy, &dummy, &dummy, ifaceName) != EOF) { PString addrStr( psprintf("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7], addr[8], addr[9], addr[10], addr[11], addr[12], addr[13], addr[14], addr[15] ) ); PString iface(ifaceName); ip6Ifaces.insert(IP6ListType::value_type(ifaceName, addrStr)); } fclose(file); } }#endif PUDPSocket sock; PBYTEArray buffer; struct ifconf ifConf; #ifdef SIOCGIFNUM int ifNum; PAssert(::ioctl(sock.GetHandle(), SIOCGIFNUM, &ifNum) >= 0, "could not do ioctl for ifNum"); ifConf.ifc_len = ifNum * sizeof(ifreq);#else ifConf.ifc_len = 100 * sizeof(ifreq); // That's a LOT of interfaces!#endif ifConf.ifc_req = (struct ifreq *)buffer.GetPointer(ifConf.ifc_len); if (ioctl(sock.GetHandle(), SIOCGIFCONF, &ifConf) >= 0) { void * ifEndList = (char *)ifConf.ifc_req + ifConf.ifc_len; ifreq * ifName = ifConf.ifc_req; while (ifName < ifEndList) { 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;#if defined(SIO_Get_MAC_Address) if (ioctl(sock.GetHandle(), SIO_Get_MAC_Address, &ifReq) >= 0) { PEthSocket::Address a((BYTE *)ifReq.ifr_macaddr); macAddr = (PString)a; }#endif if (ioctl(sock.GetHandle(), SIOCGIFADDR, &ifReq) >= 0) { PIPSocket::Address addr = ((sockaddr_in *)&ifReq.ifr_addr)->sin_addr; if (ioctl(sock.GetHandle(), SIOCGIFNETMASK, &ifReq) >= 0) { PIPSocket::Address mask = #ifndef __BEOS__ ((sockaddr_in *)&ifReq.ifr_netmask)->sin_addr;#else ((sockaddr_in *)&ifReq.ifr_mask)->sin_addr;#endif // !__BEOS__ PINDEX i; for (i = 0; i < list.GetSize(); i++) {#ifdef P_TORNADO if (list[i].GetName() == name && list[i].GetAddress() == addr) if(list[i].GetNetMask() == mask)#else if (list[i].GetName() == name && list[i].GetAddress() == addr && list[i].GetNetMask() == mask)#endif break; }#ifdef P_HAS_IPV6 PString ip6Addr; IP6ListType::const_iterator r = ip6Ifaces.find(name); if (r != ip6Ifaces.end()) ip6Addr = r->second;#endif if (i >= list.GetSize()) list.Append(PNEW InterfaceEntry(name, addr, mask, macAddr#ifdef P_HAS_IPV6 , ip6Addr#endif )); } } } }#if defined(P_FREEBSD) || defined(P_OPENBSD) || defined(P_NETBSD) || defined(P_MACOSX) || defined(P_VXWORKS) || defined(P_RTEMS) || defined(P_QNX)// Define _SIZEOF_IFREQ for platforms (eg OpenBSD) which do not have it.#ifndef _SIZEOF_ADDR_IFREQ#define _SIZEOF_ADDR_IFREQ(ifr) \ ((ifr).ifr_addr.sa_len > sizeof(struct sockaddr) ? \ (sizeof(struct ifreq) - sizeof(struct sockaddr) + \ (ifr).ifr_addr.sa_len) : sizeof(struct ifreq))#endif // move the ifName pointer along to the next ifreq entry ifName = (struct ifreq *)((char *)ifName + _SIZEOF_ADDR_IFREQ(*ifName));#else ifName++;#endif } } return TRUE;}#ifdef P_VXWORKSint h_errno;struct hostent * Vx_gethostbyname(char *name, struct hostent *hp){ u_long addr; static char staticgethostname[100]; hp->h_aliases = NULL; hp->h_addr_list[1] = NULL; if ((int)(addr = inet_addr(name)) != ERROR) { memcpy(staticgethostname, &addr, sizeof(addr)); hp->h_addr_list[0] = staticgethostname; h_errno = SUCCESS; return hp; } memcpy(staticgethostname, &addr, sizeof (addr)); hp->h_addr_list[0] = staticgethostname; h_errno = SUCCESS; return hp;}struct hostent * Vx_gethostbyaddr(char *name, struct hostent *hp){ u_long addr; static char staticgethostaddr[100]; hp->h_aliases = NULL; hp->h_addr_list = NULL; if ((int)(addr = inet_addr(name)) != ERROR) { char ipStorage[INET_ADDR_LEN]; inet_ntoa_b(*(struct in_addr*)&addr, ipStorage); sprintf(staticgethostaddr,"%s",ipStorage); hp->h_name = staticgethostaddr; h_errno = SUCCESS; } else { printf ("_gethostbyaddr: not able to get %s\n",name); h_errno = NOTFOUND; } return hp;}#endif // P_VXWORKS#include "../common/pethsock.cxx"///////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -