ndt-dev - [ndt-dev] [ndt] r1005 committed - Separate fakewww as individual subproject. By default fakewww is not b...
Subject: NDT-DEV email list created
List archive
[ndt-dev] [ndt] r1005 committed - Separate fakewww as individual subproject. By default fakewww is not b...
Chronological Thread
- From:
- To:
- Subject: [ndt-dev] [ndt] r1005 committed - Separate fakewww as individual subproject. By default fakewww is not b...
- Date: Tue, 11 Mar 2014 08:31:21 +0000
Revision: 1005
Author:
Date: Tue Mar 11 08:31:04 2014 UTC
Log: Separate fakewww as individual subproject. By default fakewww is not build. You can add it during configuration (--enable-fakewwww=yes)
http://code.google.com/p/ndt/source/detail?r=1005
Added:
/branches/Issue125/src/fakewww.c
/branches/Issue125/src/troute.c
/branches/Issue125/src/troute.h
/branches/Issue125/src/troute6.c
Deleted:
/branches/Issue125/fakewww
Modified:
/branches/Issue125/Makefile.am
/branches/Issue125/configure.ac
/branches/Issue125/src/Makefile.am
=======================================
--- /dev/null
+++ /branches/Issue125/src/fakewww.c Tue Mar 11 08:31:04 2014 UTC
@@ -0,0 +1,760 @@
+/*
+ * fakewww {options}
+ * concurrent server
+ * reap children, and thus watch out for EINTR
+ * take http GET / and return a web page, then return requested file by
+ * next GET
+ * can use this to "provide" a java client for machine without having
+ * to run a web server
+ */
+
+#include "../config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <signal.h>
+#include <time.h>
+#include <string.h>
+#include <errno.h>
+#include <getopt.h>
+#define SYSLOG_NAMES
+#include <syslog.h>
+
+#include "usage.h"
+#include "troute.h"
+#include "tr-tree.h"
+#include "network.h"
+#include "logging.h"
+#include "web100-admin.h"
+
+#define LISTEN_PORT "7123"
+#define AC_TIME_FORMAT "%d/%b/%Y:%H:%M:%S %z"
+#define ER_TIME_FORMAT "%a %b %d %H:%M:%S %Y"
+#define ACLOGFILE "access_log"
+#define ERLOGFILE "error_log"
+#define LOG_FACILITY LOG_LOCAL0
+
+char* ac_time_format = AC_TIME_FORMAT;
+char* er_time_format = ER_TIME_FORMAT;
+char buff[BUFFSIZE];
+/* html message */
+char *MsgOK = "HTTP/1.0 200 OK\r\n\r\n";
+char *MsgNope1 = "HTTP/1.0 404 Not found\r\n\r\n";
+char *MsgNope2 = "<HEAD><TITLE>File Not Found</TITLE></HEAD>\n"
+"<BODY><H1>The requested file could not be found</H1></BODY>\n";
+
+char *MsgRedir1 = "HTTP/1.0 307 Temporary Redirect\r\n";
+char *MsgRedir2 = "Location: ";
+char *MsgRedir3 = "\r\n\r\n";
+char *MsgRedir4 = "<HTML><TITLE>FLM server Redirect Page</TITLE>\n"
+" <BODY>\n <meta http-equiv=\"refresh\" content=\"2; ";
+char *MsgRedir5 =
+"\">\n\n<h2>FLM server re-direction page</h2>\n"
+"<p><font size=\"+2\">Your client is being redirected to the 'closest' FLM "
+"server for configuration testing.\n <a ";
+char *MsgRedir6 = ">Click Here </a> if you are not "
+"automatically redirected in the next 2 seconds.\n "
+"</font></BODY>\n</HTML>";
+
+char *Mypagefile = "/tcpbw100.html"; /* we throw the slash away */
+char *okfile[] = { "/tcpbw100.html", "/Tcpbw100.class", "/Tcpbw100$1.class",
+ "/Tcpbw100$clsFrame.class", "/Tcpbw100.jar", "/copyright.html",
+ "/web100variables.html", "/"ADMINFILE, "/Admin.class", "/tr.sh",
+ "/traceroute.pl", "/Tcpbw100$MyTextPane.class",
+ "/Tcpbw100$Protocol.class", "/Tcpbw100$StatusPanel.class",
+ "/Tcpbw100$3.class", "/Tcpbw100$OsfwWorker.class",
+ "/Tcpbw100$Message.class", "/Tcpbw100$StatusPanel$1.class",
+ "/Tcpbw100$clsFrame$1.class", "/Tcpbw100$TestWorker.class",
+ "/crossdomain.xml", 0 };
+
+typedef struct allowed {
+ char* filename;
+ struct allowed *next;
+} Allowed;
+
+Allowed* a_root = NULL;
+char* basedir = BASEDIR;
+
+char* DefaultTree = NULL;
+#define DTFN_STRLEN 256
+static char dtfn[DTFN_STRLEN];
+#ifdef AF_INET6
+char* DefaultTree6 = NULL;
+static char dt6fn[DTFN_STRLEN];
+#endif
+
+int usesyslog = 0;
+char *SysLogFacility = NULL;
+int syslogfacility = LOG_FACILITY;
+char *ProcessName = { "fakewww" };
+
+static struct option long_options[] = {
+ { "debug", 0, 0, 'd' }, { "help", 0, 0, 'h' }, { "alog", 1, 0, 'l' },
+ { "elog", 1, 0, 'e' }, { "port", 1, 0, 'p' }, { "ttl", 1, 0, 't' },
+ { "federated", 0, 0, 'F' }, { "file", 1, 0, 'f' }, { "basedir", 1, 0, 'b' },
+ { "syslog", 0, 0, 's' }, { "logfacility", 1, 0, 'S' },
+ { "version", 0, 0, 'v' }, { "dflttree", 1, 0, 301 },
+#ifdef AF_INET6
+ { "dflttree6", 1, 0, 302},
+ { "ipv4", 0, 0, '4'},
+ { "ipv6", 0, 0, '6'},
+#endif
+ { 0, 0, 0, 0 } };
+
+void dowww(int, I2Addr, char*, char*, char*, int, int);
+void reap();
+char* getTime(time_t*, char*);
+void logErLog(char*, time_t*, char*, char*, ...);
+void logAcLog(char*, time_t*, char*, char*, int, int, char*, char*);
+
+void err_sys(char* s) {
+ perror(s);
+ exit(1);
+}
+
+int main(int argc, char** argv) {
+ int c;
+ int sockfd, newsockfd;
+ int federated = 0, debug = 0, max_ttl = 10;
+ time_t tt;
+ socklen_t clilen;
+ char* srcname = NULL;
+ char* listenport = LISTEN_PORT;
+ int conn_options = 0;
+
+ char *ErLogFileName = BASEDIR
+ "/"ERLOGFILE;
+ char *AcLogFileName = BASEDIR
+ "/"ACLOGFILE;
+ struct sockaddr_storage cli_addr;
+ I2Addr listenaddr = NULL;
+ Allowed* ptr;
+
+#ifdef AF_INET6
+#define GETOPT_LONG_INET6(x) "46"x
+#else
+#define GETOPT_LONG_INET6(x) x
+#endif
+
+ while ((c = getopt_long(argc, argv, GETOPT_LONG_INET6("dhl:e:p:t:Ff:b:sS:v"),
+ long_options, 0)) != -1) {
+ switch (c) {
+ case '4':
+ conn_options |= OPT_IPV4_ONLY;
+ break;
+ case '6':
+ conn_options |= OPT_IPV6_ONLY;
+ break;
+ case 'd':
+ debug++;
+ break;
+ case 'h':
+ www_long_usage("ANL/Internet2 NDT version " VERSION " (fakewww)");
+ break;
+ case 'v':
+ printf("ANL/Internet2 NDT version %s (fakewww)\n", VERSION);
+ exit(0);
+ break;
+ case 'l':
+ AcLogFileName = optarg;
+ break;
+ case 'e':
+ ErLogFileName = optarg;
+ break;
+ case 'p':
+ listenport = optarg;
+ break;
+ case 't':
+ max_ttl = atoi(optarg);
+ break;
+ case 'F':
+ federated = 1;
+ break;
+ case 'f':
+ ptr = malloc(sizeof(Allowed));
+ ptr->filename = optarg;
+ ptr->next = a_root;
+ a_root = ptr;
+ break;
+ case 'b':
+ basedir = optarg;
+ break;
+ case 's':
+ usesyslog = 1;
+ break;
+ case 'S':
+ SysLogFacility = optarg;
+ break;
+ case 301:
+ DefaultTree = optarg;
+ break;
+#ifdef AF_INET6
+ case 302:
+ DefaultTree6 = optarg;
+ break;
+#endif
+ case '?':
+ short_usage(argv[0], "");
+ break;
+ }
+ }
+
+ if (optind < argc) {
+ short_usage(argv[0], "Unrecognized non-option elements");
+ }
+
+ log_init(argv[0], debug);
+
+ if (SysLogFacility != NULL) {
+ int i = 0;
+ while (facilitynames[i].c_name) {
+ if (strcmp(facilitynames[i].c_name, SysLogFacility) == 0) {
+ syslogfacility = facilitynames[i].c_val;
+ break;
+ }
+ ++i;
+ }
+ if (facilitynames[i].c_name == NULL) {
+ log_println(
+ 0,
+ "Warning: Unknown syslog facility [%s] --> using default (%d)",
+ SysLogFacility, syslogfacility);
+ SysLogFacility = NULL;
+ }
+ }
+
+ if (DefaultTree == NULL) {
+ snprintf(dtfn, sizeof(dtfn), "%s/%s", BASEDIR, DFLT_TREE);
+ DefaultTree = dtfn;
+ }
+
+#ifdef AF_INET6
+ if (DefaultTree6 == NULL) {
+ snprintf(dt6fn, sizeof(dtfn), "%s/%s", BASEDIR, DFLT_TREE6);
+ DefaultTree6 = dt6fn;
+ }
+#endif
+
+ /*
+ * Bind our local address so that the client can send to us.
+ */
+ if (srcname && !(listenaddr = I2AddrByNode(get_errhandle(), srcname))) {
+ err_sys("server: Invalid source address specified");
+ }
+ if ((listenaddr = CreateListenSocket(listenaddr, listenport, conn_options,
+ 0)) == NULL) {
+ err_sys("server: CreateListenSocket failed");
+ }
+ sockfd = I2AddrFD(listenaddr);
+
+ tt = time(0);
+ log_println(1, "%15.15s fakewww server started (NDT version %s)",
+ ctime(&tt) + 4, VERSION);
+ log_println(1, "\tport = %d", I2AddrPort(listenaddr));
+ log_println(1, "\tfederated mode = %s", (federated == 1) ? "on" : "off");
+ log_println(1, "\taccess log = %s\n\terror log = %s", AcLogFileName,
+ ErLogFileName);
+ log_println(1, "\tbasedir = %s", basedir);
+ if (usesyslog) {
+ log_println(1, "\tsyslog facility = %s (%d)",
+ SysLogFacility ? SysLogFacility : "default", syslogfacility);
+ }
+ log_println(1, "\tdebug level set to %d", debug);
+
+ logErLog(ErLogFileName, &tt, "notice",
+ "fakewww server started (NDT version %s)", VERSION);
+ logErLog(ErLogFileName, &tt, "notice", "\tport = %d",
+ I2AddrPort(listenaddr));
+ logErLog(ErLogFileName, &tt, "notice", "\tfederated mode = %s",
+ (federated == 1) ? "on" : "off");
+ logErLog(ErLogFileName, &tt, "notice", "\taccess log = %s", AcLogFileName);
+ logErLog(ErLogFileName, &tt, "notice", "\terror log = %s", ErLogFileName);
+ logErLog(ErLogFileName, &tt, "notice", "\tbasedir = %s", basedir);
+ if (usesyslog) {
+ logErLog(ErLogFileName, &tt, "notice", "\tsyslog facility = %s (%d)",
+ SysLogFacility ? SysLogFacility : "default", syslogfacility);
+ }
+ logErLog(ErLogFileName, &tt, "notice", "\tdebug level set to %d", debug);
+
+ if (usesyslog == 1)
+ syslog(LOG_FACILITY | LOG_INFO, "Fakewww (ver %s) process started",
+ VERSION);
+ signal(SIGCHLD, reap); /* get rid of zombies */
+
+ /*
+ * Wait for a connection from a client process.
+ * This is an example of a concurrent server.
+ */
+
+ for (;;) {
+ clilen = sizeof(cli_addr);
+ newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
+ if (newsockfd < 0) {
+ if (errno == EINTR)
+ continue; /*sig child */
+ err_sys("Fakewww server: accept error");
+ }
+
+ if (fork() == 0) { /* child */
+ I2Addr caddr = I2AddrBySAddr(get_errhandle(),
+ (struct sockaddr *) &cli_addr, clilen, 0, 0);
+ alarm(300); /* kill child off after 5 minutes, should never happen */
+ close(sockfd);
+ dowww(newsockfd, caddr, listenport, AcLogFileName, ErLogFileName,
+ federated, max_ttl);
+ exit(0);
+ }
+ close(newsockfd);
+ }
+}
+
+#include <sys/wait.h>
+void reap(int signo) {
+ /*
+ * avoid zombies, since we run forever
+ * Use the wait3() system call with the WNOHANG option.
+ */
+ int pid;
+ union wait status;
+
+ while ((pid = wait3(&status, WNOHANG, (struct rusage *) 0)) > 0) {
+ }
+}
+
+/*
+ * Read a line from a descriptor. Read the line one byte at a time,
+ * looking for the newline. We store the newline in the buffer,
+ * then follow it with a null (the same as fgets(3)).
+ * We return the number of characters up to, but not including,
+ * the null (the same as strlen(3)).
+ */
+
+int readline(fd, ptr, maxlen)
+ register int fd;
+ register char *ptr;
+ register int maxlen; {
+ int n, rc;
+ char c;
+
+ for (n = 1; n < maxlen; n++) {
+ if ((rc = read(fd, &c, 1)) == 1) {
+ *ptr++ = c;
+ if (c == '\n')
+ break;
+ } else if (rc == 0) {
+ if (n == 1)
+ return (0); /* EOF, no data read */
+ else
+ break; /* EOF, some data was read */
+ } else {
+ return (-1); /* error */
+ }
+ }
+
+ *ptr = 0;
+ return (n);
+ }
+
+void trim(char* ptr) {
+ while (*ptr) {
+ if ((*ptr == '\r') || (*ptr == '\n')) {
+ *ptr = 0;
+ break;
+ }
+ ptr++;
+ }
+}
+
+void dowww(int sd, I2Addr addr, char* port, char* AcLogFileName,
+ char* ErLogFileName, int fed_mode, int max_ttl) {
+ /* process web request */
+ int fd, n, i, ok;
+ char *p, filename[256], line[256], *ctime();
+ char htmlfile[256];
+ u_int32_t IPlist[64], srv_addr;
+#ifdef AF_INET6
+ u_int32_t IP6list[64][4];
+ u_int32_t srv_addr6[4];
+#endif
+ I2Addr serv_addr = NULL;
+ I2Addr loc_addr = NULL;
+ time_t tt;
+ char nodename[200];
+ char onenodename[200];
+ size_t nlen = 199;
+ Allowed* ptr;
+ char lineBuf[100];
+ char useragentBuf[100];
+ char refererBuf[100];
+ int answerSize;
+
+ memset(nodename, 0, 200);
+ I2AddrNodeName(addr, nodename, &nlen);
+
+ while ((n = readline(sd, buff, sizeof(buff))) > 0) {
+ if (n < 3)
+ break; /* end of html input */
+ p = (char *) strstr(buff, "GET");
+ if (p == NULL)
+ continue;
+ memset(lineBuf, 0, 100);
+ memset(useragentBuf, 0, 100);
+ memset(refererBuf, 0, 100);
+ strncpy(lineBuf, buff, 99);
+ trim(lineBuf);
+ sscanf(p + 4, "%s", filename);
+ while ((n = readline(sd, buff, sizeof(buff))) > 0) {
+ if ((p = (char *) strstr(buff, "User-Agent"))) {
+ strncpy(useragentBuf, p + 12, 99);
+ trim(useragentBuf);
+ }
+ if ((p = (char *) strstr(buff, "Referer"))) {
+ strncpy(refererBuf, p + 9, 99);
+ trim(refererBuf);
+ }
+ if (n < 3)
+ break; /* end of html input */
+ }
+ if (strcmp(filename, "/") == 0) {
+ /* feed em the default page */
+ /* strcpy(filename, Mypagefile); */
+ /* By default we now send out the redirect page */
+
+ log_println(4, "Received connection from [%s]", nodename);
+
+ if (fed_mode == 1) {
+ struct sockaddr* csaddr;
+ csaddr = I2AddrSAddr(addr, NULL);
+ if (csaddr->sa_family == AF_INET) { /* make the IPv4 find */
+ char ip_str[16];
+ struct sockaddr_in* cli_addr = (struct sockaddr_in*) csaddr;
+ find_route(cli_addr->sin_addr.s_addr, IPlist, max_ttl);
+ for (i = 0; IPlist[i] != cli_addr->sin_addr.s_addr; i++) {
+ snprintf(ip_str, sizeof(ip_str), "%u.%u.%u.%u",
+ IPlist[i] & 0xff,
+ (IPlist[i] >> 8) & 0xff,
+ (IPlist[i] >> 16) & 0xff,
+ (IPlist[i] >> 24) & 0xff);
+ log_println(4, "loop IPlist[%d] = %s", i, ip_str);
+ if (i == max_ttl) {
+ log_println(4, "Oops, destination not found!");
+ break;
+ }
+ }
+ /* print out last item on list */
+ snprintf(ip_str, sizeof(ip_str), "%u.%u.%u.%u",
+ IPlist[i] & 0xff,
+ (IPlist[i] >> 8) & 0xff,
+ (IPlist[i] >> 16) & 0xff,
+ (IPlist[i] >> 24) & 0xff);
+ log_println(4, "IPlist[%d] = %s", i, ip_str);
+
+ srv_addr = find_compare(IPlist, i);
+
+ /* the find_compare() routine returns the IP address of the 'closest'
+ * NDT server. It does this by comparing the clients address to a
+ * map of routes between all servers. If this comparison fails, the
+ * routine returns 0. In that case, simply use this server.
+ */
+ if (srv_addr == 0) {
+ serv_addr = I2AddrByLocalSockFD(get_errhandle(), sd,
+ False);
+ memset(onenodename, 0, 200);
+ nlen = 199;
+ I2AddrNodeName(serv_addr, onenodename, &nlen);
+ log_println(4,
+ "find_compare() returned 0, reset to [%s]",
+ onenodename);
+ srv_addr =
+ ((struct sockaddr_in*) I2AddrSAddr(serv_addr, NULL))->
+ sin_addr.s_addr;
+ }
+
+ log_println(4,
+ "Client host [%s] should be redirected to FLM server "
+ "[%u.%u.%u.%u]", inet_ntoa(cli_addr->sin_addr),
+ srv_addr & 0xff, (srv_addr >> 8) & 0xff,
+ (srv_addr >> 16) & 0xff, (srv_addr >> 24) & 0xff);
+
+ /* At this point, the srv_addr variable contains the IP address of the
+ * server we want to re-direct the connect to. So we should generate a
+ * new html page, and sent that back to the client. This new page will
+ * use the HTML refresh option with a short (2 second) timer to cause the
+ * client's browser to just to the new server.
+ *
+ * RAC 3/9/04
+ */
+
+ writen(sd, MsgRedir1, strlen(MsgRedir1));
+ writen(sd, MsgRedir2, strlen(MsgRedir2));
+ snprintf(line, sizeof(line), "http://%u.%u.%u.%u:%s/tcpbw100.html",
+ srv_addr & 0xff, (srv_addr >> 8) & 0xff,
+ (srv_addr >> 16) & 0xff, (srv_addr >> 24) & 0xff,
+ port);
+ writen(sd, line, strlen(line));
+ writen(sd, MsgRedir3, strlen(MsgRedir3));
+ writen(sd, MsgRedir4, strlen(MsgRedir4));
+ answerSize = strlen(MsgRedir4);
+ snprintf(line, sizeof(line),
+ "url=http://%u.%u.%u.%u:%s/tcpbw100.html",
+ srv_addr & 0xff, (srv_addr >> 8) & 0xff,
+ (srv_addr >> 16) & 0xff, (srv_addr >> 24) & 0xff,
+ port);
+ writen(sd, line, strlen(line));
+ answerSize += strlen(line);
+ writen(sd, MsgRedir5, strlen(MsgRedir5));
+ answerSize += strlen(MsgRedir5);
+ snprintf(line, sizeof(line),
+ "href=\"http://%u.%u.%u.%u:%s/tcpbw100.html\"",
+ srv_addr & 0xff, (srv_addr >> 8) & 0xff,
+ (srv_addr >> 16) & 0xff, (srv_addr >> 24) & 0xff,
+ port);
+ writen(sd, line, strlen(line));
+ answerSize += strlen(line);
+ writen(sd, MsgRedir6, strlen(MsgRedir6));
+ answerSize += strlen(MsgRedir6);
+ log_println(3,
+ "%s redirected to remote server [%u.%u.%u.%u:%s]",
+ inet_ntoa(cli_addr->sin_addr), srv_addr & 0xff,
+ (srv_addr >> 8) & 0xff, (srv_addr >> 16) & 0xff,
+ (srv_addr >> 24) & 0xff, port);
+ tt = time(0);
+ logErLog(ErLogFileName, &tt, "notice",
+ "[%s] redirected to remote server [%u.%u.%u.%u:%s]",
+ inet_ntoa(cli_addr->sin_addr), srv_addr & 0xff,
+ (srv_addr >> 8) & 0xff, (srv_addr >> 16) & 0xff,
+ (srv_addr >> 24) & 0xff, port);
+ logAcLog(AcLogFileName, &tt, inet_ntoa(cli_addr->sin_addr),
+ lineBuf, 307, answerSize, useragentBuf, refererBuf);
+ break;
+ }
+#ifdef AF_INET6
+ else if (csaddr->sa_family == AF_INET6) {
+ struct sockaddr_in6* cli_addr = (struct sockaddr_in6*) csaddr;
+ socklen_t onenode_len;
+ find_route6(nodename, IP6list, max_ttl);
+ for (i = 0;
+ memcmp(IP6list[i], &cli_addr->sin6_addr,
+ sizeof(cli_addr->sin6_addr));
+ i++) {
+ memset(onenodename, 0, 200);
+ onenode_len = 199;
+ inet_ntop(AF_INET6, (void *) IP6list[i], onenodename, onenode_len);
+ log_println(4, "loop IP6list[%d], = %s", i, onenodename);
+ if (i == max_ttl) {
+ log_println(4, "Oops, destination not found!");
+ break;
+ }
+ }
+ /* print out last item on list */
+
+ if (get_debuglvl() > 3) {
+ memset(onenodename, 0, 200);
+ onenode_len = 199;
+ inet_ntop(AF_INET6, (void *) IP6list[i], onenodename, onenode_len);
+ log_println(4, "IP6list[%d] = %s", i, onenodename);
+ }
+
+ srv_addr = find_compare6(srv_addr6, IP6list, i);
+ if (srv_addr == 0) {
+ serv_addr = I2AddrByLocalSockFD(get_errhandle(), sd, False);
+ memset(onenodename, 0, 200);
+ nlen = 199;
+ I2AddrNodeName(serv_addr, onenodename, &nlen);
+ log_println(4, "find_compare6() returned 0, reset to [%s]",
+ onenodename);
+ struct sockaddr* sock_addr = I2AddrSAddr(serv_addr, NULL);
+ memcpy(srv_addr6,
+ &((struct sockaddr_in6*)sock_addr)->sin6_addr,
+ 16);
+ }
+
+ nlen = 199;
+ memset(onenodename, 0, 200);
+ inet_ntop(AF_INET6, (void *) srv_addr6, onenodename, nlen);
+
+ log_println(4, "Client host [%s] should be redirected to FLM server "
+ "[%s]", nodename, onenodename);
+
+ writen(sd, MsgRedir1, strlen(MsgRedir1));
+ writen(sd, MsgRedir2, strlen(MsgRedir2));
+ snprintf(line, sizeof(line), "http://[%s]:%s/tcpbw100.html",
+ onenodename, port);
+ writen(sd, line, strlen(line));
+ writen(sd, MsgRedir3, strlen(MsgRedir3));
+ writen(sd, MsgRedir4, strlen(MsgRedir4));
+ answerSize = strlen(MsgRedir4);
+ snprintf(line, sizeof(line), "url=http://[%s]:%s/tcpbw100.html",
+ onenodename, port);
+ writen(sd, line, strlen(line));
+ answerSize += strlen(line);
+ writen(sd, MsgRedir5, strlen(MsgRedir5));
+ answerSize += strlen(MsgRedir5);
+ snprintf(line, sizeof(line), "href=\"http://[%s]:%s/tcpbw100.html\"",
+ onenodename, port);
+ writen(sd, line, strlen(line));
+ answerSize += strlen(line);
+ writen(sd, MsgRedir6, strlen(MsgRedir6));
+ answerSize += strlen(MsgRedir6);
+ log_println(3, "%s redirected to remote server [[%s]:%s]", nodename,
+ onenodename, port);
+ tt = time(0);
+ logErLog(ErLogFileName, &tt, "notice",
+ "[%s] redirected to remote server [[%s]:%s]",
+ nodename, onenodename, port);
+ logAcLog(AcLogFileName, &tt, nodename, lineBuf, 307, answerSize,
+ useragentBuf, refererBuf);
+ break;
+ }
+#endif
+ }
+ }
+
+ /* try to open and give em what they want */
+ tt = time(0);
+ ok = 0;
+ if (strcmp(filename, "/") == 0)
+ strncpy(filename, "/tcpbw100.html", 15);
+ for (i = 0; okfile[i]; i++) {
+ /* restrict file access */
+ if (strcmp(okfile[i], filename) == 0) {
+ ok = 1;
+ break;
+ }
+ }
+ if (ok == 0) {
+ ptr = a_root;
+ while (ptr != NULL) {
+ if (strcmp(ptr->filename, filename) == 0) {
+ ok = 2;
+ break;
+ }
+ ptr = ptr->next;
+ }
+ }
+ log_print(3, "%15.15s [%s] requested file '%s' - ", ctime(&tt) + 4,
+ nodename, filename);
+ if (ok == 0) {
+ writen(sd, MsgNope1, strlen(MsgNope1));
+ writen(sd, MsgNope2, strlen(MsgNope2));
+ answerSize = strlen(MsgNope2);
+ log_println(3, "access denied");
+ logAcLog(AcLogFileName, &tt, nodename, lineBuf, 403, answerSize,
+ useragentBuf, refererBuf);
+ logErLog(ErLogFileName, &tt, "error",
+ "[client %s] Permission denied: path not allowed: %s",
+ nodename, filename);
+ if (usesyslog == 1)
+ syslog(LOG_FACILITY | LOG_WARNING,
+ "[client %s] Permission denied: path not allowed: %s",
+ nodename, filename);
+ break;
+ }
+ snprintf(htmlfile, sizeof(htmlfile), "%s/%s", basedir, filename + 1);
+ fd = open(htmlfile, 0); /* open file for read */
+ if (fd < 0) {
+ close(fd);
+ writen(sd, MsgNope1, strlen(MsgNope1));
+ writen(sd, MsgNope2, strlen(MsgNope2));
+ answerSize = strlen(MsgNope2);
+ log_println(3, " not found");
+ logAcLog(AcLogFileName, &tt, nodename, lineBuf, 404, answerSize,
+ useragentBuf, refererBuf);
+ logErLog(ErLogFileName, &tt, "error",
+ "[client %s] File does not exist: %s", nodename, filename);
+ if (usesyslog == 1)
+ syslog(LOG_FACILITY | LOG_WARNING,
+ "[client %s] File does not exist: %s", nodename,
+ filename);
+ break;
+ }
+ if (ok == 1) {
+ log_println(3, "sent to client");
+ } else {
+ log_println(3, "sent to client [A]");
+ }
+
+ /* reply: */
+
+ /* RAC
+ * run Les Cottrell's traceroute program
+ */
+ if (strncmp(htmlfile, "/usr/local/ndt/traceroute.pl", 28) == 0) {
+ loc_addr = I2AddrByLocalSockFD(get_errhandle(), sd, False);
+ memset(onenodename, 0, 200);
+ nlen = 199;
+ I2AddrNodeName(loc_addr, onenodename, &nlen);
+
+ setenv("QUERY_STRING", nodename, 1);
+ setenv("SERVER_NAME", onenodename, 1);
+ setenv("REMOTE_HOST", nodename, 1);
+ setenv("REMOTE_ADDR", "207.75.164.153", 1);
+ system("/usr/bin/perl /usr/local/ndt/traceroute.pl > "
+ "/tmp/rac-traceroute.pl");
+ close(fd);
+ fd = open("/tmp/rac-traceroute.pl", 0);
+ }
+
+ writen(sd, MsgOK, strlen(MsgOK));
+ answerSize = 0;
+ while ((n = read(fd, buff, sizeof(buff))) > 0) {
+ writen(sd, buff, n);
+ answerSize += n;
+ }
+ logAcLog(AcLogFileName, &tt, nodename, lineBuf, 200, answerSize,
+ useragentBuf, refererBuf);
+ close(fd);
+ break;
+ }
+ close(sd);
+}
+
+char*
+getTime(time_t* tt, char* format) {
+ static char timeBuf[100];
+
+ if (strftime(timeBuf, 99, format, localtime(tt))) {
+ return timeBuf;
+ } else {
+ return (ctime(tt) + 4);
+ }
+}
+
+void logErLog(char* LogFileName, time_t* tt, char* severity,
+ char* format, ...) {
+ FILE *fp;
+ va_list ap;
+ if (LogFileName != NULL) {
+ fp = fopen(LogFileName, "a");
+ if (fp != NULL) {
+ fprintf(fp, "[%s] [%s] ", getTime(tt, er_time_format), severity);
+ va_start(ap, format);
+ vfprintf(fp, format, ap);
+ va_end(ap);
+ fprintf(fp, "\n");
+ fclose(fp);
+ }
+ }
+}
+
+void logAcLog(char* LogFileName, time_t* tt, char* host, char* line, int res,
+ int size, char* agent, char* referer) {
+ FILE * fp;
+ if (LogFileName != NULL) {
+ fp = fopen(LogFileName, "a");
+ if (fp != NULL) {
+ fprintf(fp, "%s - - [%s] \"%s\" %d %d \"%s\" \"%s\"\n", host,
+ getTime(tt, ac_time_format), line, res, size, agent,
+ referer);
+ fclose(fp);
+ }
+ }
+}
=======================================
--- /dev/null
+++ /branches/Issue125/src/troute.c Tue Mar 11 08:31:04 2014 UTC
@@ -0,0 +1,401 @@
+/*
+ * This is a modified version of traceroute. It is designed to be
+ * a part of the Internet2 FLM system. It links into the fakewww
+ * server program and traces routes from the NDT server to the
+ * remote client. It returns a list of IP addresses found on this
+ * return path. This list will then be compared to the traceroute
+ * map generated by the tr-tree program.
+ *
+ * Richard Carlson
+ *
+ * March 9, 2004
+ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Van Jacobson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/udp.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <stdio.h>
+
+#include "logging.h"
+
+#define MAXPACKET 65535 /* max ip packet size */
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 64
+#endif
+
+#ifndef FD_SET
+#define NFDBITS (8*sizeof(fd_set))
+#define FD_SETSIZE NFDBITS
+#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+#define FD_ZERO(p) bzero((char *)(p), sizeof(*(p)))
+#endif
+
+/*
+ * format of a (udp) probe packet.
+ */
+struct opacket {
+ struct ip ip;
+ struct udphdr udp;
+ u_char seq; /* sequence number of this packet */
+ u_char ttl; /* ttl packet left with */
+ struct timeval tv; /* time packet left */
+};
+
+u_char packet[512]; /* last inbound (icmp) packet */
+struct opacket *outpacket; /* last output (udp) packet */
+
+int wait_for_reply __P((int, struct sockaddr_in *));
+void send_probe __P((int, int));
+double deltaT __P((struct timeval *, struct timeval *));
+int packet_ok __P((u_char *, int, struct sockaddr_in *, int));
+void tvsub __P((struct timeval *, struct timeval *));
+
+int s; /* receive (icmp) socket file descriptor */
+int sndsock; /* send (udp) socket file descriptor */
+struct timezone tz; /* leftover */
+
+struct sockaddr whereto; /* Who to try to reach */
+int datalen; /* How much data */
+
+char *source = 0;
+char *hostname;
+
+int nprobes = 2;
+u_short ident;
+u_short port = 32768 + 666; /* start udp dest port # for probe packets */
+int options; /* socket options */
+int verbose;
+int waittime = 1; /* time to wait for response (in seconds) */
+int nflag; /* print addresses numerically */
+
+void find_route(u_int32_t destIP, u_int32_t IPlist[], int max_ttl) {
+ extern char *optarg;
+ extern int optind;
+ struct protoent *pe;
+ struct sockaddr_in from, *to;
+ int i, on, probe, seq, tos, ttl;
+
+ on = 1;
+ seq = tos = 0;
+ to = (struct sockaddr_in *) &whereto;
+ (void) bzero((char *) &whereto, sizeof(struct sockaddr));
+ to->sin_family = AF_INET;
+ to->sin_addr.s_addr = destIP;
+
+ datalen += sizeof(struct opacket);
+ outpacket = (struct opacket *) malloc((unsigned) datalen);
+ if (!outpacket) {
+ perror("traceroute: malloc");
+ exit(1);
+ }
+ (void) bzero((char *) outpacket, datalen);
+ outpacket->ip.ip_dst = to->sin_addr;
+ outpacket->ip.ip_tos = tos;
+ outpacket->ip.ip_v = IPVERSION;
+ outpacket->ip.ip_id = 0;
+
+ ident = (getpid() & 0xffff) | 0x8000;
+
+ if ((pe = getprotobyname("icmp")) == NULL) {
+ fprintf(stderr, "icmp: unknown protocol\n");
+ exit(10);
+ }
+ if ((s = socket(AF_INET, SOCK_RAW, pe->p_proto)) < 0) {
+ perror("traceroute: icmp socket");
+ exit(5);
+ }
+
+ if ((sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
+ perror("traceroute: raw socket");
+ exit(5);
+ }
+
+ if (source) {
+ (void) bzero((char *) &from, sizeof(struct sockaddr));
+ from.sin_family = AF_INET;
+ from.sin_addr.s_addr = inet_addr(source);
+ if (from.sin_addr.s_addr == -1) {
+ printf("traceroute: unknown host %s\n", source);
+ exit(1);
+ }
+ outpacket->ip.ip_src = from.sin_addr;
+#ifndef IP_HDRINCL
+ if (bind(sndsock, (struct sockaddr *) &from, sizeof(from)) < 0) {
+ perror("traceroute: bind:");
+ exit(1);
+ }
+#endif /* IP_HDRINCL */
+ }
+
+ for (ttl = 1; ttl <= max_ttl; ++ttl) {
+ u_long lastaddr = 0;
+ int got_there = 0;
+ int unreachable = 0;
+
+ for (probe = 0; probe < nprobes; ++probe) {
+ int cc;
+ struct timeval t1, t2;
+ struct timezone tz;
+ struct ip *ip;
+
+ (void) gettimeofday(&t1, &tz);
+ send_probe(++seq, ttl);
+ while ((cc = wait_for_reply(s, &from))) {
+ (void) gettimeofday(&t2, &tz);
+ if ((i = packet_ok(packet, cc, &from, seq))) {
+ if (from.sin_addr.s_addr != lastaddr) {
+ IPlist[ttl - 1] = from.sin_addr.s_addr;
+ lastaddr = from.sin_addr.s_addr;
+ }
+ log_println(5, "Probe %d resulted in reply from [%s]",
+ probe, inet_ntoa(from.sin_addr));
+
+ switch (i - 1) {
+ case ICMP_UNREACH_PORT:
+#ifndef ARCHAIC
+ ip = (struct ip *) packet;
+#endif /* ARCHAIC */
+ ++got_there;
+ break;
+ case ICMP_UNREACH_NET:
+ ++unreachable;
+ break;
+ case ICMP_UNREACH_HOST:
+ ++unreachable;
+ break;
+ case ICMP_UNREACH_PROTOCOL:
+ ++got_there;
+ break;
+ case ICMP_UNREACH_NEEDFRAG:
+ ++unreachable;
+ break;
+ case ICMP_UNREACH_SRCFAIL:
+ ++unreachable;
+ break;
+ }
+ break;
+ }
+ }
+ }
+ if (got_there || unreachable >= nprobes - 1) {
+ return;
+ }
+ }
+}
+
+int wait_for_reply(sock, from)
+ int sock;
+ struct sockaddr_in *from; {
+ fd_set fds;
+ struct timeval wait;
+ int cc = 0;
+ socklen_t fromlen = sizeof(*from);
+
+ FD_ZERO(&fds);
+ FD_SET(sock, &fds);
+ wait.tv_sec = waittime;
+ wait.tv_usec = 0;
+
+ if (select(sock + 1, &fds, (fd_set *) 0, (fd_set *) 0, &wait) > 0)
+ cc = recvfrom(s, (char *) packet, sizeof(packet), 0,
+ (struct sockaddr *) from, &fromlen);
+
+ return (cc);
+ }
+
+void send_probe(seq, ttl)
+ int seq, ttl; {
+ struct opacket *op = outpacket;
+ struct ip *ip = &op->ip;
+ struct udphdr *up = &op->udp;
+ int i;
+
+ ip->ip_off = 0;
+ ip->ip_hl = sizeof(*ip) >> 2;
+ ip->ip_p = IPPROTO_UDP;
+ ip->ip_len = datalen;
+ ip->ip_ttl = ttl;
+ ip->ip_v = IPVERSION;
+ ip->ip_id = htons(ident + seq);
+
+#ifdef __FAVOR_BSD
+ up->uh_sport = htons(ident);
+ up->uh_dport = htons(port+seq);
+ up->uh_ulen = htons((u_short)(datalen - sizeof(struct ip)));
+ up->uh_sum = 0;
+#else
+ up->source = htons(ident);
+ up->dest = htons(port + seq);
+ up->len = htons((u_short)(datalen - sizeof(struct ip)));
+ up->check = 0;
+#endif
+
+ op->seq = seq;
+ op->ttl = ttl;
+ (void) gettimeofday(&op->tv, &tz);
+
+ i = sendto(sndsock, (char *) outpacket, datalen, 0, &whereto,
+ sizeof(struct sockaddr));
+ if (i < 0 || i != datalen) {
+ if (i < 0)
+ perror("sendto");
+ }
+ }
+
+double deltaT(t1p, t2p)
+ struct timeval *t1p, *t2p; {
+ register double dt;
+
+ dt = (double) (t2p->tv_sec - t1p->tv_sec) * 1000.0
+ + (double) (t2p->tv_usec - t1p->tv_usec) / 1000.0;
+ return (dt);
+ }
+
+int packet_ok(buf, cc, from, seq)
+ u_char *buf;
+ int cc;
+ struct sockaddr_in *from;
+ int seq; {
+ register struct icmp *icp;
+ u_char type, code;
+ int hlen;
+#ifndef ARCHAIC
+ struct ip *ip;
+
+ ip = (struct ip *) buf;
+ hlen = ip->ip_hl << 2;
+ if (cc < hlen + ICMP_MINLEN) {
+ return (0);
+ }
+ cc -= hlen;
+ icp =
+ (struct icmp *) (buf + hlen);
+#else
+ icp = (struct icmp *)buf;
+#endif /* ARCHAIC */
+ type = icp->icmp_type;
+ code = icp->icmp_code;
+ if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) ||
+ type == ICMP_UNREACH) {
+ struct ip *hip;
+ struct udphdr *up;
+
+ hip = &icp->icmp_ip;
+ hlen = hip->ip_hl << 2;
+ up = (struct udphdr *)((u_char *)hip + hlen);
+ if (hlen + 12 <= cc && hip->ip_p == IPPROTO_UDP &&
+#ifdef __FAVOR_BSD
+ up->uh_sport == htons(ident) &&
+ up->uh_dport == htons(port+seq))
+#else
+ up->source == htons(ident) &&
+ up->dest == htons(port+seq))
+#endif
+ return (type == ICMP_TIMXCEED? -1 : code+1);
+ }
+ return(0)
+ ;}
+#ifdef notyet
+ /*
+ * Checksum routine for Internet Protocol family headers (C Version)
+ */
+ u_short
+in_cksum(addr, len)
+ u_short *addr;
+ int len;
+{
+ register int nleft = len;
+ register u_short *w = addr;
+ register u_short answer;
+ register int sum = 0;
+
+ /*
+ * Our algorithm is simple, using a 32 bit accumulator (sum),
+ * we add sequential 16 bit words to it, and at the end, fold
+ * back all the carry bits from the top 16 bits into the lower
+ * 16 bits.
+ */
+ while (nleft > 1) {
+ sum += *w++;
+ nleft -= 2;
+ }
+
+ /* mop up an odd byte, if necessary */
+ if (nleft == 1)
+ sum += *(u_char *)w;
+
+ /*
+ * add back carry outs from top 16 bits to low 16 bits
+ */
+ sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
+ sum += (sum >> 16); /* add carry */
+ answer = ~sum; /* truncate to 16 bits */
+ return (answer);
+}
+#endif /* notyet */
+
+/*
+ * Subtract 2 timeval structs: out = out - in.
+ * Out is assumed to be >= in.
+ */
+void tvsub(out, in)
+ register struct timeval *out, *in; {
+ if ((out->tv_usec -= in->tv_usec) < 0) {
+ out->tv_sec--;
+ out->tv_usec += 1000000;
+ }
+ out->tv_sec -= in->tv_sec;
+ }
=======================================
--- /dev/null
+++ /branches/Issue125/src/troute.h Tue Mar 11 08:31:04 2014 UTC
@@ -0,0 +1,14 @@
+/*
+ * This file contains the function declarations to handle troute.
+ *
+ * Jakub S³awiñski 2006-06-03
+ *
+ */
+
+#ifndef SRC_TROUTE_H_
+#define SRC_TROUTE_H_
+
+void find_route(u_int32_t destIP, u_int32_t IPlist[], int max_ttl);
+void find_route6(char* dst, u_int32_t IPlist[][4], int max_ttl);
+
+#endif // SRC_TROUTE_H_
=======================================
--- /dev/null
+++ /branches/Issue125/src/troute6.c Tue Mar 11 08:31:04 2014 UTC
@@ -0,0 +1,711 @@
+/*
+ * This is a modified version of traceroute6. It is designed to be
+ * a part of the Internet2 FLM system. It links into the fakewww
+ * server program and traces routes from the NDT server to the
+ * remote client. It returns a list of IP addresses found on this
+ * return path. This list will then be compared to the traceroute
+ * map generated by the tr-tree program.
+ *
+ * Jakub S³awiñski
+ *
+ */
+
+/*
+ * Modified for NRL 4.4BSD IPv6 release.
+ * 07/31/96 bgp
+ *
+ * Search for "#ifdef NRL" to find the changes.
+ */
+
+/*
+ * Modified for Linux IPv6 by Pedro Roque
<>
+ * 31/07/1996
+ *
+ * As ICMP error messages for IPv6 now include more than 8 bytes
+ * UDP datagrams are now sent via an UDP socket instead of magic
+ * RAW socket tricks.
+ *
+ * Original copyright and comments left intact. They might not
+ * match the code anymore.
+ */
+
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Van Jacobson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if 0
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1990, 1993\n"
+ "The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+#endif
+
+/*
+ * traceroute host - trace the route ip packets follow going to "host".
+ *
+ * Attempt to trace the route an ip packet would follow to some
+ * internet host. We find out intermediate hops by launching probe
+ * packets with a small ttl (time to live) then listening for an
+ * icmp "time exceeded" reply from a gateway. We start our probes
+ * with a ttl of one and increase by one until we get an icmp "port
+ * unreachable" (which means we got to "host") or hit a max (which
+ * defaults to 30 hops & can be changed with the -m flag). Three
+ * probes (change with -q flag) are sent at each ttl setting and a
+ * line is printed showing the ttl, address of the gateway and
+ * round trip time of each probe. If the probe answers come from
+ * different gateways, the address of each responding system will
+ * be printed. If there is no response within a 5 sec. timeout
+ * interval (changed with the -w flag), a "*" is printed for that
+ * probe.
+ *
+ * Probe packets are UDP format. We don't want the destination
+ * host to process them so the destination port is set to an
+ * unlikely value (if some clod on the destination is using that
+ * value, it can be changed with the -p flag).
+ *
+ * A sample use might be:
+ *
+ * [yak 71]% traceroute nis.nsf.net.
+ * traceroute to nis.nsf.net (35.1.1.48), 30 hops max, 56 byte packet
+ * 1 helios.ee.lbl.gov (128.3.112.1) 19 ms 19 ms 0 ms
+ * 2 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 39 ms 19 ms
+ * 3 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 39 ms 19 ms
+ * 4 ccngw-ner-cc.Berkeley.EDU (128.32.136.23) 39 ms 40 ms 39 ms
+ * 5 ccn-nerif22.Berkeley.EDU (128.32.168.22) 39 ms 39 ms 39 ms
+ * 6 128.32.197.4 (128.32.197.4) 40 ms 59 ms 59 ms
+ * 7 131.119.2.5 (131.119.2.5) 59 ms 59 ms 59 ms
+ * 8 129.140.70.13 (129.140.70.13) 99 ms 99 ms 80 ms
+ * 9 129.140.71.6 (129.140.71.6) 139 ms 239 ms 319 ms
+ * 10 129.140.81.7 (129.140.81.7) 220 ms 199 ms 199 ms
+ * 11 nic.merit.edu (35.1.1.48) 239 ms 239 ms 239 ms
+ *
+ * Note that lines 2 & 3 are the same. This is due to a buggy
+ * kernel on the 2nd hop system -- lbl-csam.arpa -- that forwards
+ * packets with a zero ttl.
+ *
+ * A more interesting example is:
+ *
+ * [yak 72]% traceroute allspice.lcs.mit.edu.
+ * traceroute to allspice.lcs.mit.edu (18.26.0.115), 30 hops max
+ * 1 helios.ee.lbl.gov (128.3.112.1) 0 ms 0 ms 0 ms
+ * 2 lilac-dmc.Berkeley.EDU (128.32.216.1) 19 ms 19 ms 19 ms
+ * 3 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 19 ms 19 ms
+ * 4 ccngw-ner-cc.Berkeley.EDU (128.32.136.23) 19 ms 39 ms 39 ms
+ * 5 ccn-nerif22.Berkeley.EDU (128.32.168.22) 20 ms 39 ms 39 ms
+ * 6 128.32.197.4 (128.32.197.4) 59 ms 119 ms 39 ms
+ * 7 131.119.2.5 (131.119.2.5) 59 ms 59 ms 39 ms
+ * 8 129.140.70.13 (129.140.70.13) 80 ms 79 ms 99 ms
+ * 9 129.140.71.6 (129.140.71.6) 139 ms 139 ms 159 ms
+ * 10 129.140.81.7 (129.140.81.7) 199 ms 180 ms 300 ms
+ * 11 129.140.72.17 (129.140.72.17) 300 ms 239 ms 239 ms
+ * 12 * * *
+ * 13 128.121.54.72 (128.121.54.72) 259 ms 499 ms 279 ms
+ * 14 * * *
+ * 15 * * *
+ * 16 * * *
+ * 17 * * *
+ * 18 ALLSPICE.LCS.MIT.EDU (18.26.0.115) 339 ms 279 ms 279 ms
+ *
+ * (I start to see why I'm having so much trouble with mail to
+ * MIT.) Note that the gateways 12, 14, 15, 16 & 17 hops away
+ * either don't send ICMP "time exceeded" messages or send them
+ * with a ttl too small to reach us. 14 - 17 are running the
+ * MIT C Gateway code that doesn't send "time exceeded"s. God
+* only knows what's going on with 12.
+*
+ * The silent gateway 12 in the above may be the result of a bug in
+* the 4.[23]BSD network code (and its derivatives): 4.x (x <= 3)
+ * sends an unreachable message using whatever ttl remains in the
+ * original datagram. Since, for gateways, the remaining ttl is
+ * zero, the icmp "time exceeded" is guaranteed to not make it back
+ * to us. The behavior of this bug is slightly more interesting
+ * when it appears on the destination system:
+ *
+ * 1 helios.ee.lbl.gov (128.3.112.1) 0 ms 0 ms 0 ms
+ * 2 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 19 ms 39 ms
+ * 3 lilac-dmc.Berkeley.EDU (128.32.216.1) 19 ms 39 ms 19 ms
+ * 4 ccngw-ner-cc.Berkeley.EDU (128.32.136.23) 39 ms 40 ms 19 ms
+ * 5 ccn-nerif35.Berkeley.EDU (128.32.168.35) 39 ms 39 ms 39 ms
+ * 6 csgw.Berkeley.EDU (128.32.133.254) 39 ms 59 ms 39 ms
+ * 7 * * *
+ * 8 * * *
+ * 9 * * *
+ * 10 * * *
+ * 11 * * *
+ * 12 * * *
+ * 13 rip.Berkeley.EDU (128.32.131.22) 59 ms ! 39 ms ! 39 ms !
+ *
+ * Notice that there are 12 "gateways" (13 is the final
+ * destination) and exactly the last half of them are "missing".
+ * What's really happening is that rip (a Sun-3 running Sun OS3.5)
+ * is using the ttl from our arriving datagram as the ttl in its
+ * icmp reply. So, the reply will time out on the return path
+ * (with no notice sent to anyone since icmp's aren't sent for
+ * icmp's) until we probe with a ttl that's at least twice the path
+ * length. I.e., rip is really only 7 hops away. A reply that
+ * returns with a ttl of 1 is a clue this problem exists.
+ * Traceroute prints a "!" after the time if the ttl is <= 1.
+ * Since vendors ship a lot of obsolete (DEC's Ultrix, Sun 3.x) or
+ * non-standard (HPUX) software, expect to see this problem
+ * frequently and/or take care picking the target host of your
+ * probes.
+ *
+ * Other possible annotations after the time are !H, !N, !P (got a host,
+ * network or protocol unreachable, respectively), !S or !F (source
+ * route failed or fragmentation needed -- neither of these should
+ * ever occur and the associated gateway is busted if you see one). If
+ * almost all the probes result in some kind of unreachable, traceroute
+ * will give up and exit.
+ *
+ * Notes
+ * -----
+ * This program must be run by root or be setuid. (I suggest that
+ * you *don't* make it setuid -- casual use could result in a lot
+ * of unnecessary traffic on our poor, congested nets.)
+ *
+ * This program requires a kernel mod that does not appear in any
+ * system available from Berkeley: A raw ip socket using proto
+ * IPPROTO_RAW must interpret the data sent as an ip datagram (as
+ * opposed to data to be wrapped in a ip datagram). See the README
+ * file that came with the source to this program for a description
+ * of the mods I made to /sys/netinet/raw_ip.c. Your mileage may
+ * vary. But, again, ANY 4.x (x < 4) BSD KERNEL WILL HAVE TO BE
+ * MODIFIED TO RUN THIS PROGRAM.
+ *
+ * The udp port usage may appear bizarre (well, ok, it is bizarre).
+ * The problem is that an icmp message only contains 8 bytes of
+ * data from the original datagram. 8 bytes is the size of a udp
+ * header so, if we want to associate replies with the original
+ * datagram, the necessary information must be encoded into the
+ * udp header (the ip id could be used but there's no way to
+ * interlock with the kernel's assignment of ip id's and, anyway,
+ * it would have taken a lot more kernel hacking to allow this
+ * code to set the ip id). So, to allow two or more users to
+ * use traceroute simultaneously, we use this task's pid as the
+ * source port (the high bit is set to move the port number out
+ * of the "likely" range). To keep track of which probe is being
+ * replied to (so times and/or hop counts don't get confused by a
+ * reply that was delayed in transit), we increment the destination
+ * port number before each probe.
+ *
+ * Don't use this as a coding example. I was trying to find a
+ * routing problem and this code sort-of popped out after 48 hours
+ * without sleep. I was amazed it ever compiled, much less ran.
+ *
+ * I stole the idea for this program from Steve Deering. Since
+ * the first release, I've learned that had I attended the right
+ * IETF working group meetings, I also could have stolen it from Guy
+ * Almes or Matt Mathis. I don't know (or care) who came up with
+ * the idea first. I envy the originators' perspicacity and I'm
+ * glad they didn't keep the idea a secret.
+ *
+ * Tim Seaver, Ken Adelman and C. Philip Wood provided bug fixes and/or
+ * enhancements to the original distribution.
+ *
+ * I've hacked up a round-trip-route version of this that works by
+ * sending a loose-source-routed udp datagram through the destination
+ * back to yourself. Unfortunately, SO many gateways botch source
+ * routing, the thing is almost worthless. Maybe one day...
+ *
+ * -- Van Jacobson
()
+ * Tue Dec 20 03:50:13 PST 1988
+ */
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+
+#if __linux__
+#include <endian.h>
+#endif
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/udp.h>
+
+#ifdef AF_INET6
+#include <asm/byteorder.h>
+#include <linux/icmpv6.h>
+
+#include <arpa/inet.h>
+
+#include <netdb.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "logging.h"
+
+#define MAXPACKET 65535
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 64
+#endif
+
+#ifndef FD_SET
+#define NFDBITS (8*sizeof(fd_set))
+#define FD_SETSIZE NFDBITS
+#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+#define FD_ZERO(p) bzero((char *)(p), sizeof(*(p)))
+#endif
+
+#define Fprintf (void)fprintf
+#define Printf (void)printf
+
+/* taken from linux/ipv6.h */
+
+/*
+* IPv6 fixed header
+*
+* BEWARE, it is incorrect. The first 4 bits of flow_lbl
+* are glued to priority now, forming "class".
+*/
+
+struct ipv6hdr {
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ __extension__ __u8 priority:4,
+ version:4;
+#elif defined(__BIG_ENDIAN_BITFIELD)
+ __extension__ __u8 version:4,
+ priority:4;
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+ __extension__ __u8 flow_lbl[3];
+
+ __extension__ __u16 payload_len;
+ __extension__ __u8 nexthdr;
+ __extension__ __u8 hop_limit;
+
+ struct in6_addr saddr;
+ struct in6_addr daddr;
+};
+
+/* --- */
+
+u_char packet[512]; /* last inbound (icmp) packet */
+
+int wait_for_reply6(int, struct sockaddr_in6 *, int);
+int packet_ok6(u_char *buf, int cc, struct sockaddr_in6 *from, int seq,
+ struct timeval *);
+void send_probe6(int seq, int ttl);
+double deltaT(struct timeval *, struct timeval *);
+void tvsub(struct timeval *, struct timeval *);
+void usage(void);
+
+int icmp_sock; /* receive (icmp) socket file descriptor */
+int sndsock; /* send (udp) socket file descriptor */
+struct timezone tz; /* leftover */
+
+struct sockaddr_in6 whereto; /* Who to try to reach */
+
+struct sockaddr_in6 saddr;
+struct sockaddr_in6 firsthop;
+char *source6 = NULL;
+char *device = NULL;
+char *hostname;
+
+int nprobes6 = 2;
+pid_t ident;
+u_short port6 = 32768+666; /* start udp dest port # for probe packets */
+int options; /* socket options */
+int verbose;
+int waittime6 = 5; /* time to wait for response (in seconds) */
+int nflag; /* print addresses numerically */
+
+struct pkt_format {
+ __u32 ident;
+ __u32 seq;
+ struct timeval tv;
+};
+
+char *sendbuff;
+int datalen = sizeof(struct pkt_format);
+
+void find_route6(char* dst, u_int32_t IPlist[][4], int max_ttl) {
+ extern char *optarg;
+ extern int optind;
+ struct hostent *hp;
+ struct sockaddr_in6 from, *to;
+ int i, on, probe, seq, tos, ttl;
+ int socket_errno;
+
+ icmp_sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
+ socket_errno = errno;
+
+ setuid(getuid());
+
+ on = 1;
+ seq = tos = 0;
+ to = (struct sockaddr_in6 *)&whereto;
+ (void) bzero((char *)&whereto, sizeof(whereto));
+
+ to->sin6_family = AF_INET6;
+ to->sin6_port = htons(port6);
+
+ if (inet_pton(AF_INET6, dst, &to->sin6_addr) > 0) {
+ hostname = dst;
+ } else {
+ hp = gethostbyname2(dst, AF_INET6);
+ if (hp) {
+ memmove((caddr_t)&to->sin6_addr, hp->h_addr, sizeof(to->sin6_addr));
+ hostname = (char *)hp->h_name;
+ } else {
+ (void)fprintf(stderr,
+ "traceroute: unknown host %s\n", dst);
+ return;
+ }
+ }
+ firsthop = *to;
+
+ ident = (getpid() & 0xffff) | 0x8000;
+
+ sendbuff = malloc(datalen);
+ if (sendbuff == NULL) {
+ fprintf(stderr, "malloc failed\n");
+ return;
+ }
+
+ if (icmp_sock < 0) {
+ errno = socket_errno;
+ perror("traceroute6: icmp socket");
+ return;
+ }
+
+ if (options & SO_DEBUG)
+ setsockopt(icmp_sock, SOL_SOCKET, SO_DEBUG,
+ (char *)&on, sizeof(on));
+ if (options & SO_DONTROUTE)
+ setsockopt(icmp_sock, SOL_SOCKET, SO_DONTROUTE,
+ (char *)&on, sizeof(on));
+ on = 2;
+ if (setsockopt(icmp_sock, SOL_RAW, IPV6_CHECKSUM, &on, sizeof(on)) < 0) {
+ perror("setsockopt(RAW_CHECKSUM)");
+ return;
+ }
+
+ if ((sndsock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
+ perror("traceroute: UDP socket");
+ return;
+ }
+#ifdef SO_SNDBUF
+ if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&datalen,
+ sizeof(datalen)) < 0) {
+ perror("traceroute: SO_SNDBUF");
+ return;
+ }
+#endif /* SO_SNDBUF */
+
+ if (options & SO_DEBUG)
+ (void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG,
+ (char *)&on, sizeof(on));
+ if (options & SO_DONTROUTE)
+ (void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE,
+ (char *)&on, sizeof(on));
+
+ if (source6 == NULL) {
+ socklen_t alen;
+ int probe_fd = socket(AF_INET6, SOCK_DGRAM, 0);
+
+ if (probe_fd < 0) {
+ perror("socket");
+ return;
+ }
+ if (device) {
+ if (setsockopt(probe_fd, SOL_SOCKET, SO_BINDTODEVICE, device,
+ strlen(device)+1) == -1) {
+ perror("WARNING: interface is ignored");
+ }
+ }
+ firsthop.sin6_port = htons(1025);
+ if (connect(probe_fd, (struct sockaddr*)&firsthop,
+ sizeof(firsthop)) == -1) {
+ perror("connect");
+ return;
+ }
+ alen = sizeof(saddr);
+ if (getsockname(probe_fd, (struct sockaddr*)&saddr, &alen) == -1) {
+ perror("getsockname");
+ return;
+ }
+ saddr.sin6_port = 0;
+ close(probe_fd);
+ } else {
+ (void) bzero((char *)&saddr, sizeof(saddr));
+ saddr.sin6_family = AF_INET6;
+ if (inet_pton(AF_INET6, source6, &saddr.sin6_addr) < 0) {
+ Printf("traceroute: unknown addr %s\n", source6);
+ return;
+ }
+ }
+
+ if (bind(sndsock, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) {
+ perror("traceroute: bind sending socket");
+ return;
+ }
+ if (bind(icmp_sock, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) {
+ perror("traceroute: bind icmp6 socket");
+ return;
+ }
+
+ for (ttl = 1; ttl <= max_ttl; ++ttl) {
+ struct in6_addr lastaddr = { { {0, }}};
+ int got_there = 0;
+ int unreachable = 0;
+
+ /* Printf("%2d ", ttl); */
+ for (probe = 0; probe < nprobes6; ++probe) {
+ int cc, reset_timer;
+ struct timeval t1, t2;
+ struct timezone tz;
+
+ gettimeofday(&t1, &tz);
+ send_probe6(++seq, ttl);
+ reset_timer = 1;
+
+ while ((cc = wait_for_reply6(icmp_sock, &from, reset_timer)) != 0) {
+ gettimeofday(&t2, &tz);
+ if (cc > 0 && (i = packet_ok6(packet, cc, &from, seq, &t1))) {
+ reset_timer = 1;
+ if (memcmp(&from.sin6_addr, &lastaddr, sizeof(from.sin6_addr))) {
+ memcpy(IPlist[ttl-1],
+ &from.sin6_addr,
+ sizeof(IPlist[ttl-1]));
+ memcpy(&lastaddr,
+ &from.sin6_addr,
+ sizeof(lastaddr));
+ }
+ if (get_debuglvl() > 4) {
+ char tmp[MAXHOSTNAMELEN];
+ inet_ntop(AF_INET6, &from.sin6_addr, tmp, sizeof(tmp));
+ log_println(5, "Probe %d resulted in reply from [%s]", probe, tmp);
+ }
+ switch (i - 1) {
+ case ICMPV6_PORT_UNREACH:
+ ++got_there;
+ break;
+
+ case ICMPV6_NOROUTE:
+ ++unreachable;
+ Printf(" !N");
+ break;
+ case ICMPV6_ADDR_UNREACH:
+ ++unreachable;
+ Printf(" !H");
+ break;
+
+ case ICMPV6_ADM_PROHIBITED:
+ ++unreachable;
+ Printf(" !S");
+ break;
+ }
+ break;
+ } else {
+ reset_timer = 0;
+ }
+ }
+ if (cc <= 0)
+ Printf(" *");
+ (void) fflush(stdout);
+ }
+ if (got_there || (unreachable > 0 && unreachable >= nprobes6-1))
+ return;
+ }
+}
+
+ int
+wait_for_reply6(sock, from, reset_timer)
+ int sock;
+ struct sockaddr_in6 *from;
+ int reset_timer;
+{
+ fd_set fds;
+ static struct timeval wait;
+ int cc = 0;
+ socklen_t fromlen = sizeof(*from);
+
+ FD_ZERO(&fds);
+ FD_SET(sock, &fds);
+ if (reset_timer) {
+ /*
+ * traceroute could hang if someone else has a ping
+ * running and our ICMP reply gets dropped but we don't
+ * realize it because we keep waking up to handle those
+ * other ICMP packets that keep coming in. To fix this,
+ * "reset_timer" will only be true if the last packet that
+ * came in was for us or if this is the first time we're
+ * waiting for a reply since sending out a probe. Note
+ * that this takes advantage of the select() feature on
+ * Linux where the remaining timeout is written to the
+ * struct timeval area.
+ */
+ wait.tv_sec = waittime6;
+ wait.tv_usec = 0;
+ }
+
+ if (select(sock+1, &fds, (fd_set *)0, (fd_set *)0, &wait) > 0) {
+ cc = recvfrom(icmp_sock, (char *)packet, sizeof(packet), 0,
+ (struct sockaddr *)from, &fromlen);
+ }
+
+ return(cc);
+}
+
+void send_probe6(int seq, int ttl) {
+ struct pkt_format *pkt = (struct pkt_format *) sendbuff;
+ int i;
+
+ pkt->ident = htonl(ident);
+ pkt->seq = htonl(seq);
+ gettimeofday(&pkt->tv, &tz);
+
+ i = setsockopt(sndsock, SOL_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl));
+ if (i < 0) {
+ perror("setsockopt");
+ return;
+ }
+
+ do {
+ i = sendto(sndsock, sendbuff, datalen, 0,
+ (struct sockaddr *)&whereto, sizeof(whereto));
+ } while (i < 0 && errno == ECONNREFUSED);
+
+ if (i < 0 || i != datalen) {
+ if (i < 0)
+ perror("sendto");
+ }
+}
+
+/*
+ * Convert an ICMP "type" field to a printable string.
+ */
+char * pr_type(unsigned char t) {
+ static char *ttab1[] = {
+ "Error",
+ "Destination Unreachable",
+ "Packet Too Big",
+ "Time Exceeded in Transit",
+ "Parameter Problem"
+ };
+
+ static char *ttab2[] = {
+ "Echo Reply",
+ "Echo Request",
+ "Membership Query",
+ "Membership Report",
+ "Membership Reduction",
+ };
+
+ if (t < 5) {
+ return (ttab1[t]);
+ }
+
+ unsigned char newt = t - 128;
+ if (newt < 5) {
+ return (ttab2[newt]);
+ }
+
+ return("OUT-OF-RANGE");
+}
+
+int packet_ok6(u_char *buf, int cc, struct sockaddr_in6 *from, int seq,
+ struct timeval *tv) {
+ struct icmp6hdr *icp;
+ u_char type, code;
+
+ icp = (struct icmp6hdr *) buf;
+
+ type = icp->icmp6_type;
+ code = icp->icmp6_code;
+
+ if ((type == ICMPV6_TIME_EXCEED && code == ICMPV6_EXC_HOPLIMIT) ||
+ type == ICMPV6_DEST_UNREACH) {
+ struct ipv6hdr *hip;
+ struct udphdr *up;
+ int nexthdr;
+
+ hip = (struct ipv6hdr *) (icp + 1);
+ up = (struct udphdr *)(hip+1);
+ nexthdr = hip->nexthdr;
+
+ if (nexthdr == 44) {
+ nexthdr = *(unsigned char*)up;
+ up++;
+ }
+ if (nexthdr == IPPROTO_UDP) {
+ struct pkt_format *pkt;
+
+ pkt = (struct pkt_format *) (up + 1);
+
+ if (ntohl(pkt->ident) == ident &&
+ ntohl(pkt->seq) == seq) {
+ *tv = pkt->tv;
+ return (type == ICMPV6_TIME_EXCEED? -1 : code+1);
+ }
+ }
+ }
+
+ if (verbose) {
+ struct ipv6hdr *hip;
+ __u32 *lp;
+ char pa1[MAXHOSTNAMELEN];
+ char pa2[MAXHOSTNAMELEN];
+ int i;
+ hip = (struct ipv6hdr *) (icp + 1);
+ lp = (__u32 *) (icp + 1);
+
+ Printf("\n%d bytes from %s to %s", cc,
+ inet_ntop(AF_INET6, &hip->saddr, pa1, sizeof(pa1)),
+ inet_ntop(AF_INET6, &hip->daddr, pa2, sizeof(pa2)));
+
+ Printf(": icmp type %d (%s) code %d\n", type, pr_type(type),
+ icp->icmp6_code);
+
+ for (i = sizeof(struct ipv6hdr); i < cc; i += 4)
+ Printf("%2d: x%8.8x\n", i, *lp++);
+ }
+
+ return(0);
+}
+
+#endif
=======================================
--- /branches/Issue125/Makefile.am Thu Mar 6 13:23:58 2014 UTC
+++ /branches/Issue125/Makefile.am Tue Mar 11 08:31:04 2014 UTC
@@ -27,9 +27,6 @@
SUBDIRS += flash-client
endif
endif
-if BUILD_FAKEWWW
-SUBDIRS += fakewww
-endif
endif
EXTRA_DIST = admin_description.html admin.html \
=======================================
--- /branches/Issue125/configure.ac Thu Mar 6 13:23:58 2014 UTC
+++ /branches/Issue125/configure.ac Tue Mar 11 08:31:04 2014 UTC
@@ -340,7 +340,7 @@
AC_SUBST(ac_aux_dir)
AC_CONFIG_FILES([Makefile
src/Makefile Admin/Makefile Applet/Makefile
- conf/Makefile doc/Makefile janalyze/Makefile flash-client/Makefile fakewww/Makefile])
+ conf/Makefile doc/Makefile janalyze/Makefile
flash-client/Makefile])
AC_OUTPUT
echo ""
@@ -373,7 +373,9 @@
else
SUMMARY_WEB100SRV="NO (missing pcap headers)"
fi
-if test "x$enable_fakewww" != "xyes"; then
+if test "x$enable_fakewww" == "xno"; then
+SUMMARY_FAKEWWW="NO (disabled by user)"
+elif test "x$enable_fakewww" != "xyes"; then
SUMMARY_FAKEWWW="NO (disabled by default)"
else
SUMMARY_FAKEWWW="YES"
@@ -430,9 +432,7 @@
else
echo "*** Server Tools - incomplete"
fi
-if test "x$enable_fakewww" == "xyes"; then
echo "* fakewww: ${SUMMARY_FAKEWWW}"
-fi
echo "* web100srv: ${SUMMARY_WEB100SRV}"
echo "* web10gsrv: ${SUMMARY_WEB10GSRV}"
echo ""
=======================================
--- /branches/Issue125/src/Makefile.am Thu Mar 6 13:23:58 2014 UTC
+++ /branches/Issue125/src/Makefile.am Tue Mar 11 08:31:04 2014 UTC
@@ -22,10 +22,16 @@
ndtdir = $(prefix)/ndt
+if BUILD_FAKEWWW
+ADD_FAKEWWW = fakewww
+endif
+
if HAVE_WEB100
bin_PROGRAMS = web100clt analyze viewtrace tr-mkmap genplot
if HAVE_PCAP_H
-sbin_PROGRAMS = web100srv
+sbin_PROGRAMS = $(ADD_FAKEWWW) web100srv
+else
+sbin_PROGRAMS = $(ADD_FAKEWWW)
endif
else
bin_PROGRAMS = web100clt
@@ -36,7 +42,7 @@
if HAVE_WEB100
sbin_PROGRAMS += web10gsrv genplot10g
else
-sbin_PROGRAMS = web10gsrv genplot10g
+sbin_PROGRAMS = $(ADD_FAKEWWW) web10gsrv genplot10g
endif
endif
endif
@@ -60,6 +66,13 @@
analyze_LDADD = $(NDTLIBS) $(I2UTILLIBDEPS) $(ZLIB)
analyze_CPPFLAGS ='-DBASEDIR="$(ndtdir)"' -DFORCE_WEB100
+if BUILD_FAKEWWW
+fakewww_SOURCES = fakewww.c troute.c troute6.c tr-tree.c tr-tree6.c network.c usage.c logging.c \
+ runningtest.c ndtptestconstants.c strlutils.c
+fakewww_LDADD = $(I2UTILLIBDEPS) $(ZLIB)
+fakewww_CPPFLAGS ='-DBASEDIR="$(ndtdir)"'
+endif
+
web100srv_SOURCES = web100srv.c web100-util.c web100-pcap.c web100-admin.c runningtest.c \
network.c usage.c utils.c mrange.c logging.c testoptions.c ndtptestconstants.c \
protocol.c test_sfw_srv.c test_meta_srv.c ndt_odbc.c strlutils.c heuristics.c \
@@ -103,6 +116,6 @@
$(I2UTILLIBMAKE)
EXTRA_DIST = clt_tests.h logging.h mrange.h network.h protocol.h testoptions.h test_sfw.h test_meta.h \
- tr-tree.h usage.h utils.h varinfo.h web100-admin.h web100srv.h ndt_odbc.h runningtest.h ndtptestconstants.h \
+ troute.h tr-tree.h usage.h utils.h varinfo.h web100-admin.h web100srv.h ndt_odbc.h runningtest.h ndtptestconstants.h \
heuristics.h strlutils.h test_results_clt.h tests_srv.h
- [ndt-dev] [ndt] r1005 committed - Separate fakewww as individual subproject. By default fakewww is not b..., ndt, 03/11/2014
Archive powered by MHonArc 2.6.16.