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;
}
{
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) {
}
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)
++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)
{
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);
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;
}
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);
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);
}