Changeset View
Changeset View
Standalone View
Standalone View
head/usr.sbin/mld6query/mld6.c
Show First 20 Lines • Show All 197 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
void | void | ||||
make_msg(int index, struct in6_addr *addr, u_int type, struct in6_addr *qaddr) | make_msg(int index, struct in6_addr *addr, u_int type, struct in6_addr *qaddr) | ||||
{ | { | ||||
static struct iovec iov[2]; | static struct iovec iov[2]; | ||||
static u_char *cmsgbuf; | static u_char *cmsgbuf; | ||||
int cmsglen, hbhlen = 0; | int cmsglen, hbhlen = 0; | ||||
#ifdef USE_RFC2292BIS | |||||
void *hbhbuf = NULL, *optp = NULL; | void *hbhbuf = NULL, *optp = NULL; | ||||
int currentlen; | int currentlen; | ||||
#else | |||||
u_int8_t raopt[IP6OPT_RTALERT_LEN]; | |||||
#endif | |||||
struct in6_pktinfo *pi; | struct in6_pktinfo *pi; | ||||
struct cmsghdr *cmsgp; | struct cmsghdr *cmsgp; | ||||
u_short rtalert_code = htons(IP6OPT_RTALERT_MLD); | u_short rtalert_code = htons(IP6OPT_RTALERT_MLD); | ||||
struct ifaddrs *ifa, *ifap; | struct ifaddrs *ifa, *ifap; | ||||
struct in6_addr src; | struct in6_addr src; | ||||
dst.sin6_len = sizeof(dst); | dst.sin6_len = sizeof(dst); | ||||
dst.sin6_family = AF_INET6; | dst.sin6_family = AF_INET6; | ||||
Show All 28 Lines | make_msg(int index, struct in6_addr *addr, u_int type, struct in6_addr *qaddr) | ||||
memcpy(&src, &((struct sockaddr_in6 *)ifap->ifa_addr)->sin6_addr, | memcpy(&src, &((struct sockaddr_in6 *)ifap->ifa_addr)->sin6_addr, | ||||
sizeof(src)); | sizeof(src)); | ||||
freeifaddrs(ifa); | freeifaddrs(ifa); | ||||
#ifdef __KAME__ | #ifdef __KAME__ | ||||
/* remove embedded ifindex */ | /* remove embedded ifindex */ | ||||
src.s6_addr[2] = src.s6_addr[3] = 0; | src.s6_addr[2] = src.s6_addr[3] = 0; | ||||
#endif | #endif | ||||
#ifdef USE_RFC2292BIS | |||||
if ((hbhlen = inet6_opt_init(NULL, 0)) == -1) | if ((hbhlen = inet6_opt_init(NULL, 0)) == -1) | ||||
errx(1, "inet6_opt_init(0) failed"); | errx(1, "inet6_opt_init(0) failed"); | ||||
if ((hbhlen = inet6_opt_append(NULL, 0, hbhlen, IP6OPT_ROUTER_ALERT, 2, | if ((hbhlen = inet6_opt_append(NULL, 0, hbhlen, IP6OPT_ROUTER_ALERT, 2, | ||||
2, NULL)) == -1) | 2, NULL)) == -1) | ||||
errx(1, "inet6_opt_append(0) failed"); | errx(1, "inet6_opt_append(0) failed"); | ||||
if ((hbhlen = inet6_opt_finish(NULL, 0, hbhlen)) == -1) | if ((hbhlen = inet6_opt_finish(NULL, 0, hbhlen)) == -1) | ||||
errx(1, "inet6_opt_finish(0) failed"); | errx(1, "inet6_opt_finish(0) failed"); | ||||
cmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) + CMSG_SPACE(hbhlen); | cmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) + CMSG_SPACE(hbhlen); | ||||
#else | |||||
hbhlen = sizeof(raopt); | |||||
cmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) + | |||||
inet6_option_space(hbhlen); | |||||
#endif | |||||
if ((cmsgbuf = malloc(cmsglen)) == NULL) | if ((cmsgbuf = malloc(cmsglen)) == NULL) | ||||
errx(1, "can't allocate enough memory for cmsg"); | errx(1, "can't allocate enough memory for cmsg"); | ||||
cmsgp = (struct cmsghdr *)cmsgbuf; | cmsgp = (struct cmsghdr *)cmsgbuf; | ||||
m.msg_control = (caddr_t)cmsgbuf; | m.msg_control = (caddr_t)cmsgbuf; | ||||
m.msg_controllen = cmsglen; | m.msg_controllen = cmsglen; | ||||
/* specify the outgoing interface */ | /* specify the outgoing interface */ | ||||
cmsgp->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); | cmsgp->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); | ||||
cmsgp->cmsg_level = IPPROTO_IPV6; | cmsgp->cmsg_level = IPPROTO_IPV6; | ||||
cmsgp->cmsg_type = IPV6_PKTINFO; | cmsgp->cmsg_type = IPV6_PKTINFO; | ||||
pi = (struct in6_pktinfo *)CMSG_DATA(cmsgp); | pi = (struct in6_pktinfo *)CMSG_DATA(cmsgp); | ||||
pi->ipi6_ifindex = index; | pi->ipi6_ifindex = index; | ||||
memcpy(&pi->ipi6_addr, &src, sizeof(pi->ipi6_addr)); | memcpy(&pi->ipi6_addr, &src, sizeof(pi->ipi6_addr)); | ||||
/* specifiy to insert router alert option in a hop-by-hop opt hdr. */ | /* specifiy to insert router alert option in a hop-by-hop opt hdr. */ | ||||
cmsgp = CMSG_NXTHDR(&m, cmsgp); | cmsgp = CMSG_NXTHDR(&m, cmsgp); | ||||
#ifdef USE_RFC2292BIS | |||||
cmsgp->cmsg_len = CMSG_LEN(hbhlen); | cmsgp->cmsg_len = CMSG_LEN(hbhlen); | ||||
cmsgp->cmsg_level = IPPROTO_IPV6; | cmsgp->cmsg_level = IPPROTO_IPV6; | ||||
cmsgp->cmsg_type = IPV6_HOPOPTS; | cmsgp->cmsg_type = IPV6_HOPOPTS; | ||||
hbhbuf = CMSG_DATA(cmsgp); | hbhbuf = CMSG_DATA(cmsgp); | ||||
if ((currentlen = inet6_opt_init(hbhbuf, hbhlen)) == -1) | if ((currentlen = inet6_opt_init(hbhbuf, hbhlen)) == -1) | ||||
errx(1, "inet6_opt_init(len = %d) failed", hbhlen); | errx(1, "inet6_opt_init(len = %d) failed", hbhlen); | ||||
if ((currentlen = inet6_opt_append(hbhbuf, hbhlen, currentlen, | if ((currentlen = inet6_opt_append(hbhbuf, hbhlen, currentlen, | ||||
IP6OPT_ROUTER_ALERT, 2, | IP6OPT_ROUTER_ALERT, 2, | ||||
2, &optp)) == -1) | 2, &optp)) == -1) | ||||
errx(1, "inet6_opt_append(currentlen = %d, hbhlen = %d) failed", | errx(1, "inet6_opt_append(currentlen = %d, hbhlen = %d) failed", | ||||
currentlen, hbhlen); | currentlen, hbhlen); | ||||
(void)inet6_opt_set_val(optp, 0, &rtalert_code, sizeof(rtalert_code)); | (void)inet6_opt_set_val(optp, 0, &rtalert_code, sizeof(rtalert_code)); | ||||
if ((currentlen = inet6_opt_finish(hbhbuf, hbhlen, currentlen)) == -1) | if ((currentlen = inet6_opt_finish(hbhbuf, hbhlen, currentlen)) == -1) | ||||
errx(1, "inet6_opt_finish(buf) failed"); | errx(1, "inet6_opt_finish(buf) failed"); | ||||
#else /* old advanced API */ | |||||
if (inet6_option_init((void *)cmsgp, &cmsgp, IPV6_HOPOPTS)) | |||||
errx(1, "inet6_option_init failed\n"); | |||||
raopt[0] = IP6OPT_ROUTER_ALERT; | |||||
raopt[1] = IP6OPT_RTALERT_LEN - 2; | |||||
memcpy(&raopt[2], (caddr_t)&rtalert_code, sizeof(u_short)); | |||||
if (inet6_option_append(cmsgp, raopt, 4, 0)) | |||||
errx(1, "inet6_option_append failed\n"); | |||||
#endif | |||||
} | } | ||||
void | void | ||||
dump(int s) | dump(int s) | ||||
{ | { | ||||
int i; | int i; | ||||
struct mld_hdr *mld; | struct mld_hdr *mld; | ||||
u_char buf[1024]; | u_char buf[1024]; | ||||
▲ Show 20 Lines • Show All 54 Lines • Show Last 20 Lines |