X-Git-Url: https://git.saurik.com/apple/network_cmds.git/blobdiff_plain/fa34b6f5f32f696bb2fe92a877dfaec960fcd850..a3cc5c72831f0e0465ddce1886b29357f9257121:/ecnprobe/ecn_probe.c diff --git a/ecnprobe/ecn_probe.c b/ecnprobe/ecn_probe.c index 9ff6193..362ff4f 100644 --- a/ecnprobe/ecn_probe.c +++ b/ecnprobe/ecn_probe.c @@ -64,7 +64,7 @@ extern struct TcpSession session; void usage (char *name); -int GetCannonicalInfo(char *string, u_int32_t *address); +int GetCannonicalInfo(char *string, size_t str_size, u_int32_t *address); int BindTcpPort(int sockfd) ; void usage(char *name) @@ -79,6 +79,8 @@ void usage(char *name) printf("\t-f \n"); printf("\t-d \n"); printf("\t-C for CE path check\n"); + printf("\t-S [A|R|X] SYN followed by ACK or RST or nothing\n"); + printf("\t-F [set|clear|skip] how to handle firewall rules\n"); return; } @@ -86,17 +88,17 @@ void SetupFirewall(u_int32_t targetIP, u_int16_t port, char *dev) { char pfcmd[512]; char *pf_file_name = "/tmp/pf.conf"; - int pf_fd = 0, rc; + int pf_fd = 0, rc; ssize_t bytes; - char *args[4]; + char *args[4]; bzero(pfcmd, sizeof(pfcmd)); - bzero(args, sizeof(args)); + bzero(args, sizeof(args)); sprintf(pfcmd, "block in quick on %s inet proto tcp from %s port %u\n", - dev, InetAddress(targetIP), port); + dev, InetAddress(targetIP), port); if (session.debug >= SESSION_DEBUG_LOW) - printf("PF rule: %s\n", pfcmd); + printf("PF rule: %s\n", pfcmd); pf_fd = open(pf_file_name, O_RDWR|O_TRUNC|O_CREAT); if (pf_fd < 0) { @@ -105,52 +107,59 @@ void SetupFirewall(u_int32_t targetIP, u_int16_t port, char *dev) } bytes = write(pf_fd, pfcmd, strlen(pfcmd) + 1); close(pf_fd); - args[0] = "pfctl"; - args[1] = "-d"; - args[2] = NULL; - rc = posix_spawn(NULL, "/sbin/pfctl", NULL, NULL, args, NULL); - if (rc != 0) { - printf("Failed to exec: pfctl -d: %d\n", rc); - Quit(FAIL); - } - - args[1] = "-f"; - args[2] = pf_file_name; - args[3] = NULL; - rc = posix_spawn(NULL, "/sbin/pfctl", NULL, NULL, args, NULL); - if (rc != 0) { - printf("Failed to exec: pfctl -f /tmp/pf.conf: %d\n", rc); - Quit(FAIL); - } - - args[1] = "-e"; - args[2] = NULL; - rc = posix_spawn(NULL, "/sbin/pfctl", NULL, NULL, args, NULL); - if (rc != 0) { - printf("Failed to exec: pfctl -e: %d\n", rc); - Quit(FAIL); - } + args[0] = "pfctl"; + args[1] = "-d"; + args[2] = NULL; + rc = posix_spawn(NULL, "/sbin/pfctl", NULL, NULL, args, NULL); + if (rc != 0) { + printf("Failed to exec: pfctl -d: %d\n", rc); + Quit(FAIL); + } + + args[1] = "-f"; + args[2] = pf_file_name; + args[3] = NULL; + rc = posix_spawn(NULL, "/sbin/pfctl", NULL, NULL, args, NULL); + if (rc != 0) { + printf("Failed to exec: pfctl -f /tmp/pf.conf: %d\n", rc); + Quit(FAIL); + } + + args[1] = "-e"; + args[2] = NULL; + rc = posix_spawn(NULL, "/sbin/pfctl", NULL, NULL, args, NULL); + if (rc != 0) { + printf("Failed to exec: pfctl -e: %d\n", rc); + Quit(FAIL); + } +} + +void CleanupFirewall() +{ + char * args[3]; + int rc; + + args[0] = "pfctl"; + args[1] = "-d"; + args[2] = NULL; + rc = posix_spawn(NULL, "/sbin/pfctl", NULL, NULL, args, NULL); + if (rc != 0) { + printf("Failed to exec: pfctl -d: %d\n", rc); + Quit(FAIL); + } } void Cleanup() { - char * args[3]; - int rc; if (session.initSession > 0) { shutdown(session.socket, 2); } - if (session.initCapture > 0) { CaptureEnd(); } - args[0] = "pfctl"; - args[1] = "-d"; - args[2] = NULL; - rc = posix_spawn(NULL, "/sbin/pfctl", NULL, NULL, args, NULL); - if (rc != 0) { - printf("Failed to exec: pfctl -d: %d\n", rc); - Quit(FAIL); - } + if (session.initFirewall > 0) { + CleanupFirewall(); + } } void Quit(int how) @@ -170,7 +179,7 @@ void SigHandle(int signo) exit(-1); } -int GetCannonicalInfo(char *string, u_int32_t *address) +int GetCannonicalInfo(char *string, size_t str_size, u_int32_t *address) { struct hostent *hp; /* Is string in dotted decimal format? */ @@ -182,7 +191,7 @@ int GetCannonicalInfo(char *string, u_int32_t *address) "RETURN CODE: %d\n", string, FAIL); return(-1); } else { - strncpy(string, hp->h_name, MAXHOSTNAMELEN-1); + strlcpy(string, hp->h_name, str_size); memcpy((void *)address, (void *)hp->h_addr, hp->h_length); } @@ -198,9 +207,9 @@ int GetCannonicalInfo(char *string, u_int32_t *address) " name for %s\nRETURN CODE: %d", string, NO_SRC_CANON_INFO); } - /* strncpy(name, string, MAXHOSTNAMELEN - 1);*/ + /* strlcpy(name, string, MAXHOSTNAMELEN);*/ } else { - /* strncpy(name, hp->h_name, MAXHOSTNAMELEN - 1);*/ + /* strlcpy(name, hp->h_name, MAXHOSTNAMELEN);*/ } } return(0); @@ -227,21 +236,34 @@ int BindTcpPort(int sockfd) ++port; sockName.sin_addr.s_addr = INADDR_ANY; sockName.sin_family = AF_INET; - sockName.sin_port = htons(port); + sockName.sin_port = 0; //htons(port); result = bind(sockfd, (struct sockaddr *)&sockName, sizeof(sockName)); } while ((result < 0) && (port < END_PORT)); + if (result < 0) { /* No free ports */ perror("bind"); port = 0; - } + } else { + socklen_t len = sizeof(sockName); + result = getsockname(sockfd, (struct sockaddr *)&sockName, &len); + if (result < 0) { + perror("getsockname"); + port = 0; + } else { + port = ntohs(sockName.sin_port); + } + } return port; } - +#define FIREWALL_DEFAULT 0 +#define FIREWALL_SET_ONLY 1 +#define FIREWALL_CLEAR_ONLY 2 +#define FIREWALL_SKIP 3 int main(int argc, char **argv) { @@ -252,83 +274,105 @@ int main(int argc, char **argv) int mss = DEFAULT_MSS; int mtu = DEFAULT_MTU; int fd, opt, usedev = 0, rc = 0, path_check = 0; + int syn_test = 0, syn_reply = 0; struct sockaddr_in saddr; char dev[11]; /* device name for pcap init */ struct ifaddrs *ifap, *tmp; + int firewall_mode = FIREWALL_DEFAULT; bzero(&session, sizeof(session)); - while ((opt = getopt(argc, argv, "n:p:w:m:M:s:d:f:-C")) != -1) { + while ((opt = getopt(argc, argv, "n:p:w:m:M:s:d:f:-CS:vF:")) != -1) { switch (opt) { - case 'n': - if (strlen(optarg) > (MAXHOSTNAMELEN - 1)) { - printf("Target host name too long, max %u chars\n", MAXHOSTNAMELEN); - Quit(FAIL); - } - strncpy(session.targetHostName, optarg, - MAXHOSTNAMELEN); - strncpy(session.targetName, session.targetHostName, - MAXHOSTNAMELEN); - break; - case 'p': - targetPort = atoi(optarg); - break; - case 'm': - mss = atoi(optarg); - break; - case 'M': - mtu = atoi(optarg); - break; - case 'w': - sourcePort = atoi(optarg); - break; - case 's': - if (strlen(optarg) > (MAXHOSTNAMELEN - 1)) { - printf("Source host name too long, max %u chars\n", MAXHOSTNAMELEN); - Quit(FAIL); - } - strncpy(session.sourceHostName, optarg, - MAXHOSTNAMELEN); - break; - case 'd': - if (strlen(optarg) > (sizeof(dev) - 1)) { - printf("Interface nae is too large, max %lu chars\n", (sizeof(dev) - 1)); - Quit(FAIL); - } - bzero(dev, sizeof(dev)); - strncpy(dev, optarg, (sizeof(dev) - 1)); - usedev = 1; - break; - case 'f': - if (strlen(optarg) > 0) { - session.filename = strndup(optarg, strlen(optarg) + 1); - } else { - printf("Invalid file name \n"); - } - break; - case 'C': - path_check = 1; - break; - default: - usage(argv[0]); - exit(1); + case 'n': + if (strlen(optarg) > (MAXHOSTNAMELEN - 1)) { + printf("Target host name too long, max %u chars\n", MAXHOSTNAMELEN); + Quit(FAIL); + } + strlcpy(session.targetHostName, optarg, + sizeof(session.targetHostName)); + strlcpy(session.targetName, session.targetHostName, + sizeof(session.targetName)); + break; + case 'p': + targetPort = atoi(optarg); + break; + case 'm': + mss = atoi(optarg); + break; + case 'M': + mtu = atoi(optarg); + break; + case 'w': + sourcePort = atoi(optarg); + break; + case 's': + if (strlen(optarg) > (MAXHOSTNAMELEN - 1)) { + printf("Source host name too long, max %u chars\n", MAXHOSTNAMELEN); + Quit(FAIL); + } + strlcpy(session.sourceHostName, optarg, + MAXHOSTNAMELEN); + break; + case 'd': + if (strlen(optarg) > (sizeof(dev) - 1)) { + printf("Interface nae is too large, max %lu chars\n", (sizeof(dev) - 1)); + Quit(FAIL); + } + bzero(dev, sizeof(dev)); + strlcpy(dev, optarg, sizeof(dev)); + usedev = 1; + break; + case 'f': + if (strlen(optarg) > 0) { + session.filename = strndup(optarg, strlen(optarg) + 1); + } else { + printf("Invalid file name \n"); + } + break; + case 'F': + if (strcasecmp(optarg, "default") == 0) + firewall_mode = FIREWALL_DEFAULT; + else if (strcasecmp(optarg, "set") == 0) + firewall_mode = FIREWALL_SET_ONLY; + else if (strcasecmp(optarg, "clear") == 0) + firewall_mode = FIREWALL_CLEAR_ONLY; + else if (strcasecmp(optarg, "skip") == 0) + firewall_mode = FIREWALL_SKIP; + else + printf("firewall mode\n"); + break; + case 'C': + path_check = 1; + break; + case 'S': + syn_test = 1; + if (strcasecmp(optarg, "A") == 0) + syn_reply = TCPFLAGS_ACK; + else if (strcasecmp(optarg, "R") == 0) + syn_reply = TCPFLAGS_RST; + else if (strcasecmp(optarg, "X") == 0) + syn_reply = 0; + else + printf("Invalid SYN reply \n"); + break; + case 'v': + session.debug++; + break; + default: + usage(argv[0]); + exit(1); } } signal(SIGTERM, SigHandle); signal(SIGINT, SigHandle); signal(SIGHUP, SigHandle); - - if (GetCannonicalInfo(session.targetHostName, &targetIpAddress) < 0) + + if (GetCannonicalInfo(session.targetHostName, sizeof(session.targetHostName), + &targetIpAddress) < 0) { printf("Failed to convert targetIP address\n"); Quit(NO_TARGET_CANON_INFO); - } -/* - if (GetCannonicalInfo(session.sourceHostName, &sourceIpAddress) < 0) - { - printf("Failed to convert source IP address\n"); - Quit(NO_TARGET_CANON_INFO); } -*/ rc = getifaddrs(&ifap); if (rc != 0 || ifap == NULL) { printf("Failed to get source addresswith getifaddrs: %d\n", rc); @@ -348,9 +392,9 @@ int main(int argc, char **argv) if (strcmp(dev, tmp->ifa_name) == 0) { sin = (struct sockaddr_in *)tmp->ifa_addr; sourceIpAddress = sin->sin_addr.s_addr; - strncpy(session.sourceHostName, - inet_ntoa(sin->sin_addr), - MAXHOSTNAMELEN); + strlcpy(session.sourceHostName, + inet_ntoa(sin->sin_addr), + sizeof(session.sourceHostName)); } else { continue; } @@ -359,10 +403,10 @@ int main(int argc, char **argv) bzero(dev, sizeof(dev)); sin = (struct sockaddr_in *)tmp->ifa_addr; sourceIpAddress = sin->sin_addr.s_addr; - strncpy(session.sourceHostName, - inet_ntoa(sin->sin_addr), - MAXHOSTNAMELEN); - strncpy(dev, tmp->ifa_name, sizeof(dev)); + strlcpy(session.sourceHostName, + inet_ntoa(sin->sin_addr), + sizeof(session.sourceHostName)); + strlcpy(dev, tmp->ifa_name, sizeof(dev)); } } freeifaddrs(ifap); @@ -383,23 +427,42 @@ int main(int argc, char **argv) return (-1); } } - CaptureInit(sourceIpAddress, sourcePort, targetIpAddress, - targetPort, dev); - session.initCapture = 1; - printf("Source: %s:%d\n", session.sourceHostName, sourcePort); printf("Destination: %s:%d\n", session.targetHostName, targetPort); - SetupFirewall(targetIpAddress, targetPort, dev); + switch (firewall_mode) { + case FIREWALL_DEFAULT: + SetupFirewall(targetIpAddress, targetPort, dev); + session.initFirewall = 1; + break; + case FIREWALL_SET_ONLY: + SetupFirewall(targetIpAddress, targetPort, dev); + goto done; + case FIREWALL_CLEAR_ONLY: + session.initFirewall = 1; + goto done; + case FIREWALL_SKIP: + break; + } + + CaptureInit(sourceIpAddress, sourcePort, targetIpAddress, + targetPort, dev); + session.initCapture = 1; + printf("Starting ECN test\n"); - if (path_check) { - ECNPathCheckTest(sourceIpAddress, sourcePort, targetIpAddress, - targetPort, mss); + if (syn_test) { + session.dont_send_reset = 1; + SynTest(sourceIpAddress, sourcePort, targetIpAddress, + targetPort, mss, syn_reply); + } else if (path_check) { + ECNPathCheckTest(sourceIpAddress, sourcePort, targetIpAddress, + targetPort, mss); } else { - ECNTest(sourceIpAddress, sourcePort, targetIpAddress, - targetPort, mss); + ECNTest(sourceIpAddress, sourcePort, targetIpAddress, + targetPort, mss); } +done: Quit(SUCCESS); close(session.socket); return (0);