/* * sifaddr - Config the interface IP addresses and netmask. */ int sifaddr( int u, uint32_t o, uint32_t h, uint32_t m ) { struct ifaliasreq ifra; struct ifreq ifr; 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; if (m != 0) { SET_SA_FAMILY(ifra.ifra_mask, AF_INET); ((struct sockaddr_in *) &ifra.ifra_mask)->sin_addr.s_addr = m; } else BZERO(&ifra.ifra_mask, sizeof(ifra.ifra_mask)); BZERO(&ifr, sizeof(ifr)); strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); if (ioctl(sockfd, SIOCDIFADDR, (caddr_t) &ifr) < 0) { 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; }
int cifaddr (int unit, int our_adr, int his_adr) { struct rtentry rt; /* * Delete the route through the device */ memset (&rt, '\0', sizeof (rt)); SET_SA_FAMILY (rt.rt_dst, AF_INET); SET_SA_FAMILY (rt.rt_gateway, AF_INET); rt.rt_dev = ifname; /* MJC */ ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = 0; ((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr = his_adr; rt.rt_flags = RTF_UP | RTF_HOST; if (ioctl(sockfd, SIOCDELRT, &rt) < 0 && errno != ESRCH) { if (still_ppp()) { syslog (LOG_ERR, "ioctl(SIOCDELRT) device route: %m"); return (0); } } return 1; }
int sifdefaultroute (int unit, int gateway) { struct rtentry rt; if (has_default_route == 0) { if (netmask) { /*printf("Adding route dst='%s'\n", inet_ntoa(gateway & netmask)); printf("Adding route genmask='%s'\n", inet_ntoa(netmask)); printf("Adding route gateway='%s'\n", inet_ntoa(gateway));*/ memset (&rt, '\0', sizeof (rt)); SET_SA_FAMILY (rt.rt_dst, AF_INET); SET_SA_FAMILY (rt.rt_genmask, AF_INET); SET_SA_FAMILY (rt.rt_gateway, AF_INET); ((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr = gateway & netmask; ((struct sockaddr_in *) &rt.rt_genmask)->sin_addr.s_addr = netmask; ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = gateway; rt.rt_flags = RTF_UP | RTF_GATEWAY; if (ioctl(sockfd, SIOCADDRT, &rt) < 0) { fprintf(stderr, "route failed: %d\n", errno); syslog (LOG_ERR, "default route ioctl(SIOCADDRT): %m"); return 0; } } else { if (defaultroute_exists()) { return 0; } memset (&rt, '\0', sizeof (rt)); SET_SA_FAMILY (rt.rt_dst, AF_INET); SET_SA_FAMILY (rt.rt_gateway, AF_INET); ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = gateway; rt.rt_flags = RTF_UP | RTF_GATEWAY; if (ioctl(sockfd, SIOCADDRT, &rt) < 0) { syslog (LOG_ERR, "default route ioctl(SIOCADDRT): %m"); return 0; } } } has_default_route = 1; return 1; }
/* * arp_SetProxy - Make a proxy ARP entry for the peer. */ int arp_SetProxy(struct bundle *bundle, struct in_addr addr, int s) { struct arpreq arpreq; struct { struct sockaddr_dl sdl; char space[128]; } dls; memset(&arpreq, '\0', sizeof arpreq); /* * Get the hardware address of an interface on the same subnet as our local * address. */ if (!arp_EtherAddr(addr, &dls.sdl, 1)) { log_Printf(LOG_PHASE_BIT, "Cannot determine ethernet address for " "proxy ARP\n"); return 0; } arpreq.arp_ha.sa_len = sizeof(struct sockaddr); arpreq.arp_ha.sa_family = AF_UNSPEC; memcpy(arpreq.arp_ha.sa_data, LLADDR(&dls.sdl), dls.sdl.sdl_alen); SET_SA_FAMILY(arpreq.arp_pa, AF_INET); ((struct sockaddr_in *)&arpreq.arp_pa)->sin_addr.s_addr = addr.s_addr; arpreq.arp_flags = ATF_PERM | ATF_PUBL; if (ID0ioctl(s, SIOCSARP, (caddr_t) & arpreq) < 0) { log_Printf(LogERROR, "arp_SetProxy: ioctl(SIOCSARP): %s\n", strerror(errno)); return 0; } return 1; }
/* * cifaddr - Clear the interface IP addresses, and delete routes * through the interface if possible. */ int cifaddr( int u, uint32_t o, uint32_t 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; }
/* * arp_ClearProxy - Delete the proxy ARP entry for the peer. */ int arp_ClearProxy(struct bundle *bundle, struct in_addr addr, int s) { struct arpreq arpreq; memset(&arpreq, '\0', sizeof arpreq); SET_SA_FAMILY(arpreq.arp_pa, AF_INET); ((struct sockaddr_in *)&arpreq.arp_pa)->sin_addr.s_addr = addr.s_addr; if (ID0ioctl(s, SIOCDARP, (caddr_t) & arpreq) < 0) { log_Printf(LogERROR, "arp_ClearProxy: ioctl(SIOCDARP): %s\n", strerror(errno)); return 0; } return 1; }
int cifdefaultroute (int unit, int gateway) { struct rtentry rt; if (has_default_route) { memset (&rt, '\0', sizeof (rt)); SET_SA_FAMILY (rt.rt_dst, AF_INET); SET_SA_FAMILY (rt.rt_gateway, AF_INET); ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = gateway; rt.rt_flags = RTF_UP | RTF_GATEWAY; if (ioctl(sockfd, SIOCDELRT, &rt) < 0 && errno != ESRCH) { if (still_ppp()) { syslog (LOG_ERR, "default route ioctl(SIOCDELRT): %m"); return 0; } } } has_default_route = 0; return 1; }
/* * cifproxyarp - Delete the proxy ARP entry for the peer. */ int cifproxyarp( int unit, uint32_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; }
int cifproxyarp (int unit, u_int32_t his_adr) { struct arpreq arpreq; if (has_proxy_arp == 1) { memset (&arpreq, '\0', sizeof(arpreq)); SET_SA_FAMILY(arpreq.arp_pa, AF_INET); arpreq.arp_flags = ATF_PERM | ATF_PUBL; ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = his_adr; if (ioctl(sockfd, SIOCDARP, (caddr_t)&arpreq) < 0) { syslog(LOG_WARNING, "ioctl(SIOCDARP): %m"); return 0; } } has_proxy_arp = 0; return 1; }
int sifproxyarp (int unit, u_int32_t his_adr) { struct arpreq arpreq; /* * Sometime in the 1.3 series kernels, the arp request added a device name. */ #include <linux/version.h> #if LINUX_VERSION_CODE < 66381 char arpreq_arp_dev[32]; #else #define arpreq_arp_dev arpreq.arp_dev #endif if (has_proxy_arp == 0) { memset (&arpreq, '\0', sizeof(arpreq)); /* * Get the hardware address of an interface on the same subnet * as our local address. */ if (!get_ether_addr(his_adr, &arpreq.arp_ha, arpreq_arp_dev)) { syslog(LOG_ERR, "Cannot determine ethernet address for proxy ARP"); return 0; } SET_SA_FAMILY(arpreq.arp_pa, AF_INET); ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = his_adr; arpreq.arp_flags = ATF_PERM | ATF_PUBL; if (ioctl(sockfd, SIOCSARP, (caddr_t)&arpreq) < 0) { syslog(LOG_ERR, "ioctl(SIOCSARP): %m"); return 0; } } has_proxy_arp = 1; return 1; }
/* * sifproxyarp - Make a proxy ARP entry for the peer. */ int sifproxyarp( int unit, uint32_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; }
int dev_set_addrs() { ulong laddr = 0, raddr = 0; char sbuf[sizeof(PATH_IFCONFIG SL_DOWN) + 10]; /* Try to get the interface number if we don't know it yet. */ if (link_iface == -1) { link_iface = device_iface; syslog(LOG_INFO,"Old %s , New device : %s %d",device,device_node,device_iface); } /* Ok then, see if pppd has upped the interface yet. */ if (link_iface != -1) { struct ifreq ifr; SET_SA_FAMILY (ifr.ifr_addr, AF_INET); SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET); SET_SA_FAMILY (ifr.ifr_netmask, AF_INET); sprintf(ifr.ifr_name, device); if (ioctl(snoopfd, SIOCGIFFLAGS, (caddr_t) &ifr) == -1) { syslog(LOG_ERR,"failed to read interface status from device %s",device); return 0; } if (!(ifr.ifr_flags & IFF_UP)) return 0; /* interface is not up yet */ if (route_wait) { /* set the initial rx counter once the link is up */ if (rx_count == -1) rx_count = dev_rx_count(); /* check if we got the routing packet yet */ if (dev_rx_count() == rx_count) return 0; } /* Ok, the interface is up, grab the addresses. */ if (ioctl(snoopfd, SIOCGIFADDR, (caddr_t) &ifr) == -1) syslog(LOG_ERR,"failed to get local address from device %s: %m",device); else laddr = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr; if (ioctl(snoopfd, SIOCGIFDSTADDR, (caddr_t) &ifr) == -1) syslog(LOG_ERR,"failed to get remote address: %m"); else raddr = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr; /* Set the ptp routing for the new interface */ set_ptp(device_node,link_iface,remote_ip,metric); if (dynamic_addrs) { /* only do the configuration in dynamic mode. */ struct in_addr addr; addr.s_addr = raddr; strcpy(remote_ip,inet_ntoa(addr)); addr.s_addr = laddr; strcpy(local_ip,inet_ntoa(addr)); local_addr = laddr; syslog(LOG_INFO,"New addresses: local %s, remote %s.", local_ip,remote_ip); if (!do_reroute) { proxy_config(local_ip,remote_ip); set_ptp("sl",proxy_iface,remote_ip,metric+1); add_routes("sl",proxy_iface,local_ip,remote_ip,drmetric+1); } } if (do_reroute) add_routes(device_node,link_iface,local_ip,remote_ip,drmetric); /* * bring down the sl link here, and then bring it back up. */ snprintf(sbuf, sizeof(sbuf), PATH_IFCONFIG SL_DOWN, proxy_iface); system(sbuf); snprintf(sbuf, sizeof(sbuf), PATH_IFCONFIG SL_UP, proxy_iface); system(sbuf); return 1; } return 0; }
int sifaddr (int unit, int our_adr, int his_adr, int net_mask) { struct ifreq ifr; struct rtentry rt; memset (&ifr, '\0', sizeof (ifr)); memset (&rt, '\0', sizeof (rt)); SET_SA_FAMILY (ifr.ifr_addr, AF_INET); SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET); SET_SA_FAMILY (ifr.ifr_netmask, AF_INET); strncpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); /* * Set our IP address */ ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = our_adr; if (ioctl(sockfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) { if (errno != EEXIST) { syslog (LOG_ERR, "ioctl(SIOCAIFADDR): %m"); } else { syslog (LOG_WARNING, "ioctl(SIOCAIFADDR): Address already exists"); } return (0); } /* * Set the gateway address */ ((struct sockaddr_in *) &ifr.ifr_dstaddr)->sin_addr.s_addr = his_adr; if (ioctl(sockfd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) { syslog (LOG_ERR, "ioctl(SIOCSIFDSTADDR): %m"); return (0); } /* * Set the netmask */ if (net_mask != 0) { ((struct sockaddr_in *) &ifr.ifr_netmask)->sin_addr.s_addr = net_mask; if (ioctl(sockfd, SIOCSIFNETMASK, (caddr_t) &ifr) < 0) { syslog (LOG_ERR, "ioctl(SIOCSIFNETMASK): %m"); return (0); } } /* * Add the device route */ SET_SA_FAMILY (rt.rt_dst, AF_INET); SET_SA_FAMILY (rt.rt_gateway, AF_INET); rt.rt_dev = ifname; /* MJC */ ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = 0L; ((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr = his_adr; rt.rt_flags = RTF_UP | RTF_HOST; if (ioctl(sockfd, SIOCADDRT, &rt) < 0) { syslog (LOG_ERR, "ioctl(SIOCADDRT) device route: %m"); return (0); } return 1; }