/*
- * Copyright (c) 2009-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2009-2018 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
Perror("ioctl(SIOCSECNMODE)");
}
+void
+setprobeconnectivity(const char *vname, int value, int s, const struct afswtch *afp)
+{
+ strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+ ifr.ifr_ifru.ifru_probe_connectivity = value;
+
+ if (ioctl(s, SIOCSIFPROBECONNECTIVITY, (caddr_t)&ifr) < 0)
+ Perror(vname);
+}
+
#if defined(SIOCSQOSMARKINGMODE) && defined(SIOCSQOSMARKINGENABLED)
void
"\20MULTICAST"
#define IFEFBITS \
-"\020\1AUTOCONFIGURING\5FASTLN_CAP\6IPV6_DISABLED\7ACCEPT_RTADV\10TXSTART\11RXPOLL" \
+"\020\1AUTOCONFIGURING\4PROBE_CONNECTIVITY\5FASTLN_CAP\6IPV6_DISABLED\7ACCEPT_RTADV\10TXSTART\11RXPOLL" \
"\12VLAN\13BOND\14ARPLL\15NOWINDOWSCALE\16NOAUTOIPV6LL\17EXPENSIVE\20ROUTER4" \
"\21ROUTER6\22LOCALNET_PRIVATE\23ND6ALT\24RESTRICTED_RECV\25AWDL\26NOACKPRI" \
"\27AWDL_RESTRICTED\30CL2K\31ECN_ENABLE\32ECN_DISABLE\33CHANNEL_DRV\34CA" \
DEF_CMD_ARG2("fastlane", setfastlane),
DEF_CMD_ARG2("qosmarking", setqosmarking),
DEF_CMD_ARG("disable_output", setdisableoutput),
+ DEF_CMD("probe_connectivity", 1, setprobeconnectivity),
+ DEF_CMD("-probe_connectivity", 0, setprobeconnectivity),
};
static __constructor void
basename(const char * str)
{
const char *last_slash = strrchr(str, '/');
-
+
if (last_slash == NULL)
return (str);
else
struct option_desc *option_desc;
char * usage_str = (char *)malloc(BUF_MAX);
size_t usage_len;
-
+
if (usage_str == NULL)
err(1, "%s: malloc(%d)", __func__, BUF_MAX);
-
+
usage_len = snprintf(usage_str, BUF_MAX, "# usage: %s ", basename(cmd));
-
+
for (option_desc = option_desc_list; option_desc->option != NULL; option_desc++) {
int len;
-
+
if (option_desc->required)
len = snprintf(usage_str + usage_len, BUF_MAX - usage_len, "%s ", option_desc->option);
else
len = snprintf(usage_str + usage_len, BUF_MAX - usage_len, "[%s] ", option_desc->option);
if (len < 0)
err(1, "%s: snprintf(", __func__);
-
+
usage_len += len;
if (usage_len > BUF_MAX)
break;
}
printf("%s\n", usage_str);
printf("options:\n");
-
+
for (option_desc = option_desc_list; option_desc->option != NULL; option_desc++) {
printf(" %-20s # %s\n", option_desc->option, option_desc->description);
}
-
+
}
int
main(int argc, char * const argv[]) {
int ch;
int error;
-
+
if (argc == 1) {
usage(argv[0]);
exit(0);
}
-
+
while ((ch = getopt(argc, argv, "hf:l:r:t:p:m:M:L:R:")) != -1) {
switch (ch) {
case 'h':
case 'l':
if ((error = getaddrinfo(optarg, NULL, NULL, &p_localaddr)))
errx(1, "getaddrinfo returned error: %s", gai_strerror(error));
-
+
break;
case 'r':
if ((error = getaddrinfo(optarg, NULL, NULL, &p_remoteaddr)))
errx(1, "getaddrinfo returned error: %s", gai_strerror(error));
-
+
break;
case 'm':
ip_act_mask = (uint32_t)atoi(optarg);
errx(1, "Protocol not supported.");
}
break;
-
+
case 'L':
- local_port = (uint16_t)atoi(optarg);
+ local_port = htons((uint16_t)atoi(optarg));
break;
case 'R':
- remote_port = (uint16_t)atoi(optarg);
+ remote_port = htons((uint16_t)atoi(optarg));
break;
case 'M':
proto_act_mask = (uint32_t)atoi(optarg);
break;
-
+
default:
warnx("# syntax error, unknow option '%d'", ch);
usage(argv[0]);
exit(0);
}
}
-
+
if (p_localaddr && p_remoteaddr) {
if (p_localaddr->ai_family!=p_remoteaddr->ai_family) {
errx(1, "The address families for local and remote address"
" when both present, must be equal");
}
}
-
-
+
+
doit();
-
+
return (0);
}
doit()
{
struct sockaddr_ctl addr;
-
+
sf = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
if (sf == -1) {
err(1, "socket()");
}
-
+
/* Connect the socket */
bzero(&addr, sizeof(addr));
addr.sc_len = sizeof(addr);
addr.sc_family = AF_SYSTEM;
addr.ss_sysaddr = AF_SYS_CONTROL;
-
+
{
struct ctl_info info;
memset(&info, 0, sizeof(info));
addr.sc_id = info.ctl_id;
addr.sc_unit = 1;
}
-
+
if (connect(sf, (struct sockaddr *)&addr, sizeof(struct sockaddr_ctl)) == -1) {
err(1, "connect()");
}
-
+
if (setsockopt(sf, SYSPROTO_CONTROL, PKT_MNGLR_OPT_DIRECTION,
&dir, sizeof(uint32_t)) == -1) {
err(1, "setsockopt could not set direction.");
}
-
+
/* Set the IP addresses for the flow */
if (p_localaddr) {
l_saddr = *((struct sockaddr_storage *)(p_localaddr->ai_addr));
-
+
if (setsockopt(sf, SYSPROTO_CONTROL, PKT_MNGLR_OPT_LOCAL_IP,
&l_saddr, sizeof(struct sockaddr_storage)) == -1) {
err(1, "setsockopt could not set local address.");
freeaddrinfo(p_localaddr);
p_localaddr = NULL;
}
-
+
if (p_remoteaddr) {
r_saddr = *((struct sockaddr_storage *)(p_remoteaddr->ai_addr));
-
+
if (setsockopt(sf, SYSPROTO_CONTROL, PKT_MNGLR_OPT_REMOTE_IP,
&r_saddr, sizeof(struct sockaddr_storage)) == -1) {
err(1, "setsockopt could not set remote address.");
freeaddrinfo(p_remoteaddr);
p_remoteaddr = NULL;
}
-
+
/* Set ports for the flow */
if (local_port && (setsockopt(sf, SYSPROTO_CONTROL, PKT_MNGLR_OPT_LOCAL_PORT,
&local_port, sizeof(uint16_t)) == -1)) {
err(1, "setsockopt could not set local port.");
-
+
}
-
+
if (remote_port && (setsockopt(sf, SYSPROTO_CONTROL, PKT_MNGLR_OPT_REMOTE_PORT,
&remote_port, sizeof(uint16_t)) == -1)) {
err(1, "setsockopt could not set remote port.");
-
+
}
-
+
if (protocol && setsockopt(sf, SYSPROTO_CONTROL, PKT_MNGLR_OPT_PROTOCOL,
&protocol, sizeof(uint32_t)) == -1) {
err(1, "setsockopt could not set protocol.");
}
-
+
if (proto_act_mask &&
(setsockopt(sf, SYSPROTO_CONTROL, PKT_MNGLR_OPT_PROTO_ACT_MASK,
&proto_act_mask, sizeof(uint32_t))==-1)) {
err(1, "setsockopt could not set protocol action mask.");
}
-
+
if (setsockopt(sf, SYSPROTO_CONTROL, PKT_MNGLR_OPT_ACTIVATE,
&activate, sizeof(uint8_t))== -1) {
err(1, "setsockopt could not activate packet mangler.");
}
-
+
if (!duration) {
pause();
} else {
sleep(duration);
}
-
+
close(sf);
return 0;
}