static void link_getaddr(const char *addr, int which) { char *temp; struct sockaddr_dl sdl; struct sockaddr *sa = &link_ridreq.ifr_addr; if (which != ADDR) errx(1, "can't set link-level netmask or broadcast"); if (!strcmp(addr, "random")) { sdl.sdl_len = sizeof(sdl); sdl.sdl_alen = ETHER_ADDR_LEN; sdl.sdl_nlen = 0; sdl.sdl_family = AF_LINK; arc4random_buf(&sdl.sdl_data, ETHER_ADDR_LEN); /* Non-multicast and claim it is locally administered. */ sdl.sdl_data[0] &= 0xfc; sdl.sdl_data[0] |= 0x02; } else { if ((temp = malloc(strlen(addr) + 2)) == NULL) errx(1, "malloc failed"); temp[0] = ':'; strcpy(temp + 1, addr); sdl.sdl_len = sizeof(sdl); link_addr(temp, &sdl); free(temp); } if (sdl.sdl_alen > sizeof(sa->sa_data)) errx(1, "malformed link-level address"); sa->sa_family = AF_LINK; sa->sa_len = sdl.sdl_alen; bcopy(LLADDR(&sdl), sa->sa_data, sdl.sdl_alen); }
void frame::layout_iterate(FrameLayoutClosure* blk) { if (is_interpreted_frame()){ oop* eos = temp_addr(0); for (oop* p = sp(); p <= eos; p++) blk->do_stack(eos-p, p); blk->do_hp(hp_addr()); blk->do_receiver(receiver_addr()); blk->do_link(link_addr()); blk->do_return_addr(return_addr_addr()); } }
static void if_linkaddr(struct sockaddr_dl *sdl, const struct interface *ifp) { #ifdef __FreeBSD__ memcpy(sdl, &ifp->linkaddr, sizeof(*sdl)); sdl->sdl_nlen = sdl->sdl_alen = sdl->sdl_slen = 0; #else sdl->sdl_len = sizeof(*sdl); link_addr(ifp->name, sdl); #endif }
static void link_getaddr(const char *addr, int which) { char *temp; struct sockaddr_dl sdl; struct sockaddr *sa = &link_ridreq.ifr_addr; if (which != ADDR) errx(1, "can't set link-level netmask or broadcast"); if ((temp = malloc(strlen(addr) + 2)) == NULL) errx(1, "malloc failed"); temp[0] = ':'; strcpy(temp + 1, addr); sdl.sdl_len = sizeof(sdl); link_addr(temp, &sdl); free(temp); if (sdl.sdl_alen > sizeof(sa->sa_data)) errx(1, "malformed link-level address"); sa->sa_family = AF_LINK; sa->sa_len = sdl.sdl_alen; bcopy(LLADDR(&sdl), sa->sa_data, sdl.sdl_alen); }
E* Stack<E, F>::set_link(E* new_seg, E* old_seg) { *link_addr(new_seg) = old_seg; return new_seg; }
E* Stack<E, F>::get_link(E* seg) const { return *link_addr(seg); }
/* ARGSUSED4 */ int if_route(const struct interface *iface, const struct in_addr *dest, const struct in_addr *net, const struct in_addr *gate, _unused int metric, int action) { union sockunion { struct sockaddr sa; struct sockaddr_in sin; #ifdef INET6 struct sockaddr_in6 sin6; #endif struct sockaddr_dl sdl; struct sockaddr_storage ss; } su; struct rtm { struct rt_msghdr hdr; char buffer[sizeof(su) * 4]; } rtm; char *bp = rtm.buffer, *p; size_t l; int retval = 0; #define ADDSU(_su) { \ l = ROUNDUP(_su.sa.sa_len); \ memcpy(bp, &(_su), l); \ bp += l; \ } #define ADDADDR(_a) { \ memset (&su, 0, sizeof(su)); \ su.sin.sin_family = AF_INET; \ su.sin.sin_len = sizeof(su.sin); \ memcpy (&su.sin.sin_addr, _a, sizeof(su.sin.sin_addr)); \ ADDSU(su); \ } memset(&rtm, 0, sizeof(rtm)); rtm.hdr.rtm_version = RTM_VERSION; rtm.hdr.rtm_seq = 1; if (action == 0) rtm.hdr.rtm_type = RTM_CHANGE; else if (action > 0) rtm.hdr.rtm_type = RTM_ADD; else rtm.hdr.rtm_type = RTM_DELETE; rtm.hdr.rtm_flags = RTF_UP; /* None interface subnet routes are static. */ if (gate->s_addr != INADDR_ANY || net->s_addr != iface->net.s_addr || dest->s_addr != (iface->addr.s_addr & iface->net.s_addr)) rtm.hdr.rtm_flags |= RTF_STATIC; rtm.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY; if (dest->s_addr == gate->s_addr && net->s_addr == INADDR_BROADCAST) rtm.hdr.rtm_flags |= RTF_HOST; else { rtm.hdr.rtm_addrs |= RTA_NETMASK; if (rtm.hdr.rtm_flags & RTF_STATIC) rtm.hdr.rtm_flags |= RTF_GATEWAY; if (action >= 0) rtm.hdr.rtm_addrs |= RTA_IFA; } ADDADDR(dest); if (rtm.hdr.rtm_flags & RTF_HOST || !(rtm.hdr.rtm_flags & RTF_STATIC)) { /* Make us a link layer socket for the host gateway */ memset(&su, 0, sizeof(su)); su.sdl.sdl_len = sizeof(struct sockaddr_dl); link_addr(iface->name, &su.sdl); ADDSU(su); } else ADDADDR(gate); if (rtm.hdr.rtm_addrs & RTA_NETMASK) { /* Ensure that netmask is set correctly */ memset(&su, 0, sizeof(su)); su.sin.sin_family = AF_INET; su.sin.sin_len = sizeof(su.sin); memcpy(&su.sin.sin_addr, &net->s_addr, sizeof(su.sin.sin_addr)); p = su.sa.sa_len + (char *)&su; for (su.sa.sa_len = 0; p > (char *)&su;) if (*--p != 0) { su.sa.sa_len = 1 + p - (char *)&su; break; } ADDSU(su); } if (rtm.hdr.rtm_addrs & RTA_IFA) ADDADDR(&iface->addr); rtm.hdr.rtm_msglen = l = bp - (char *)&rtm; if (write(r_fd, &rtm, l) == -1) retval = -1; return retval; }
int if_route6(const struct rt6 *rt, int action) { union sockunion { struct sockaddr sa; struct sockaddr_in6 sin; struct sockaddr_dl sdl; struct sockaddr_storage ss; } su; struct rtm { struct rt_msghdr hdr; char buffer[sizeof(su) * 4]; } rtm; char *bp = rtm.buffer; size_t l; int retval = 0; const struct ipv6_addr_l *lla; /* KAME based systems want to store the scope inside the sin6_addr * for link local addreses */ #ifdef __KAME__ #define SCOPE { \ if (IN6_IS_ADDR_LINKLOCAL(&su.sin.sin6_addr)) { \ uint16_t scope = htons(su.sin.sin6_scope_id); \ memcpy(&su.sin.sin6_addr.s6_addr[2], &scope, \ sizeof(scope)); \ su.sin.sin6_scope_id = 0; \ } \ } #else #define SCOPE #endif #define ADDSU { \ l = RT_ROUNDUP(su.sa.sa_len); \ memcpy(bp, &su, l); \ bp += l; \ } #define ADDADDRS(addr, scope) { \ memset(&su, 0, sizeof(su)); \ su.sin.sin6_family = AF_INET6; \ su.sin.sin6_len = sizeof(su.sin); \ (&su.sin)->sin6_addr = *addr; \ su.sin.sin6_scope_id = scope; \ SCOPE; \ ADDSU; \ } #define ADDADDR(addr) ADDADDRS(addr, 0) memset(&rtm, 0, sizeof(rtm)); rtm.hdr.rtm_version = RTM_VERSION; rtm.hdr.rtm_seq = 1; if (action == 0) rtm.hdr.rtm_type = RTM_CHANGE; else if (action > 0) rtm.hdr.rtm_type = RTM_ADD; else rtm.hdr.rtm_type = RTM_DELETE; rtm.hdr.rtm_flags = RTF_UP; /* None interface subnet routes are static. */ if (IN6_IS_ADDR_UNSPECIFIED(&rt->dest) && IN6_IS_ADDR_UNSPECIFIED(&rt->net)) rtm.hdr.rtm_flags |= RTF_GATEWAY; #ifdef RTF_CLONING else rtm.hdr.rtm_flags |= RTF_CLONING; #endif rtm.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK; if (action >= 0) rtm.hdr.rtm_addrs |= RTA_IFP | RTA_IFA; ADDADDR(&rt->dest); if (!(rtm.hdr.rtm_flags & RTF_GATEWAY)) { lla = ipv6_linklocal(rt->iface); if (lla == NULL) /* unlikely as we need a LL to get here */ return -1; ADDADDRS(&lla->addr, rt->iface->index); } else { lla = NULL; ADDADDRS(&rt->gate, rt->iface->index); } if (rtm.hdr.rtm_addrs & RTA_NETMASK) { if (rtm.hdr.rtm_flags & RTF_GATEWAY) { memset(&su, 0, sizeof(su)); su.sin.sin6_family = AF_INET6; ADDSU; } else ADDADDR(&rt->net); } if (rtm.hdr.rtm_addrs & RTA_IFP) { /* Make us a link layer socket for the host gateway */ memset(&su, 0, sizeof(su)); su.sdl.sdl_len = sizeof(struct sockaddr_dl); link_addr(rt->iface->name, &su.sdl); ADDSU; } if (rtm.hdr.rtm_addrs & RTA_IFA) { if (lla == NULL) { lla = ipv6_linklocal(rt->iface); if (lla == NULL) /* unlikely */ return -1; } ADDADDRS(&lla->addr, rt->iface->index); } #undef ADDADDR #undef ADDSU #undef SCOPE if (action >= 0 && rt->mtu) { rtm.hdr.rtm_inits |= RTV_MTU; rtm.hdr.rtm_rmx.rmx_mtu = rt->mtu; } rtm.hdr.rtm_msglen = l = bp - (char *)&rtm; if (write(r_fd, &rtm, l) == -1) retval = -1; return retval; }
int if_route(const struct rt *rt, int action) { const struct dhcp_state *state; union sockunion { struct sockaddr sa; struct sockaddr_in sin; struct sockaddr_dl sdl; struct sockaddr_storage ss; } su; struct rtm { struct rt_msghdr hdr; char buffer[sizeof(su) * 4]; } rtm; char *bp = rtm.buffer; size_t l; int retval = 0; #define ADDSU { \ l = RT_ROUNDUP(su.sa.sa_len); \ memcpy(bp, &su, l); \ bp += l; \ } #define ADDADDR(addr) { \ memset(&su, 0, sizeof(su)); \ su.sin.sin_family = AF_INET; \ su.sin.sin_len = sizeof(su.sin); \ (&su.sin)->sin_addr = *addr; \ ADDSU; \ } state = D_CSTATE(rt->iface); memset(&rtm, 0, sizeof(rtm)); rtm.hdr.rtm_version = RTM_VERSION; rtm.hdr.rtm_seq = 1; if (action == 0) rtm.hdr.rtm_type = RTM_CHANGE; else if (action > 0) rtm.hdr.rtm_type = RTM_ADD; else rtm.hdr.rtm_type = RTM_DELETE; rtm.hdr.rtm_flags = RTF_UP; /* None interface subnet routes are static. */ if (rt->gate.s_addr != INADDR_ANY || rt->net.s_addr != state->net.s_addr || rt->dest.s_addr != (state->addr.s_addr & state->net.s_addr)) rtm.hdr.rtm_flags |= RTF_STATIC; rtm.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY; if (rt->dest.s_addr == rt->gate.s_addr && rt->net.s_addr == INADDR_BROADCAST) rtm.hdr.rtm_flags |= RTF_HOST; else if (rt->gate.s_addr == htonl(INADDR_LOOPBACK) && rt->net.s_addr == INADDR_BROADCAST) rtm.hdr.rtm_flags |= RTF_HOST | RTF_GATEWAY; else { rtm.hdr.rtm_addrs |= RTA_NETMASK; if (rtm.hdr.rtm_flags & RTF_STATIC) rtm.hdr.rtm_flags |= RTF_GATEWAY; if (action >= 0) rtm.hdr.rtm_addrs |= RTA_IFA; } ADDADDR(&rt->dest); if ((rtm.hdr.rtm_flags & RTF_HOST && rt->gate.s_addr != htonl(INADDR_LOOPBACK)) || !(rtm.hdr.rtm_flags & RTF_STATIC)) { /* Make us a link layer socket for the host gateway */ memset(&su, 0, sizeof(su)); su.sdl.sdl_len = sizeof(struct sockaddr_dl); link_addr(rt->iface->name, &su.sdl); ADDSU; } else ADDADDR(&rt->gate); if (rtm.hdr.rtm_addrs & RTA_NETMASK) ADDADDR(&rt->net); if (rtm.hdr.rtm_addrs & RTA_IFP) { /* Make us a link layer socket for the host gateway */ memset(&su, 0, sizeof(su)); su.sdl.sdl_len = sizeof(struct sockaddr_dl); link_addr(rt->iface->name, &su.sdl); ADDSU; } if (rtm.hdr.rtm_addrs & RTA_IFA) ADDADDR(&state->addr); #undef ADDADDR #undef ADDSU rtm.hdr.rtm_msglen = l = bp - (char *)&rtm; if (write(r_fd, &rtm, l) == -1) retval = -1; return retval; }
void set_link(int* addr) { *link_addr() = addr; }
// Link int* link() const { return *link_addr(); }
static int link_netlink(struct dhcpcd_ctx *ctx, struct interface *ifp, struct nlmsghdr *nlm) { int r; size_t len; struct rtattr *rta, *hwaddr; struct ifinfomsg *ifi; char ifn[IF_NAMESIZE + 1]; r = link_route(ctx, ifp, nlm); if (r != 0) return r; r = link_addr(ctx, ifp, nlm); if (r != 0) return r; #ifdef INET6 r = link_neigh(ctx, ifp, nlm); if (r != 0) return r; #endif if (nlm->nlmsg_type != RTM_NEWLINK && nlm->nlmsg_type != RTM_DELLINK) return 0; len = nlm->nlmsg_len - sizeof(*nlm); if ((size_t)len < sizeof(*ifi)) { errno = EBADMSG; return -1; } ifi = NLMSG_DATA(nlm); if (ifi->ifi_flags & IFF_LOOPBACK) return 0; rta = (void *)((char *)ifi + NLMSG_ALIGN(sizeof(*ifi))); len = NLMSG_PAYLOAD(nlm, sizeof(*ifi)); *ifn = '\0'; hwaddr = NULL; while (RTA_OK(rta, len)) { switch (rta->rta_type) { case IFLA_WIRELESS: /* Ignore wireless messages */ if (nlm->nlmsg_type == RTM_NEWLINK && ifi->ifi_change == 0) return 0; break; case IFLA_IFNAME: strlcpy(ifn, (char *)RTA_DATA(rta), sizeof(ifn)); break; case IFLA_ADDRESS: hwaddr = rta; break; } rta = RTA_NEXT(rta, len); } if (nlm->nlmsg_type == RTM_DELLINK) { /* If are listening to a dev manager, let that remove * the interface rather than the kernel. */ if (dev_listening(ctx) < 1) dhcpcd_handleinterface(ctx, -1, ifn); return 0; } /* Virtual interfaces may not get a valid hardware address * at this point. * To trigger a valid hardware address pickup we need to pretend * that that don't exist until they have one. */ if (ifi->ifi_flags & IFF_MASTER && !hwaddr) { dhcpcd_handleinterface(ctx, -1, ifn); return 0; } /* Check for a new interface */ ifp = if_findindex(ctx->ifaces, (unsigned int)ifi->ifi_index); if (ifp == NULL) { /* If are listening to a dev manager, let that announce * the interface rather than the kernel. */ if (dev_listening(ctx) < 1) dhcpcd_handleinterface(ctx, 1, ifn); return 0; } /* Handle interface being renamed */ if (strcmp(ifp->name, ifn) != 0) { dhcpcd_handleinterface(ctx, -1, ifn); dhcpcd_handleinterface(ctx, 1, ifn); return 0; } /* Re-read hardware address and friends */ if (!(ifi->ifi_flags & IFF_UP) && hwaddr) { uint8_t l; l = l2addr_len(ifi->ifi_type); if (hwaddr->rta_len == RTA_LENGTH(l)) dhcpcd_handlehwaddr(ctx, ifn, RTA_DATA(hwaddr), l); } dhcpcd_handlecarrier(ctx, ifi->ifi_flags & IFF_RUNNING ? LINK_UP : LINK_DOWN, ifi->ifi_flags, ifn); return 0; }
static int link_netlink(struct nlmsghdr *nlm) { int len; struct rtattr *rta, *hwaddr; struct ifinfomsg *ifi; char ifn[IF_NAMESIZE + 1]; struct interface *ifp; len = link_route(nlm); if (len != 0) return len; len = link_addr(nlm); if (len != 0) return len; if (nlm->nlmsg_type != RTM_NEWLINK && nlm->nlmsg_type != RTM_DELLINK) return 0; len = nlm->nlmsg_len - sizeof(*nlm); if ((size_t)len < sizeof(*ifi)) { errno = EBADMSG; return -1; } ifi = NLMSG_DATA(nlm); if (ifi->ifi_flags & IFF_LOOPBACK) return 1; rta = (struct rtattr *)(void *)((char *)ifi +NLMSG_ALIGN(sizeof(*ifi))); len = NLMSG_PAYLOAD(nlm, sizeof(*ifi)); *ifn = '\0'; hwaddr = NULL; while (RTA_OK(rta, len)) { switch (rta->rta_type) { case IFLA_WIRELESS: /* Ignore wireless messages */ if (nlm->nlmsg_type == RTM_NEWLINK && ifi->ifi_change == 0) return 1; break; case IFLA_IFNAME: strlcpy(ifn, RTA_DATA(rta), sizeof(ifn)); break; case IFLA_ADDRESS: hwaddr = rta; break; } rta = RTA_NEXT(rta, len); } if (nlm->nlmsg_type == RTM_DELLINK) { handle_interface(-1, ifn); return 1; } /* Virtual interfaces may not get a valid hardware address * at this point. * To trigger a valid hardware address pickup we need to pretend * that that don't exist until they have one. */ if (ifi->ifi_flags & IFF_MASTER && !hwaddr) { handle_interface(-1, ifn); return 1; } /* Check for interface name change */ if (handle_rename(ifi->ifi_index, ifn)) return 1; /* Check for a new interface */ ifp = find_interface(ifn); if (ifp == NULL) { /* If are listening to a dev manager, let that announce * the interface rather than the kernel. */ if (dev_listening() < 1) handle_interface(1, ifn); return 1; } /* Re-read hardware address and friends */ if (!(ifi->ifi_flags & IFF_UP) && hwaddr) { len = l2addr_len(ifi->ifi_type); if (hwaddr->rta_len == RTA_LENGTH(len)) handle_hwaddr(ifn, RTA_DATA(hwaddr), len); } handle_carrier(ifi->ifi_flags & IFF_RUNNING ? LINK_UP : LINK_DOWN, ifi->ifi_flags, ifn); return 1; }