int rump_netconfig_ipv6_gw(const char *gwaddr) { struct rt_msghdr rtm, *rtmp; struct sockaddr_in6 sin6; struct mbuf *m; int off, rv; CHECKDOMAIN(in6so); memset(&rtm, 0, sizeof(rtm)); rtm.rtm_type = RTM_ADD; rtm.rtm_flags = RTF_UP | RTF_STATIC | RTF_GATEWAY; rtm.rtm_version = RTM_VERSION; rtm.rtm_seq = 2; rtm.rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK; m = m_gethdr(M_WAIT, MT_DATA); m->m_pkthdr.len = 0; m_copyback(m, 0, sizeof(rtm), &rtm); off = sizeof(rtm); /* dest */ memset(&sin6, 0, sizeof(sin6)); sin6.sin6_family = AF_INET6; sin6.sin6_len = sizeof(sin6); m_copyback(m, off, sin6.sin6_len, &sin6); RT_ADVANCE(off, (struct sockaddr *)&sin6); /* gw */ netconfig_inet_pton6(gwaddr, &sin6.sin6_addr); m_copyback(m, off, sin6.sin6_len, &sin6); RT_ADVANCE(off, (struct sockaddr *)&sin6); /* mask */ memset(&sin6.sin6_addr, 0, sizeof(sin6.sin6_addr)); m_copyback(m, off, sin6.sin6_len, &sin6); off = m->m_pkthdr.len; m = m_pullup(m, sizeof(*rtmp)); rtmp = mtod(m, struct rt_msghdr *); rtmp->rtm_msglen = off; solock(rtso); #if __NetBSD_Prereq__(7,99,26) rv = rtso->so_proto->pr_usrreqs->pr_send(rtso, m, NULL, NULL, curlwp); #else rv = rtso->so_proto->pr_output(m, rtso); #endif sounlock(rtso); return rv; }
static void get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info) { int i; for (i = 0; i < RTAX_MAX; i++) { if (addrs & (1 << i)) { rti_info[i] = sa; RT_ADVANCE(sa, sa); } else rti_info[i] = NULL; } }
void rt_xaddrs(caddr_t cp, caddr_t cplim, struct rt_addrinfo *rtinfo) { struct sockaddr *sa; int i; memset(rtinfo->rti_info, 0, sizeof(rtinfo->rti_info)); for (i = 0; (i < RTAX_MAX) && (cp < cplim); i++) { if ((rtinfo->rti_addrs & (1 << i)) == 0) continue; rtinfo->rti_info[i] = sa = (struct sockaddr *)cp; RT_ADVANCE(cp, sa); } }
static void get_addrs(int type, char *cp, struct sockaddr **sa) { int i; for (i = 0; i < RTAX_MAX; i++) { if (type & (1 << i)) { sa[i] = (struct sockaddr *)cp; #ifdef DEBUG printf ("got %d %d %s\n", i, sa[i]->sa_family, inet_ntoa(((struct sockaddr_in *)sa[i])-> sin_addr)); #endif RT_ADVANCE(cp, sa[i]); } else sa[i] = NULL; } }
static void SetAliasAddressFromIfName(const char *ifn) { size_t needed; int mib[6]; char *buf, *lim, *next; struct if_msghdr *ifm; struct ifa_msghdr *ifam; struct sockaddr_dl *s_dl; struct sockaddr_in *s_in; mib[0] = CTL_NET; mib[1] = PF_ROUTE; mib[2] = 0; mib[3] = AF_INET; /* Only IP addresses please */ mib[4] = NET_RT_IFLIST; mib[5] = 0; /* ifIndex??? */ /* * Get interface data. */ if (sysctl(mib, 6, NULL, &needed, NULL, 0) == -1) err(1, "iflist-sysctl-estimate"); if ((buf = malloc(needed)) == NULL) errx(1, "malloc failed"); if (sysctl(mib, 6, buf, &needed, NULL, 0) == -1) err(1, "iflist-sysctl-get"); lim = buf + needed; /* * Loop through interfaces until one with * given name is found. This is done to * find correct interface index for routing * message processing. */ ifIndex = 0; next = buf; while (next < lim) { ifm = (struct if_msghdr *)next; next += ifm->ifm_msglen; if (ifm->ifm_version != RTM_VERSION) { if (verbose) warnx("routing message version %d " "not understood", ifm->ifm_version); continue; } if (ifm->ifm_type == RTM_IFINFO) { s_dl = (struct sockaddr_dl *)(ifm + 1); if (strlen(ifn) == s_dl->sdl_nlen && strncmp(ifn, s_dl->sdl_data, s_dl->sdl_nlen) == 0) { ifIndex = ifm->ifm_index; ifMTU = ifm->ifm_data.ifi_mtu; break; } } } if (!ifIndex) errx(1, "unknown interface name %s", ifn); /* * Get interface address. */ s_in = NULL; while (next < lim) { ifam = (struct ifa_msghdr *)next; next += ifam->ifam_msglen; if (ifam->ifam_version != RTM_VERSION) { if (verbose) warnx("routing message version %d " "not understood", ifam->ifam_version); continue; } if (ifam->ifam_type != RTM_NEWADDR) break; if (ifam->ifam_addrs & RTA_IFA) { int i; char *cp = (char *)(ifam + 1); for (i = 1; i < RTA_IFA; i <<= 1) if (ifam->ifam_addrs & i) RT_ADVANCE(cp, (struct sockaddr *)cp); if (((struct sockaddr *)cp)->sa_family == AF_INET) { s_in = (struct sockaddr_in *)cp; break; } } } if (s_in == NULL) errx(1, "%s: cannot get interface address", ifn); PacketAliasSetAddress(s_in->sin_addr); syslog(LOG_INFO, "Aliasing to %s, mtu %d bytes", inet_ntoa(s_in->sin_addr), ifMTU); free(buf); }