sys-rtems.c

来自「RTEMS (Real-Time Executive for Multiproc」· C语言 代码 · 共 1,339 行 · 第 1/3 页

C
1,339
字号
	if (errno != EADDRNOTAVAIL)	    warn("Couldn't remove interface address: %m");    }    if (ioctl(sockfd, SIOCAIFADDR, (caddr_t) &ifra) < 0) {	if (errno != EEXIST) {	    error("Couldn't set interface address: %m");	    return 0;	}	warn("Couldn't set interface address: Address %I already exists", o);    }    ifaddrs[0] = o;    ifaddrs[1] = h;    return 1;}/* * cifaddr - Clear the interface IP addresses, and delete routes * through the interface if possible. */intcifaddr(u, o, h)    int u;    u_int32_t o, h;{    struct ifaliasreq ifra;    ifaddrs[0] = 0;    strlcpy(ifra.ifra_name, ifname, sizeof(ifra.ifra_name));    SET_SA_FAMILY(ifra.ifra_addr, AF_INET);    ((struct sockaddr_in *) &ifra.ifra_addr)->sin_addr.s_addr = o;    SET_SA_FAMILY(ifra.ifra_broadaddr, AF_INET);    ((struct sockaddr_in *) &ifra.ifra_broadaddr)->sin_addr.s_addr = h;    BZERO(&ifra.ifra_mask, sizeof(ifra.ifra_mask));    if (ioctl(sockfd, SIOCDIFADDR, (caddr_t) &ifra) < 0) {	if (errno != EADDRNOTAVAIL)	    warn("Couldn't delete interface address: %m");	return 0;    }    return 1;}/* * sifdefaultroute - assign a default route through the address given. */intsifdefaultroute(u, l, g)    int u;    u_int32_t l, g;{    return dodefaultroute(g, 's');}/* * cifdefaultroute - delete a default route through the address given. */intcifdefaultroute(u, l, g)    int u;    u_int32_t l, g;{    return dodefaultroute(g, 'c');}/* * dodefaultroute - talk to a routing socket to add/delete a default route. */static intdodefaultroute(g, cmd)    u_int32_t g;    int cmd;{/*    int    status;  */    struct sockaddr_in address;    struct sockaddr_in netmask;    struct sockaddr_in gateway;    memset((void *) &address, 0, sizeof(address));    address.sin_len = sizeof address;    address.sin_family = AF_INET;    address.sin_addr.s_addr = INADDR_ANY;    memset((void *) &netmask, 0, sizeof(netmask));    netmask.sin_len = sizeof netmask;    netmask.sin_addr.s_addr = INADDR_ANY;      netmask.sin_family = AF_INET;    if (cmd=='s') {	      memset((void *) &gateway, 0, sizeof(gateway));      gateway.sin_len = sizeof gateway;      gateway.sin_family = AF_INET;      gateway.sin_addr.s_addr = g;      rtems_bsdnet_rtrequest(RTM_ADD,                             (struct sockaddr *)&address,                             (struct sockaddr *)&gateway,                             (struct sockaddr *)&netmask,                             (RTF_UP|RTF_GATEWAY|RTF_STATIC), NULL);    }    else {      memset((void *) &gateway, 0, sizeof(gateway));      gateway.sin_len = sizeof gateway;      gateway.sin_family = AF_INET;      gateway.sin_addr.s_addr =  INADDR_ANY;      rtems_bsdnet_rtrequest(RTM_DELETE,                             (struct sockaddr *)&address,                             (struct sockaddr *)&gateway,                             (struct sockaddr *)&netmask,                             (RTF_UP|RTF_STATIC), NULL);    }    default_route_gateway = (cmd == 's')? g: 0;    return 1;}#if RTM_VERSION >= 3/* * sifproxyarp - Make a proxy ARP entry for the peer. */static struct {    struct rt_msghdr		hdr;    struct sockaddr_inarp	dst;    struct sockaddr_dl		hwa;    char			extra[128];} arpmsg;static int arpmsg_valid;intsifproxyarp(unit, hisaddr)    int unit;    u_int32_t hisaddr;{    int routes;    /*     * Get the hardware address of an interface on the same subnet     * as our local address.     */    memset(&arpmsg, 0, sizeof(arpmsg));    if (!get_ether_addr(hisaddr, &arpmsg.hwa)) {	error("Cannot determine ethernet address for proxy ARP");	return 0;    }    if ((routes = socket(PF_ROUTE, SOCK_RAW, AF_INET)) < 0) {	error("Couldn't add proxy arp entry: socket: %m");	return 0;    }    arpmsg.hdr.rtm_type = RTM_ADD;    arpmsg.hdr.rtm_flags = RTF_ANNOUNCE | RTF_HOST | RTF_STATIC;    arpmsg.hdr.rtm_version = RTM_VERSION;    arpmsg.hdr.rtm_seq = ++rtm_seq;    arpmsg.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY;    arpmsg.hdr.rtm_inits = RTV_EXPIRE;    arpmsg.dst.sin_len = sizeof(struct sockaddr_inarp);    arpmsg.dst.sin_family = AF_INET;    arpmsg.dst.sin_addr.s_addr = hisaddr;    arpmsg.dst.sin_other = SIN_PROXY;    arpmsg.hdr.rtm_msglen = (char *) &arpmsg.hwa - (char *) &arpmsg	+ arpmsg.hwa.sdl_len;    if (write(routes, &arpmsg, arpmsg.hdr.rtm_msglen) < 0) {	error("Couldn't add proxy arp entry: %m");	close(routes);	return 0;    }    close(routes);    arpmsg_valid = 1;    proxy_arp_addr = hisaddr;    return 1;}/* * cifproxyarp - Delete the proxy ARP entry for the peer. */intcifproxyarp(unit, hisaddr)    int unit;    u_int32_t hisaddr;{    int routes;    if (!arpmsg_valid)	return 0;    arpmsg_valid = 0;    arpmsg.hdr.rtm_type = RTM_DELETE;    arpmsg.hdr.rtm_seq = ++rtm_seq;    if ((routes = socket(PF_ROUTE, SOCK_RAW, AF_INET)) < 0) {	error("Couldn't delete proxy arp entry: socket: %m");	return 0;    }    if (write(routes, &arpmsg, arpmsg.hdr.rtm_msglen) < 0) {	error("Couldn't delete proxy arp entry: %m");	close(routes);	return 0;    }    close(routes);    proxy_arp_addr = 0;    return 1;}#else	/* RTM_VERSION *//* * sifproxyarp - Make a proxy ARP entry for the peer. */intsifproxyarp(unit, hisaddr)    int unit;    u_int32_t hisaddr;{    struct arpreq arpreq;    struct {	struct sockaddr_dl	sdl;	char			space[128];    } dls;    BZERO(&arpreq, sizeof(arpreq));    /*     * Get the hardware address of an interface on the same subnet     * as our local address.     */    if (!get_ether_addr(hisaddr, &dls.sdl)) {	error("Cannot determine ethernet address for proxy ARP");	return 0;    }    arpreq.arp_ha.sa_len = sizeof(struct sockaddr);    arpreq.arp_ha.sa_family = AF_UNSPEC;    BCOPY(LLADDR(&dls.sdl), arpreq.arp_ha.sa_data, dls.sdl.sdl_alen);    SET_SA_FAMILY(arpreq.arp_pa, AF_INET);    ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr;    arpreq.arp_flags = ATF_PERM | ATF_PUBL;    if (ioctl(sockfd, SIOCSARP, (caddr_t)&arpreq) < 0) {	error("Couldn't add proxy arp entry: %m");	return 0;    }    proxy_arp_addr = hisaddr;    return 1;}/* * cifproxyarp - Delete the proxy ARP entry for the peer. */intcifproxyarp(unit, hisaddr)    int unit;    u_int32_t hisaddr;{    struct arpreq arpreq;    BZERO(&arpreq, sizeof(arpreq));    SET_SA_FAMILY(arpreq.arp_pa, AF_INET);    ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr;    if (ioctl(sockfd, SIOCDARP, (caddr_t)&arpreq) < 0) {	warn("Couldn't delete proxy arp entry: %m");	return 0;    }    proxy_arp_addr = 0;    return 1;}#endif	/* RTM_VERSION *//* * get_ether_addr - get the hardware address of an interface on the * the same subnet as ipaddr. */#define MAX_IFS		32static intget_ether_addr(ipaddr, hwaddr)    u_int32_t ipaddr;    struct sockaddr_dl *hwaddr;{    struct ifreq *ifr, *ifend, *ifp;    u_int32_t ina, mask;    struct sockaddr_dl *dla;    struct ifreq ifreq;    struct ifconf ifc;    struct ifreq ifs[MAX_IFS];    ifc.ifc_len = sizeof(ifs);    ifc.ifc_req = ifs;    if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) {	error("ioctl(SIOCGIFCONF): %m");	return 0;    }    /*     * Scan through looking for an interface with an Internet     * address on the same subnet as `ipaddr'.     */    ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);    for (ifr = ifc.ifc_req; ifr < ifend; ifr = (struct ifreq *)	 	((char *)&ifr->ifr_addr + ifr->ifr_addr.sa_len)) {	if (ifr->ifr_addr.sa_family == AF_INET) {	    ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr;	    strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));	    /*	     * Check that the interface is up, and not point-to-point	     * or loopback.	     */	    if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0)		continue;	    if ((ifreq.ifr_flags &		 (IFF_UP|IFF_BROADCAST|IFF_POINTOPOINT|IFF_LOOPBACK|IFF_NOARP))		 != (IFF_UP|IFF_BROADCAST))		continue;	    /*	     * Get its netmask and check that it's on the right subnet.	     */	    if (ioctl(sockfd, SIOCGIFNETMASK, &ifreq) < 0)		continue;	    mask = ((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr.s_addr;	    if ((ipaddr & mask) != (ina & mask))		continue;	    break;	}    }    if (ifr >= ifend)	return 0;    info("found interface %s for proxy arp", ifr->ifr_name);    /*     * Now scan through again looking for a link-level address     * for this interface.     */    ifp = ifr;    for (ifr = ifc.ifc_req; ifr < ifend; ) {	if (strcmp(ifp->ifr_name, ifr->ifr_name) == 0	    && ifr->ifr_addr.sa_family == AF_LINK) {	    /*	     * Found the link-level address - copy it out	     */	    dla = (struct sockaddr_dl *) &ifr->ifr_addr;	    BCOPY(dla, hwaddr, dla->sdl_len);	    return 1;	}	ifr = (struct ifreq *) ((char *)&ifr->ifr_addr + ifr->ifr_addr.sa_len);    }    return 0;}/* * Return user specified netmask, modified by any mask we might determine * for address `addr' (in network byte order). * Here we scan through the system's list of interfaces, looking for * any non-point-to-point interfaces which might appear to be on the same * network as `addr'.  If we find any, we OR in their netmask to the * user-specified netmask. */u_int32_tGetMask(addr)    u_int32_t addr;{    u_int32_t mask, nmask, ina;    struct ifreq *ifr, *ifend, ifreq;    struct ifconf ifc;    struct ifreq ifs[MAX_IFS];    addr = ntohl(addr);    if (IN_CLASSA(addr))	/* determine network mask for address class */	nmask = IN_CLASSA_NET;    else if (IN_CLASSB(addr))	nmask = IN_CLASSB_NET;    else	nmask = IN_CLASSC_NET;    /* class D nets are disallowed by bad_ip_adrs */    mask = netmask | htonl(nmask);    /*     * Scan through the system's network interfaces.     */    ifc.ifc_len = sizeof(ifs);    ifc.ifc_req = ifs;    if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) {	warn("ioctl(SIOCGIFCONF): %m");	return mask;    }    ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);    for (ifr = ifc.ifc_req; ifr < ifend; ifr = (struct ifreq *)	 	((char *)&ifr->ifr_addr + ifr->ifr_addr.sa_len)) {	/*	 * Check the interface's internet address.	 */	if (ifr->ifr_addr.sa_family != AF_INET)	    continue;	ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr;	if ((ntohl(ina) & nmask) != (addr & nmask))	    continue;	/*	 * Check that the interface is up, and not point-to-point or loopback.	 */	strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));	if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0)	    continue;	if ((ifreq.ifr_flags & (IFF_UP|IFF_POINTOPOINT|IFF_LOOPBACK))	    != IFF_UP)	    continue;	/*	 * Get its netmask and OR it into our mask.	 */	if (ioctl(sockfd, SIOCGIFNETMASK, &ifreq) < 0)	    continue;	mask |= ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr.s_addr;    }    return mask;}/* * have_route_to - determine if the system has any route to * a given IP address. * For demand mode to work properly, we have to ignore routes * through our own interface. */int have_route_to(u_int32_t addr){    return -1;}/* * Use the hostid as part of the random number seed. */intget_host_seed(){    return 17;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?