]> git.saurik.com Git - apple/network_cmds.git/blobdiff - ecnprobe/ecn_probe.c
network_cmds-543.200.16.tar.gz
[apple/network_cmds.git] / ecnprobe / ecn_probe.c
index 36e0967f02a8ca1e1c0855a8d106bfee4da585b9..ae00f4ad3a032eaaf652e6db4ee3c7d813a6f625 100644 (file)
@@ -78,6 +78,9 @@ void usage(char *name)
        printf("\t-s <source hostname or ip address>\n");
        printf("\t-f <file-name to get>\n");
        printf("\t-d <interface name>\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;
 }
 
@@ -85,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) {
@@ -104,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)
@@ -226,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)
 {
@@ -250,83 +273,112 @@ int main(int argc, char **argv)
        u_int32_t sourceIpAddress = 0;
        int mss = DEFAULT_MSS;
        int mtu = DEFAULT_MTU;
-       int fd;
-       int opt;
-       int usedev = 0, rc = 0;
+       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:")) != -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;
-               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);
+                               }
+                               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 '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)
        {
                printf("Failed to convert targetIP address\n");
                Quit(NO_TARGET_CANON_INFO);
-       } 
-/*
-       if (GetCannonicalInfo(session.sourceHostName, &sourceIpAddress) < 0)
-       {
+       }
+       /*
+        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);
@@ -347,8 +399,8 @@ int main(int argc, char **argv)
                                sin = (struct sockaddr_in *)tmp->ifa_addr;
                                sourceIpAddress = sin->sin_addr.s_addr;
                                strncpy(session.sourceHostName,
-                                   inet_ntoa(sin->sin_addr),
-                                   MAXHOSTNAMELEN);
+                                       inet_ntoa(sin->sin_addr),
+                                       MAXHOSTNAMELEN);
                        } else {
                                continue;
                        }
@@ -358,9 +410,9 @@ int main(int argc, char **argv)
                        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)); 
+                               inet_ntoa(sin->sin_addr),
+                               MAXHOSTNAMELEN);
+                       strncpy(dev, tmp->ifa_name, sizeof(dev));
                }
        }
        freeifaddrs(ifap);
@@ -381,19 +433,43 @@ 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;
+       }
 
-       printf("Starting ECN test\n");
-       ECNTest(sourceIpAddress, sourcePort, targetIpAddress, targetPort, mss);
+       CaptureInit(sourceIpAddress, sourcePort, targetIpAddress,
+                   targetPort, dev);
+       session.initCapture = 1;
 
-       Cleanup();
+
+       printf("Starting ECN test\n");
+       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);
+       }
+done:
+       Quit(SUCCESS);
        close(session.socket);
        return (0);
 }