Changeset View
Standalone View
sbin/ping6/ping6.c
Show First 20 Lines • Show All 98 Lines • ▼ Show 20 Lines | |||||
* NOTE: | * NOTE: | ||||
* USE_SIN6_SCOPE_ID assumes that sin6_scope_id has the same semantics | * USE_SIN6_SCOPE_ID assumes that sin6_scope_id has the same semantics | ||||
* as IPV6_PKTINFO. Some people object it (sin6_scope_id specifies *link* | * as IPV6_PKTINFO. Some people object it (sin6_scope_id specifies *link* | ||||
* while IPV6_PKTINFO specifies *interface*. Link is defined as collection of | * while IPV6_PKTINFO specifies *interface*. Link is defined as collection of | ||||
* network attached to 1 or more interfaces) | * network attached to 1 or more interfaces) | ||||
*/ | */ | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/capsicum.h> | |||||
#include <sys/uio.h> | #include <sys/uio.h> | ||||
#include <sys/socket.h> | #include <sys/socket.h> | ||||
#include <sys/time.h> | #include <sys/time.h> | ||||
#include <net/if.h> | #include <net/if.h> | ||||
#include <net/route.h> | #include <net/route.h> | ||||
#include <netinet/in.h> | #include <netinet/in.h> | ||||
#include <netinet/ip6.h> | #include <netinet/ip6.h> | ||||
#include <netinet/icmp6.h> | #include <netinet/icmp6.h> | ||||
#include <arpa/inet.h> | #include <arpa/inet.h> | ||||
#include <arpa/nameser.h> | #include <arpa/nameser.h> | ||||
#include <netdb.h> | #include <netdb.h> | ||||
#include <capsicum_helpers.h> | |||||
#include <casper/cap_dns.h> | |||||
#include <libcasper.h> | |||||
#include <ctype.h> | #include <ctype.h> | ||||
#include <err.h> | #include <err.h> | ||||
#include <errno.h> | #include <errno.h> | ||||
#include <fcntl.h> | #include <fcntl.h> | ||||
#include <math.h> | #include <math.h> | ||||
#include <signal.h> | #include <signal.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
▲ Show 20 Lines • Show All 80 Lines • ▼ Show 20 Lines | |||||
#define MAX_DUP_CHK (8 * 8192) | #define MAX_DUP_CHK (8 * 8192) | ||||
static int mx_dup_ck = MAX_DUP_CHK; | static int mx_dup_ck = MAX_DUP_CHK; | ||||
static char rcvd_tbl[MAX_DUP_CHK / 8]; | static char rcvd_tbl[MAX_DUP_CHK / 8]; | ||||
static struct sockaddr_in6 dst; /* who to ping6 */ | static struct sockaddr_in6 dst; /* who to ping6 */ | ||||
static struct sockaddr_in6 src; /* src addr of this packet */ | static struct sockaddr_in6 src; /* src addr of this packet */ | ||||
static socklen_t srclen; | static socklen_t srclen; | ||||
static size_t datalen = DEFDATALEN; | static size_t datalen = DEFDATALEN; | ||||
static int s; /* socket file descriptor */ | static int ssend; /* send socket file descriptor */ | ||||
static int srecv; /* receive socket file descriptor */ | |||||
static u_char outpack[MAXPACKETLEN]; | static u_char outpack[MAXPACKETLEN]; | ||||
static char BSPACE = '\b'; /* characters written for flood */ | static char BSPACE = '\b'; /* characters written for flood */ | ||||
static char BBELL = '\a'; /* characters written for AUDIBLE */ | static char BBELL = '\a'; /* characters written for AUDIBLE */ | ||||
static char DOT = '.'; | static char DOT = '.'; | ||||
static char *hostname; | static char *hostname; | ||||
static int ident; /* process id to identify our packets */ | static int ident; /* process id to identify our packets */ | ||||
static u_int8_t nonce[8]; /* nonce field for node information */ | static u_int8_t nonce[8]; /* nonce field for node information */ | ||||
static int hoplimit = -1; /* hoplimit */ | static int hoplimit = -1; /* hoplimit */ | ||||
static u_char *packet = NULL; | static u_char *packet = NULL; | ||||
static cap_channel_t *capdns; | |||||
/* counters */ | /* counters */ | ||||
static long nmissedmax; /* max value of ntransmitted - nreceived - 1 */ | static long nmissedmax; /* max value of ntransmitted - nreceived - 1 */ | ||||
static long npackets; /* max packets to transmit */ | static long npackets; /* max packets to transmit */ | ||||
static long nreceived; /* # of packets we got back */ | static long nreceived; /* # of packets we got back */ | ||||
static long nrepeats; /* number of duplicates */ | static long nrepeats; /* number of duplicates */ | ||||
static long ntransmitted; /* sequence # for outbound packets = #sent */ | static long ntransmitted; /* sequence # for outbound packets = #sent */ | ||||
static int interval = 1000; /* interval between packets in ms */ | static int interval = 1000; /* interval between packets in ms */ | ||||
Show All 16 Lines | |||||
static char *scmsg = 0; | static char *scmsg = 0; | ||||
static volatile sig_atomic_t seenint; | static volatile sig_atomic_t seenint; | ||||
#ifdef SIGINFO | #ifdef SIGINFO | ||||
static volatile sig_atomic_t seeninfo; | static volatile sig_atomic_t seeninfo; | ||||
#endif | #endif | ||||
int main(int, char *[]); | int main(int, char *[]); | ||||
static cap_channel_t *capdns_setup(void); | |||||
static void fill(char *, char *); | static void fill(char *, char *); | ||||
static int get_hoplim(struct msghdr *); | static int get_hoplim(struct msghdr *); | ||||
static int get_pathmtu(struct msghdr *); | static int get_pathmtu(struct msghdr *); | ||||
static struct in6_pktinfo *get_rcvpktinfo(struct msghdr *); | static struct in6_pktinfo *get_rcvpktinfo(struct msghdr *); | ||||
static void onsignal(int); | static void onsignal(int); | ||||
static void onint(int); | static void onint(int); | ||||
static size_t pingerlen(void); | static size_t pingerlen(void); | ||||
static int pinger(void); | static int pinger(void); | ||||
▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | #ifdef IPSEC_POLICY_IPSEC | ||||
char *policy_out = NULL; | char *policy_out = NULL; | ||||
#endif | #endif | ||||
double t; | double t; | ||||
u_long alarmtimeout; | u_long alarmtimeout; | ||||
size_t rthlen; | size_t rthlen; | ||||
#ifdef IPV6_USE_MIN_MTU | #ifdef IPV6_USE_MIN_MTU | ||||
int mflag = 0; | int mflag = 0; | ||||
#endif | #endif | ||||
cap_rights_t rights_srecv; | |||||
cap_rights_t rights_ssend; | |||||
/* just to be sure */ | /* just to be sure */ | ||||
memset(&smsghdr, 0, sizeof(smsghdr)); | memset(&smsghdr, 0, sizeof(smsghdr)); | ||||
memset(&smsgiov, 0, sizeof(smsgiov)); | memset(&smsgiov, 0, sizeof(smsgiov)); | ||||
alarmtimeout = preload = 0; | alarmtimeout = preload = 0; | ||||
datap = &outpack[ICMP6ECHOLEN + ICMP6ECHOTMLEN]; | datap = &outpack[ICMP6ECHOLEN + ICMP6ECHOTMLEN]; | ||||
capdns = capdns_setup(); | |||||
#ifndef IPSEC | #ifndef IPSEC | ||||
#define ADDOPTS | #define ADDOPTS | ||||
#else | #else | ||||
#ifdef IPSEC_POLICY_IPSEC | #ifdef IPSEC_POLICY_IPSEC | ||||
#define ADDOPTS "P:" | #define ADDOPTS "P:" | ||||
#else | #else | ||||
#define ADDOPTS "AE" | #define ADDOPTS "AE" | ||||
#endif /*IPSEC_POLICY_IPSEC*/ | #endif /*IPSEC_POLICY_IPSEC*/ | ||||
▲ Show 20 Lines • Show All 162 Lines • ▼ Show 20 Lines | case 'R': | ||||
break; | break; | ||||
case 'S': | case 'S': | ||||
memset(&hints, 0, sizeof(struct addrinfo)); | memset(&hints, 0, sizeof(struct addrinfo)); | ||||
hints.ai_flags = AI_NUMERICHOST; /* allow hostname? */ | hints.ai_flags = AI_NUMERICHOST; /* allow hostname? */ | ||||
hints.ai_family = AF_INET6; | hints.ai_family = AF_INET6; | ||||
hints.ai_socktype = SOCK_RAW; | hints.ai_socktype = SOCK_RAW; | ||||
hints.ai_protocol = IPPROTO_ICMPV6; | hints.ai_protocol = IPPROTO_ICMPV6; | ||||
error = getaddrinfo(optarg, NULL, &hints, &res); | error = cap_getaddrinfo(capdns, optarg, NULL, &hints, &res); | ||||
if (error) { | if (error) { | ||||
errx(1, "invalid source address: %s", | errx(1, "invalid source address: %s", | ||||
gai_strerror(error)); | gai_strerror(error)); | ||||
} | } | ||||
/* | /* | ||||
* res->ai_family must be AF_INET6 and res->ai_addrlen | * res->ai_family must be AF_INET6 and res->ai_addrlen | ||||
* must be sizeof(src). | * must be sizeof(src). | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 99 Lines • ▼ Show 20 Lines | if (options & F_NIGROUP) { | ||||
target = nigroup(argv[argc - 1], nig_oldmcprefix); | target = nigroup(argv[argc - 1], nig_oldmcprefix); | ||||
if (target == NULL) { | if (target == NULL) { | ||||
usage(); | usage(); | ||||
/*NOTREACHED*/ | /*NOTREACHED*/ | ||||
} | } | ||||
} else | } else | ||||
target = argv[argc - 1]; | target = argv[argc - 1]; | ||||
/* getaddrinfo */ | /* cap_getaddrinfo */ | ||||
memset(&hints, 0, sizeof(struct addrinfo)); | memset(&hints, 0, sizeof(struct addrinfo)); | ||||
hints.ai_flags = AI_CANONNAME; | hints.ai_flags = AI_CANONNAME; | ||||
hints.ai_family = AF_INET6; | hints.ai_family = AF_INET6; | ||||
hints.ai_socktype = SOCK_RAW; | hints.ai_socktype = SOCK_RAW; | ||||
hints.ai_protocol = IPPROTO_ICMPV6; | hints.ai_protocol = IPPROTO_ICMPV6; | ||||
error = getaddrinfo(target, NULL, &hints, &res); | error = cap_getaddrinfo(capdns, target, NULL, &hints, &res); | ||||
if (error) | if (error) | ||||
errx(1, "%s", gai_strerror(error)); | errx(1, "%s", gai_strerror(error)); | ||||
if (res->ai_canonname) | if (res->ai_canonname) | ||||
hostname = strdup(res->ai_canonname); | hostname = strdup(res->ai_canonname); | ||||
else | else | ||||
hostname = target; | hostname = target; | ||||
if (!res->ai_addr) | if (!res->ai_addr) | ||||
errx(1, "getaddrinfo failed"); | errx(1, "cap_getaddrinfo failed"); | ||||
(void)memcpy(&dst, res->ai_addr, res->ai_addrlen); | (void)memcpy(&dst, res->ai_addr, res->ai_addrlen); | ||||
if ((s = socket(res->ai_family, res->ai_socktype, | if ((ssend = socket(res->ai_family, res->ai_socktype, | ||||
res->ai_protocol)) < 0) | res->ai_protocol)) < 0) | ||||
err(1, "socket"); | err(1, "socket ssend"); | ||||
if ((srecv = socket(res->ai_family, res->ai_socktype, | |||||
res->ai_protocol)) < 0) | |||||
err(1, "socket srecv"); | |||||
freeaddrinfo(res); | freeaddrinfo(res); | ||||
/* set the source address if specified. */ | /* set the source address if specified. */ | ||||
if ((options & F_SRCADDR) != 0) { | if ((options & F_SRCADDR) != 0) { | ||||
/* properly fill sin6_scope_id */ | /* properly fill sin6_scope_id */ | ||||
if (IN6_IS_ADDR_LINKLOCAL(&src.sin6_addr) && ( | if (IN6_IS_ADDR_LINKLOCAL(&src.sin6_addr) && ( | ||||
IN6_IS_ADDR_LINKLOCAL(&dst.sin6_addr) || | IN6_IS_ADDR_LINKLOCAL(&dst.sin6_addr) || | ||||
IN6_IS_ADDR_MC_LINKLOCAL(&dst.sin6_addr) || | IN6_IS_ADDR_MC_LINKLOCAL(&dst.sin6_addr) || | ||||
IN6_IS_ADDR_MC_NODELOCAL(&dst.sin6_addr))) { | IN6_IS_ADDR_MC_NODELOCAL(&dst.sin6_addr))) { | ||||
if (src.sin6_scope_id == 0) | if (src.sin6_scope_id == 0) | ||||
src.sin6_scope_id = dst.sin6_scope_id; | src.sin6_scope_id = dst.sin6_scope_id; | ||||
if (dst.sin6_scope_id == 0) | if (dst.sin6_scope_id == 0) | ||||
dst.sin6_scope_id = src.sin6_scope_id; | dst.sin6_scope_id = src.sin6_scope_id; | ||||
} | } | ||||
if (bind(s, (struct sockaddr *)&src, srclen) != 0) | if (bind(ssend, (struct sockaddr *)&src, srclen) != 0) | ||||
err(1, "bind"); | err(1, "bind"); | ||||
} | } | ||||
/* set the gateway (next hop) if specified */ | /* set the gateway (next hop) if specified */ | ||||
if (gateway) { | if (gateway) { | ||||
memset(&hints, 0, sizeof(hints)); | memset(&hints, 0, sizeof(hints)); | ||||
hints.ai_family = AF_INET6; | hints.ai_family = AF_INET6; | ||||
hints.ai_socktype = SOCK_RAW; | hints.ai_socktype = SOCK_RAW; | ||||
hints.ai_protocol = IPPROTO_ICMPV6; | hints.ai_protocol = IPPROTO_ICMPV6; | ||||
error = getaddrinfo(gateway, NULL, &hints, &res); | error = cap_getaddrinfo(capdns, gateway, NULL, &hints, &res); | ||||
if (error) { | if (error) { | ||||
errx(1, "getaddrinfo for the gateway %s: %s", | errx(1, "cap_getaddrinfo for the gateway %s: %s", | ||||
gateway, gai_strerror(error)); | gateway, gai_strerror(error)); | ||||
} | } | ||||
if (res->ai_next && (options & F_VERBOSE)) | if (res->ai_next && (options & F_VERBOSE)) | ||||
warnx("gateway resolves to multiple addresses"); | warnx("gateway resolves to multiple addresses"); | ||||
if (setsockopt(s, IPPROTO_IPV6, IPV6_NEXTHOP, | if (setsockopt(ssend, IPPROTO_IPV6, IPV6_NEXTHOP, | ||||
res->ai_addr, res->ai_addrlen)) { | res->ai_addr, res->ai_addrlen)) { | ||||
err(1, "setsockopt(IPV6_NEXTHOP)"); | err(1, "setsockopt(IPV6_NEXTHOP)"); | ||||
} | } | ||||
freeaddrinfo(res); | freeaddrinfo(res); | ||||
} | } | ||||
/* | /* | ||||
* let the kerel pass extension headers of incoming packets, | * let the kerel pass extension headers of incoming packets, | ||||
* for privileged socket options | * for privileged socket options | ||||
*/ | */ | ||||
if ((options & F_VERBOSE) != 0) { | if ((options & F_VERBOSE) != 0) { | ||||
int opton = 1; | int opton = 1; | ||||
#ifdef IPV6_RECVHOPOPTS | #ifdef IPV6_RECVHOPOPTS | ||||
if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVHOPOPTS, &opton, | if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RECVHOPOPTS, &opton, | ||||
sizeof(opton))) | sizeof(opton))) | ||||
err(1, "setsockopt(IPV6_RECVHOPOPTS)"); | err(1, "setsockopt(IPV6_RECVHOPOPTS)"); | ||||
#else /* old adv. API */ | #else /* old adv. API */ | ||||
if (setsockopt(s, IPPROTO_IPV6, IPV6_HOPOPTS, &opton, | if (setsockopt(srecv, IPPROTO_IPV6, IPV6_HOPOPTS, &opton, | ||||
sizeof(opton))) | sizeof(opton))) | ||||
err(1, "setsockopt(IPV6_HOPOPTS)"); | err(1, "setsockopt(IPV6_HOPOPTS)"); | ||||
#endif | #endif | ||||
#ifdef IPV6_RECVDSTOPTS | #ifdef IPV6_RECVDSTOPTS | ||||
if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVDSTOPTS, &opton, | if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RECVDSTOPTS, &opton, | ||||
sizeof(opton))) | sizeof(opton))) | ||||
err(1, "setsockopt(IPV6_RECVDSTOPTS)"); | err(1, "setsockopt(IPV6_RECVDSTOPTS)"); | ||||
#else /* old adv. API */ | #else /* old adv. API */ | ||||
if (setsockopt(s, IPPROTO_IPV6, IPV6_DSTOPTS, &opton, | if (setsockopt(srecv, IPPROTO_IPV6, IPV6_DSTOPTS, &opton, | ||||
sizeof(opton))) | sizeof(opton))) | ||||
err(1, "setsockopt(IPV6_DSTOPTS)"); | err(1, "setsockopt(IPV6_DSTOPTS)"); | ||||
#endif | #endif | ||||
#ifdef IPV6_RECVRTHDRDSTOPTS | #ifdef IPV6_RECVRTHDRDSTOPTS | ||||
if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVRTHDRDSTOPTS, &opton, | if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RECVRTHDRDSTOPTS, &opton, | ||||
sizeof(opton))) | sizeof(opton))) | ||||
err(1, "setsockopt(IPV6_RECVRTHDRDSTOPTS)"); | err(1, "setsockopt(IPV6_RECVRTHDRDSTOPTS)"); | ||||
#endif | #endif | ||||
} | } | ||||
/* revoke root privilege */ | /* revoke root privilege */ | ||||
if (seteuid(getuid()) != 0) | if (seteuid(getuid()) != 0) | ||||
err(1, "seteuid() failed"); | err(1, "seteuid() failed"); | ||||
Show All 26 Lines | #endif | ||||
if (!(options & F_PINGFILLED)) | if (!(options & F_PINGFILLED)) | ||||
for (i = ICMP6ECHOLEN; i < packlen; ++i) | for (i = ICMP6ECHOLEN; i < packlen; ++i) | ||||
*datap++ = i; | *datap++ = i; | ||||
ident = getpid() & 0xFFFF; | ident = getpid() & 0xFFFF; | ||||
arc4random_buf(nonce, sizeof(nonce)); | arc4random_buf(nonce, sizeof(nonce)); | ||||
optval = 1; | optval = 1; | ||||
if (options & F_DONTFRAG) | if (options & F_DONTFRAG) | ||||
if (setsockopt(s, IPPROTO_IPV6, IPV6_DONTFRAG, | if (setsockopt(ssend, IPPROTO_IPV6, IPV6_DONTFRAG, | ||||
&optval, sizeof(optval)) == -1) | &optval, sizeof(optval)) == -1) | ||||
err(1, "IPV6_DONTFRAG"); | err(1, "IPV6_DONTFRAG"); | ||||
hold = 1; | hold = 1; | ||||
if (options & F_SO_DEBUG) | if (options & F_SO_DEBUG) { | ||||
(void)setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&hold, | (void)setsockopt(ssend, SOL_SOCKET, SO_DEBUG, (char *)&hold, | ||||
sizeof(hold)); | sizeof(hold)); | ||||
(void)setsockopt(srecv, SOL_SOCKET, SO_DEBUG, (char *)&hold, | |||||
sizeof(hold)); | |||||
} | |||||
optval = IPV6_DEFHLIM; | optval = IPV6_DEFHLIM; | ||||
if (IN6_IS_ADDR_MULTICAST(&dst.sin6_addr)) | if (IN6_IS_ADDR_MULTICAST(&dst.sin6_addr)) | ||||
if (setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, | if (setsockopt(ssend, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, | ||||
&optval, sizeof(optval)) == -1) | &optval, sizeof(optval)) == -1) | ||||
err(1, "IPV6_MULTICAST_HOPS"); | err(1, "IPV6_MULTICAST_HOPS"); | ||||
#ifdef IPV6_USE_MIN_MTU | #ifdef IPV6_USE_MIN_MTU | ||||
if (mflag != 1) { | if (mflag != 1) { | ||||
optval = mflag > 1 ? 0 : 1; | optval = mflag > 1 ? 0 : 1; | ||||
if (setsockopt(s, IPPROTO_IPV6, IPV6_USE_MIN_MTU, | if (setsockopt(ssend, IPPROTO_IPV6, IPV6_USE_MIN_MTU, | ||||
&optval, sizeof(optval)) == -1) | &optval, sizeof(optval)) == -1) | ||||
err(1, "setsockopt(IPV6_USE_MIN_MTU)"); | err(1, "setsockopt(IPV6_USE_MIN_MTU)"); | ||||
} | } | ||||
#ifdef IPV6_RECVPATHMTU | #ifdef IPV6_RECVPATHMTU | ||||
else { | else { | ||||
optval = 1; | optval = 1; | ||||
if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVPATHMTU, | if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RECVPATHMTU, | ||||
&optval, sizeof(optval)) == -1) | &optval, sizeof(optval)) == -1) | ||||
err(1, "setsockopt(IPV6_RECVPATHMTU)"); | err(1, "setsockopt(IPV6_RECVPATHMTU)"); | ||||
} | } | ||||
#endif /* IPV6_RECVPATHMTU */ | #endif /* IPV6_RECVPATHMTU */ | ||||
#endif /* IPV6_USE_MIN_MTU */ | #endif /* IPV6_USE_MIN_MTU */ | ||||
#ifdef IPSEC | #ifdef IPSEC | ||||
#ifdef IPSEC_POLICY_IPSEC | #ifdef IPSEC_POLICY_IPSEC | ||||
if (options & F_POLICY) { | if (options & F_POLICY) { | ||||
if (setpolicy(s, policy_in) < 0) | if (setpolicy(srecv, policy_in) < 0) | ||||
errx(1, "%s", ipsec_strerror()); | errx(1, "%s", ipsec_strerror()); | ||||
if (setpolicy(s, policy_out) < 0) | if (setpolicy(ssend, policy_out) < 0) | ||||
errx(1, "%s", ipsec_strerror()); | errx(1, "%s", ipsec_strerror()); | ||||
} | } | ||||
#else | #else | ||||
if (options & F_AUTHHDR) { | if (options & F_AUTHHDR) { | ||||
optval = IPSEC_LEVEL_REQUIRE; | optval = IPSEC_LEVEL_REQUIRE; | ||||
#ifdef IPV6_AUTH_TRANS_LEVEL | #ifdef IPV6_AUTH_TRANS_LEVEL | ||||
if (setsockopt(s, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL, | if (setsockopt(ssend, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL, | ||||
&optval, sizeof(optval)) == -1) | &optval, sizeof(optval)) == -1) | ||||
err(1, "setsockopt(IPV6_AUTH_TRANS_LEVEL)"); | err(1, "setsockopt(IPV6_AUTH_TRANS_LEVEL)"); | ||||
if (setsockopt(srecv, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL, | |||||
&optval, sizeof(optval)) == -1) | |||||
err(1, "setsockopt(IPV6_AUTH_TRANS_LEVEL)"); | |||||
#else /* old def */ | #else /* old def */ | ||||
if (setsockopt(s, IPPROTO_IPV6, IPV6_AUTH_LEVEL, | if (setsockopt(ssend, IPPROTO_IPV6, IPV6_AUTH_LEVEL, | ||||
&optval, sizeof(optval)) == -1) | &optval, sizeof(optval)) == -1) | ||||
err(1, "setsockopt(IPV6_AUTH_LEVEL)"); | err(1, "setsockopt(IPV6_AUTH_LEVEL)"); | ||||
if (setsockopt(srecv, IPPROTO_IPV6, IPV6_AUTH_LEVEL, | |||||
&optval, sizeof(optval)) == -1) | |||||
err(1, "setsockopt(IPV6_AUTH_LEVEL)"); | |||||
#endif | #endif | ||||
} | } | ||||
if (options & F_ENCRYPT) { | if (options & F_ENCRYPT) { | ||||
optval = IPSEC_LEVEL_REQUIRE; | optval = IPSEC_LEVEL_REQUIRE; | ||||
if (setsockopt(s, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL, | if (setsockopt(ssend, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL, | ||||
&optval, sizeof(optval)) == -1) | &optval, sizeof(optval)) == -1) | ||||
err(1, "setsockopt(IPV6_ESP_TRANS_LEVEL)"); | err(1, "setsockopt(IPV6_ESP_TRANS_LEVEL)"); | ||||
if (setsockopt(srecv, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL, | |||||
&optval, sizeof(optval)) == -1) | |||||
err(1, "setsockopt(IPV6_ESP_TRANS_LEVEL)"); | |||||
} | } | ||||
#endif /*IPSEC_POLICY_IPSEC*/ | #endif /*IPSEC_POLICY_IPSEC*/ | ||||
#endif | #endif | ||||
#ifdef ICMP6_FILTER | #ifdef ICMP6_FILTER | ||||
{ | { | ||||
struct icmp6_filter filt; | struct icmp6_filter filt; | ||||
if (!(options & F_VERBOSE)) { | if (!(options & F_VERBOSE)) { | ||||
ICMP6_FILTER_SETBLOCKALL(&filt); | ICMP6_FILTER_SETBLOCKALL(&filt); | ||||
if ((options & F_FQDN) || (options & F_FQDNOLD) || | if ((options & F_FQDN) || (options & F_FQDNOLD) || | ||||
(options & F_NODEADDR) || (options & F_SUPTYPES)) | (options & F_NODEADDR) || (options & F_SUPTYPES)) | ||||
ICMP6_FILTER_SETPASS(ICMP6_NI_REPLY, &filt); | ICMP6_FILTER_SETPASS(ICMP6_NI_REPLY, &filt); | ||||
else | else | ||||
ICMP6_FILTER_SETPASS(ICMP6_ECHO_REPLY, &filt); | ICMP6_FILTER_SETPASS(ICMP6_ECHO_REPLY, &filt); | ||||
} else { | } else { | ||||
ICMP6_FILTER_SETPASSALL(&filt); | ICMP6_FILTER_SETPASSALL(&filt); | ||||
} | } | ||||
if (setsockopt(s, IPPROTO_ICMPV6, ICMP6_FILTER, &filt, | if (setsockopt(srecv, IPPROTO_ICMPV6, ICMP6_FILTER, &filt, | ||||
sizeof(filt)) < 0) | sizeof(filt)) < 0) | ||||
err(1, "setsockopt(ICMP6_FILTER)"); | err(1, "setsockopt(ICMP6_FILTER)"); | ||||
} | } | ||||
#endif /*ICMP6_FILTER*/ | #endif /*ICMP6_FILTER*/ | ||||
/* let the kerel pass extension headers of incoming packets */ | /* let the kerel pass extension headers of incoming packets */ | ||||
if ((options & F_VERBOSE) != 0) { | if ((options & F_VERBOSE) != 0) { | ||||
int opton = 1; | int opton = 1; | ||||
#ifdef IPV6_RECVRTHDR | #ifdef IPV6_RECVRTHDR | ||||
if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVRTHDR, &opton, | if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RECVRTHDR, &opton, | ||||
sizeof(opton))) | sizeof(opton))) | ||||
err(1, "setsockopt(IPV6_RECVRTHDR)"); | err(1, "setsockopt(IPV6_RECVRTHDR)"); | ||||
#else /* old adv. API */ | #else /* old adv. API */ | ||||
if (setsockopt(s, IPPROTO_IPV6, IPV6_RTHDR, &opton, | if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RTHDR, &opton, | ||||
sizeof(opton))) | sizeof(opton))) | ||||
err(1, "setsockopt(IPV6_RTHDR)"); | err(1, "setsockopt(IPV6_RTHDR)"); | ||||
#endif | #endif | ||||
} | } | ||||
/* | /* | ||||
optval = 1; | optval = 1; | ||||
if (IN6_IS_ADDR_MULTICAST(&dst.sin6_addr)) | if (IN6_IS_ADDR_MULTICAST(&dst.sin6_addr)) | ||||
if (setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, | if (setsockopt(ssend, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, | ||||
&optval, sizeof(optval)) == -1) | &optval, sizeof(optval)) == -1) | ||||
err(1, "IPV6_MULTICAST_LOOP"); | err(1, "IPV6_MULTICAST_LOOP"); | ||||
*/ | */ | ||||
/* Specify the outgoing interface and/or the source address */ | /* Specify the outgoing interface and/or the source address */ | ||||
if (usepktinfo) | if (usepktinfo) | ||||
ip6optlen += CMSG_SPACE(sizeof(struct in6_pktinfo)); | ip6optlen += CMSG_SPACE(sizeof(struct in6_pktinfo)); | ||||
▲ Show 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | if ((scmsgp = (struct cmsghdr *)inet6_rthdr_init(scmsgp, | ||||
IPV6_RTHDR_TYPE_0)) == NULL) | IPV6_RTHDR_TYPE_0)) == NULL) | ||||
errx(1, "can't initialize rthdr"); | errx(1, "can't initialize rthdr"); | ||||
#endif /* USE_RFC2292BIS */ | #endif /* USE_RFC2292BIS */ | ||||
for (hops = 0; hops < argc - 1; hops++) { | for (hops = 0; hops < argc - 1; hops++) { | ||||
memset(&hints, 0, sizeof(hints)); | memset(&hints, 0, sizeof(hints)); | ||||
hints.ai_family = AF_INET6; | hints.ai_family = AF_INET6; | ||||
if ((error = getaddrinfo(argv[hops], NULL, &hints, | if ((error = cap_getaddrinfo(capdns, argv[hops], NULL, &hints, | ||||
&res))) | &res))) | ||||
errx(1, "%s", gai_strerror(error)); | errx(1, "%s", gai_strerror(error)); | ||||
if (res->ai_addr->sa_family != AF_INET6) | if (res->ai_addr->sa_family != AF_INET6) | ||||
errx(1, | errx(1, | ||||
"bad addr family of an intermediate addr"); | "bad addr family of an intermediate addr"); | ||||
sin6 = (struct sockaddr_in6 *)(void *)res->ai_addr; | sin6 = (struct sockaddr_in6 *)(void *)res->ai_addr; | ||||
#ifdef USE_RFC2292BIS | #ifdef USE_RFC2292BIS | ||||
if (inet6_rth_add(rthdr, &sin6->sin6_addr)) | if (inet6_rth_add(rthdr, &sin6->sin6_addr)) | ||||
Show All 9 Lines | |||||
#ifndef USE_RFC2292BIS | #ifndef USE_RFC2292BIS | ||||
if (inet6_rthdr_lasthop(scmsgp, IPV6_RTHDR_LOOSE)) | if (inet6_rthdr_lasthop(scmsgp, IPV6_RTHDR_LOOSE)) | ||||
errx(1, "can't set the last flag"); | errx(1, "can't set the last flag"); | ||||
#endif | #endif | ||||
scmsgp = CMSG_NXTHDR(&smsghdr, scmsgp); | scmsgp = CMSG_NXTHDR(&smsghdr, scmsgp); | ||||
} | } | ||||
/* From now on we will use only reverse DNS lookups. */ | |||||
if (capdns != NULL) { | |||||
const char *types[1]; | |||||
types[0] = "ADDR2NAME"; | |||||
if (cap_dns_type_limit(capdns, types, 1) < 0) | |||||
oshogbo: We may use nitems. | |||||
jansucanUnsubmitted Not Done Inline ActionsFixed. jansucan: Fixed. | |||||
err(1, "unable to limit access to system.dns service"); | |||||
} | |||||
if (!(options & F_SRCADDR)) { | if (!(options & F_SRCADDR)) { | ||||
/* | /* | ||||
* get the source address. XXX since we revoked the root | * get the source address. XXX since we revoked the root | ||||
* privilege, we cannot use a raw socket for this. | * privilege, we cannot use a raw socket for this. | ||||
*/ | */ | ||||
int dummy; | int dummy; | ||||
socklen_t len = sizeof(src); | socklen_t len = sizeof(src); | ||||
Show All 36 Lines | if (connect(dummy, (struct sockaddr *)&src, len) < 0) | ||||
err(1, "UDP connect"); | err(1, "UDP connect"); | ||||
if (getsockname(dummy, (struct sockaddr *)&src, &len) < 0) | if (getsockname(dummy, (struct sockaddr *)&src, &len) < 0) | ||||
err(1, "getsockname"); | err(1, "getsockname"); | ||||
close(dummy); | close(dummy); | ||||
} | } | ||||
if (connect(ssend, (struct sockaddr *)&dst, sizeof(dst)) != 0) | |||||
err(1, "connect() ssend"); | |||||
oshogboUnsubmitted Not Done Inline ActionsCan we limit stdio as well? oshogbo: Can we limit stdio as well? | |||||
jansucanUnsubmitted Not Done Inline ActionsLike this? cap_rights_init(&rights_stdio, CAP_WRITE); if (caph_rights_limit(STDOUT_FILENO, &rights_stdio) < 0) err(1, "cap_rights_limit stdout"); if (caph_rights_limit(STDERR_FILENO, &rights_stdio) < 0) err(1, "cap_rights_limit stderr"); cap_rights_clear(&rights_stdio, CAP_WRITE); if (caph_rights_limit(STDIN_FILENO, &rights_stdio) < 0) err(1, "cap_rights_limit stdin"); jansucan: Like this?
```
cap_rights_init(&rights_stdio, CAP_WRITE);
if (caph_rights_limit… | |||||
markjUnsubmitted Not Done Inline ActionsThe caph_limit_stdio() helper can be used instead. It looks like IPv4 ping is missing this as well. markj: The caph_limit_stdio() helper can be used instead.
It looks like IPv4 ping is missing this as… | |||||
jansucanUnsubmitted Not Done Inline Actionscaph_limit_stdio() keeps CAP_READ for stdin. I will use caph_limit_stdout() and caph_limit_stderr() for the other stdio descriptors. jansucan: caph_limit_stdio() keeps CAP_READ for stdin. I will use caph_limit_stdout() and… | |||||
caph_cache_catpages(); | |||||
if (caph_enter_casper() < 0) | |||||
err(1, "caph_enter_casper"); | |||||
cap_rights_init(&rights_srecv, CAP_RECV, CAP_EVENT, CAP_SETSOCKOPT); | |||||
if (caph_rights_limit(srecv, &rights_srecv) < 0) | |||||
err(1, "cap_rights_limit srecv"); | |||||
cap_rights_init(&rights_ssend, CAP_SEND, CAP_SETSOCKOPT); | |||||
if (caph_rights_limit(ssend, &rights_ssend) < 0) | |||||
err(1, "cap_rights_limit ssend"); | |||||
#if defined(SO_SNDBUF) && defined(SO_RCVBUF) | #if defined(SO_SNDBUF) && defined(SO_RCVBUF) | ||||
if (sockbufsize) { | if (sockbufsize) { | ||||
if (datalen > (size_t)sockbufsize) | if (datalen > (size_t)sockbufsize) | ||||
warnx("you need -b to increase socket buffer size"); | warnx("you need -b to increase socket buffer size"); | ||||
if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &sockbufsize, | if (setsockopt(ssend, SOL_SOCKET, SO_SNDBUF, &sockbufsize, | ||||
sizeof(sockbufsize)) < 0) | sizeof(sockbufsize)) < 0) | ||||
err(1, "setsockopt(SO_SNDBUF)"); | err(1, "setsockopt(SO_SNDBUF)"); | ||||
if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &sockbufsize, | if (setsockopt(srecv, SOL_SOCKET, SO_RCVBUF, &sockbufsize, | ||||
sizeof(sockbufsize)) < 0) | sizeof(sockbufsize)) < 0) | ||||
err(1, "setsockopt(SO_RCVBUF)"); | err(1, "setsockopt(SO_RCVBUF)"); | ||||
} | } | ||||
else { | else { | ||||
if (datalen > 8 * 1024) /*XXX*/ | if (datalen > 8 * 1024) /*XXX*/ | ||||
warnx("you need -b to increase socket buffer size"); | warnx("you need -b to increase socket buffer size"); | ||||
/* | /* | ||||
* When pinging the broadcast address, you can get a lot of | * When pinging the broadcast address, you can get a lot of | ||||
* answers. Doing something so evil is useful if you are trying | * answers. Doing something so evil is useful if you are trying | ||||
* to stress the ethernet, or just want to fill the arp cache | * to stress the ethernet, or just want to fill the arp cache | ||||
* to get some stuff for /etc/ethers. | * to get some stuff for /etc/ethers. | ||||
*/ | */ | ||||
hold = 48 * 1024; | hold = 48 * 1024; | ||||
setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&hold, | setsockopt(srecv, SOL_SOCKET, SO_RCVBUF, (char *)&hold, | ||||
sizeof(hold)); | sizeof(hold)); | ||||
} | } | ||||
#endif | #endif | ||||
optval = 1; | optval = 1; | ||||
#ifndef USE_SIN6_SCOPE_ID | #ifndef USE_SIN6_SCOPE_ID | ||||
#ifdef IPV6_RECVPKTINFO | #ifdef IPV6_RECVPKTINFO | ||||
if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVPKTINFO, &optval, | if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RECVPKTINFO, &optval, | ||||
sizeof(optval)) < 0) | sizeof(optval)) < 0) | ||||
warn("setsockopt(IPV6_RECVPKTINFO)"); /* XXX err? */ | warn("setsockopt(IPV6_RECVPKTINFO)"); /* XXX err? */ | ||||
#else /* old adv. API */ | #else /* old adv. API */ | ||||
if (setsockopt(s, IPPROTO_IPV6, IPV6_PKTINFO, &optval, | if (setsockopt(srecv, IPPROTO_IPV6, IPV6_PKTINFO, &optval, | ||||
sizeof(optval)) < 0) | sizeof(optval)) < 0) | ||||
warn("setsockopt(IPV6_PKTINFO)"); /* XXX err? */ | warn("setsockopt(IPV6_PKTINFO)"); /* XXX err? */ | ||||
#endif | #endif | ||||
#endif /* USE_SIN6_SCOPE_ID */ | #endif /* USE_SIN6_SCOPE_ID */ | ||||
#ifdef IPV6_RECVHOPLIMIT | #ifdef IPV6_RECVHOPLIMIT | ||||
if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &optval, | if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &optval, | ||||
sizeof(optval)) < 0) | sizeof(optval)) < 0) | ||||
warn("setsockopt(IPV6_RECVHOPLIMIT)"); /* XXX err? */ | warn("setsockopt(IPV6_RECVHOPLIMIT)"); /* XXX err? */ | ||||
#else /* old adv. API */ | #else /* old adv. API */ | ||||
if (setsockopt(s, IPPROTO_IPV6, IPV6_HOPLIMIT, &optval, | if (setsockopt(srecv, IPPROTO_IPV6, IPV6_HOPLIMIT, &optval, | ||||
sizeof(optval)) < 0) | sizeof(optval)) < 0) | ||||
warn("setsockopt(IPV6_HOPLIMIT)"); /* XXX err? */ | warn("setsockopt(IPV6_HOPLIMIT)"); /* XXX err? */ | ||||
#endif | #endif | ||||
cap_rights_clear(&rights_srecv, CAP_SETSOCKOPT); | |||||
if (caph_rights_limit(srecv, &rights_srecv) < 0) | |||||
err(1, "cap_rights_limit srecv setsockopt"); | |||||
cap_rights_clear(&rights_ssend, CAP_SETSOCKOPT); | |||||
if (caph_rights_limit(ssend, &rights_ssend) < 0) | |||||
err(1, "cap_rights_limit ssend setsockopt"); | |||||
Not Done Inline ActionsRather than duplicating the lists of rights, you can define two separate cap_rights_t sets, one for each socket, and use cap_rights_clear() to remove CAP_SETSOCKOPT before further limiting rights on those sockets. markj: Rather than duplicating the lists of rights, you can define two separate cap_rights_t sets, one… | |||||
Not Done Inline ActionsThanks. It has been implemented. jansucan: Thanks. It has been implemented. | |||||
printf("PING6(%lu=40+8+%lu bytes) ", (unsigned long)(40 + pingerlen()), | printf("PING6(%lu=40+8+%lu bytes) ", (unsigned long)(40 + pingerlen()), | ||||
(unsigned long)(pingerlen() - 8)); | (unsigned long)(pingerlen() - 8)); | ||||
printf("%s --> ", pr_addr((struct sockaddr *)&src, sizeof(src))); | printf("%s --> ", pr_addr((struct sockaddr *)&src, sizeof(src))); | ||||
printf("%s\n", pr_addr((struct sockaddr *)&dst, sizeof(dst))); | printf("%s\n", pr_addr((struct sockaddr *)&dst, sizeof(dst))); | ||||
if (preload == 0) | if (preload == 0) | ||||
pinger(); | pinger(); | ||||
else { | else { | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | |||||
#ifdef SIGINFO | #ifdef SIGINFO | ||||
if (seeninfo) { | if (seeninfo) { | ||||
summary(); | summary(); | ||||
seeninfo = 0; | seeninfo = 0; | ||||
continue; | continue; | ||||
} | } | ||||
#endif | #endif | ||||
FD_ZERO(&rfds); | FD_ZERO(&rfds); | ||||
FD_SET(s, &rfds); | FD_SET(srecv, &rfds); | ||||
gettimeofday(&now, NULL); | gettimeofday(&now, NULL); | ||||
timeout.tv_sec = last.tv_sec + intvl.tv_sec - now.tv_sec; | timeout.tv_sec = last.tv_sec + intvl.tv_sec - now.tv_sec; | ||||
timeout.tv_usec = last.tv_usec + intvl.tv_usec - now.tv_usec; | timeout.tv_usec = last.tv_usec + intvl.tv_usec - now.tv_usec; | ||||
while (timeout.tv_usec < 0) { | while (timeout.tv_usec < 0) { | ||||
timeout.tv_usec += 1000000; | timeout.tv_usec += 1000000; | ||||
timeout.tv_sec--; | timeout.tv_sec--; | ||||
} | } | ||||
while (timeout.tv_usec > 1000000) { | while (timeout.tv_usec > 1000000) { | ||||
timeout.tv_usec -= 1000000; | timeout.tv_usec -= 1000000; | ||||
timeout.tv_sec++; | timeout.tv_sec++; | ||||
} | } | ||||
if (timeout.tv_sec < 0) | if (timeout.tv_sec < 0) | ||||
timeout.tv_sec = timeout.tv_usec = 0; | timeout.tv_sec = timeout.tv_usec = 0; | ||||
n = select(s + 1, &rfds, NULL, NULL, &timeout); | n = select(srecv + 1, &rfds, NULL, NULL, &timeout); | ||||
if (n < 0) | if (n < 0) | ||||
continue; /* EINTR */ | continue; /* EINTR */ | ||||
if (n == 1) { | if (n == 1) { | ||||
m.msg_name = (caddr_t)&from; | m.msg_name = (caddr_t)&from; | ||||
m.msg_namelen = sizeof(from); | m.msg_namelen = sizeof(from); | ||||
memset(&iov, 0, sizeof(iov)); | memset(&iov, 0, sizeof(iov)); | ||||
iov[0].iov_base = (caddr_t)packet; | iov[0].iov_base = (caddr_t)packet; | ||||
iov[0].iov_len = packlen; | iov[0].iov_len = packlen; | ||||
m.msg_iov = iov; | m.msg_iov = iov; | ||||
m.msg_iovlen = 1; | m.msg_iovlen = 1; | ||||
memset(cm, 0, CONTROLLEN); | memset(cm, 0, CONTROLLEN); | ||||
m.msg_control = (void *)cm; | m.msg_control = (void *)cm; | ||||
m.msg_controllen = CONTROLLEN; | m.msg_controllen = CONTROLLEN; | ||||
cc = recvmsg(s, &m, 0); | cc = recvmsg(srecv, &m, 0); | ||||
if (cc < 0) { | if (cc < 0) { | ||||
if (errno != EINTR) { | if (errno != EINTR) { | ||||
warn("recvmsg"); | warn("recvmsg"); | ||||
sleep(1); | sleep(1); | ||||
} | } | ||||
continue; | continue; | ||||
} else if (cc == 0) { | } else if (cc == 0) { | ||||
int mtu; | int mtu; | ||||
▲ Show 20 Lines • Show All 197 Lines • ▼ Show 20 Lines | if (options & F_FQDN) { | ||||
cc = ICMP6ECHOLEN + datalen; | cc = ICMP6ECHOLEN + datalen; | ||||
} | } | ||||
#ifdef DIAGNOSTIC | #ifdef DIAGNOSTIC | ||||
if (pingerlen() != cc) | if (pingerlen() != cc) | ||||
errx(1, "internal error; length mismatch"); | errx(1, "internal error; length mismatch"); | ||||
#endif | #endif | ||||
smsghdr.msg_name = (caddr_t)&dst; | |||||
smsghdr.msg_namelen = sizeof(dst); | |||||
memset(&iov, 0, sizeof(iov)); | memset(&iov, 0, sizeof(iov)); | ||||
iov[0].iov_base = (caddr_t)outpack; | iov[0].iov_base = (caddr_t)outpack; | ||||
iov[0].iov_len = cc; | iov[0].iov_len = cc; | ||||
smsghdr.msg_iov = iov; | smsghdr.msg_iov = iov; | ||||
smsghdr.msg_iovlen = 1; | smsghdr.msg_iovlen = 1; | ||||
i = sendmsg(s, &smsghdr, 0); | i = sendmsg(ssend, &smsghdr, 0); | ||||
if (i < 0 || i != cc) { | if (i < 0 || i != cc) { | ||||
if (i < 0) | if (i < 0) | ||||
warn("sendmsg"); | warn("sendmsg"); | ||||
(void)printf("ping6: wrote %s %d chars, ret=%d\n", | (void)printf("ping6: wrote %s %d chars, ret=%d\n", | ||||
hostname, cc, i); | hostname, cc, i); | ||||
} | } | ||||
if (!(options & F_QUIET) && options & F_FLOOD) | if (!(options & F_QUIET) && options & F_FLOOD) | ||||
▲ Show 20 Lines • Show All 386 Lines • ▼ Show 20 Lines | pr_exthdrs(struct msghdr *mhdr) | ||||
bufp = mhdr->msg_control; | bufp = mhdr->msg_control; | ||||
for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm; | for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm; | ||||
cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) { | cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) { | ||||
if (cm->cmsg_level != IPPROTO_IPV6) | if (cm->cmsg_level != IPPROTO_IPV6) | ||||
continue; | continue; | ||||
bufsize = CONTROLLEN - ((caddr_t)CMSG_DATA(cm) - (caddr_t)bufp); | bufsize = CONTROLLEN - ((caddr_t)CMSG_DATA(cm) - (caddr_t)bufp); | ||||
if (bufsize <= 0) | if (bufsize <= 0) | ||||
continue; | continue; | ||||
Not Done Inline ActionsWhitespace change. markj: Whitespace change. | |||||
Not Done Inline ActionsThe change has been excluded. jansucan: The change has been excluded. | |||||
switch (cm->cmsg_type) { | switch (cm->cmsg_type) { | ||||
case IPV6_HOPOPTS: | case IPV6_HOPOPTS: | ||||
printf(" HbH Options: "); | printf(" HbH Options: "); | ||||
pr_ip6opt(CMSG_DATA(cm), (size_t)bufsize); | pr_ip6opt(CMSG_DATA(cm), (size_t)bufsize); | ||||
break; | break; | ||||
case IPV6_DSTOPTS: | case IPV6_DSTOPTS: | ||||
#ifdef IPV6_RTHDRDSTOPTS | #ifdef IPV6_RTHDRDSTOPTS | ||||
case IPV6_RTHDRDSTOPTS: | case IPV6_RTHDRDSTOPTS: | ||||
▲ Show 20 Lines • Show All 765 Lines • ▼ Show 20 Lines | |||||
pr_addr(struct sockaddr *addr, int addrlen) | pr_addr(struct sockaddr *addr, int addrlen) | ||||
{ | { | ||||
static char buf[NI_MAXHOST]; | static char buf[NI_MAXHOST]; | ||||
int flag = 0; | int flag = 0; | ||||
if ((options & F_HOSTNAME) == 0) | if ((options & F_HOSTNAME) == 0) | ||||
flag |= NI_NUMERICHOST; | flag |= NI_NUMERICHOST; | ||||
if (getnameinfo(addr, addrlen, buf, sizeof(buf), NULL, 0, flag) == 0) | if (cap_getnameinfo(capdns, addr, addrlen, buf, sizeof(buf), NULL, 0, | ||||
flag) == 0) | |||||
Not Done Inline ActionsThis line should be wrapped to 80 columns. markj: This line should be wrapped to 80 columns. | |||||
Not Done Inline ActionsFixed. jansucan: Fixed. | |||||
return (buf); | return (buf); | ||||
else | else | ||||
return "?"; | return "?"; | ||||
} | } | ||||
/* | /* | ||||
* pr_retip -- | * pr_retip -- | ||||
* Dump some info on a returned (via ICMPv6) IPv6 packet. | * Dump some info on a returned (via ICMPv6) IPv6 packet. | ||||
▲ Show 20 Lines • Show All 117 Lines • ▼ Show 20 Lines | setpolicy(int so __unused, char *policy) | ||||
char *buf; | char *buf; | ||||
if (policy == NULL) | if (policy == NULL) | ||||
return 0; /* ignore */ | return 0; /* ignore */ | ||||
buf = ipsec_set_policy(policy, strlen(policy)); | buf = ipsec_set_policy(policy, strlen(policy)); | ||||
if (buf == NULL) | if (buf == NULL) | ||||
errx(1, "%s", ipsec_strerror()); | errx(1, "%s", ipsec_strerror()); | ||||
if (setsockopt(s, IPPROTO_IPV6, IPV6_IPSEC_POLICY, buf, | if (setsockopt(ssend, IPPROTO_IPV6, IPV6_IPSEC_POLICY, buf, | ||||
ipsec_get_policylen(buf)) < 0) | ipsec_get_policylen(buf)) < 0) | ||||
warnx("Unable to set IPsec policy"); | warnx("Unable to set IPsec policy"); | ||||
free(buf); | free(buf); | ||||
return 0; | return 0; | ||||
} | } | ||||
#endif | #endif | ||||
#endif | #endif | ||||
Show All 37 Lines | if (nig_oldmcprefix) { | ||||
/* draft-ietf-ipngwg-icmp-name-lookup */ | /* draft-ietf-ipngwg-icmp-name-lookup */ | ||||
valid = inet_pton(AF_INET6, "ff02::2:0000:0000", &in6); | valid = inet_pton(AF_INET6, "ff02::2:0000:0000", &in6); | ||||
} else { | } else { | ||||
/* RFC 4620 */ | /* RFC 4620 */ | ||||
valid = inet_pton(AF_INET6, "ff02::2:ff00:0000", &in6); | valid = inet_pton(AF_INET6, "ff02::2:ff00:0000", &in6); | ||||
} | } | ||||
if (valid != 1) | if (valid != 1) | ||||
return NULL; /*XXX*/ | return NULL; /*XXX*/ | ||||
Not Done Inline ActionsWhitespace change. markj: Whitespace change. | |||||
Not Done Inline ActionsThe change has been excluded. jansucan: The change has been excluded. | |||||
if (nig_oldmcprefix) { | if (nig_oldmcprefix) { | ||||
/* draft-ietf-ipngwg-icmp-name-lookup */ | /* draft-ietf-ipngwg-icmp-name-lookup */ | ||||
bcopy(digest, &in6.s6_addr[12], 4); | bcopy(digest, &in6.s6_addr[12], 4); | ||||
} else { | } else { | ||||
/* RFC 4620 */ | /* RFC 4620 */ | ||||
bcopy(digest, &in6.s6_addr[13], 3); | bcopy(digest, &in6.s6_addr[13], 3); | ||||
} | } | ||||
Show All 25 Lines | |||||
#if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) | #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) | ||||
" [-P policy]" | " [-P policy]" | ||||
#endif | #endif | ||||
"\n" | "\n" | ||||
" [-p pattern] [-S sourceaddr] [-s packetsize] " | " [-p pattern] [-S sourceaddr] [-s packetsize] " | ||||
"[-x waittime]\n" | "[-x waittime]\n" | ||||
" [-X timeout] [hops ...] host\n"); | " [-X timeout] [hops ...] host\n"); | ||||
exit(1); | exit(1); | ||||
} | |||||
static cap_channel_t * | |||||
oshogboUnsubmitted Not Done Inline ActionsIf it's initializing global struct, maybe this function should just do that? oshogbo: If it's initializing global struct, maybe this function should just do that? | |||||
jansucanUnsubmitted Not Done Inline ActionsI'm not sure if I understand. Do you mean that the return value should be changed to void and the function should set the global variable directly? jansucan: I'm not sure if I understand. Do you mean that the return value should be changed to `void` and… | |||||
capdns_setup(void) | |||||
{ | |||||
cap_channel_t *capcas, *capdnsloc; | |||||
const char *types[2]; | |||||
int families[1]; | |||||
capcas = cap_init(); | |||||
if (capcas == NULL) | |||||
err(1, "unable to create casper process"); | |||||
capdnsloc = cap_service_open(capcas, "system.dns"); | |||||
/* Casper capability no longer needed. */ | |||||
cap_close(capcas); | |||||
if (capdnsloc == NULL) | |||||
err(1, "unable to open system.dns service"); | |||||
types[0] = "NAME2ADDR"; | |||||
types[1] = "ADDR2NAME"; | |||||
if (cap_dns_type_limit(capdnsloc, types, 2) < 0) | |||||
oshogboUnsubmitted Not Done Inline ActionsYou can use nitems I guess. oshogbo: You can use nitems I guess. | |||||
jansucanUnsubmitted Not Done Inline ActionsFixed. jansucan: Fixed. | |||||
err(1, "unable to limit access to system.dns service"); | |||||
families[0] = AF_INET6; | |||||
if (cap_dns_family_limit(capdnsloc, families, 1) < 0) | |||||
oshogboUnsubmitted Not Done Inline ActionsSame here. oshogbo: Same here. | |||||
jansucanUnsubmitted Not Done Inline ActionsFixed. jansucan: Fixed. | |||||
err(1, "unable to limit access to system.dns service"); | |||||
return (capdnsloc); | |||||
} | } |
We may use nitems.