📄 socket.cxx
字号:
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
#endif
BOOL 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 // 0
BOOL PIPSocket::GetRouteTable(RouteTable & table)
{
#warning Platform requires implemetation of GetRouteTable()
return FALSE;
}
#endif
// fe800000000000000202e3fffe1ee330 02 40 20 80 eth0
// 00000000000000000000000000000001 01 80 10 80 lo
BOOL PIPSocket::GetInterfaceTable(InterfaceTable & list)
{
#if 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[255];
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 %x %x %x %x %255s\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;
// HERE
#if defined(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;
memcpy(&ifReq, ifName, sizeof(ifreq));
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)
memcpy(&ifReq, ifName, sizeof(ifreq));
if (ioctl(sock.GetHandle(), SIO_Get_MAC_Address, &ifReq) >= 0) {
PEthSocket::Address a((BYTE *)ifReq.ifr_macaddr);
macAddr = (PString)a;
}
#endif
memcpy(&ifReq, ifName, sizeof(ifreq));
if (ioctl(sock.GetHandle(), SIOCGIFADDR, &ifReq) >= 0) {
sockaddr_in * sin = (sockaddr_in *)&ifReq.ifr_addr;
PIPSocket::Address addr = sin->sin_addr;
memcpy(&ifReq, ifName, sizeof(ifreq));
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;
}
#if 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
#if 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_VXWORKS
int 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"
//////////////////////////////////////////////////////////////////////////////
// PUDPSocket
void PUDPSocket::EnableGQoS()
{
}
BOOL PUDPSocket::SupportQoS(const PIPSocket::Address & )
{
return FALSE;
}
///////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -