From owner-freebsd-ports-bugs@FreeBSD.ORG Fri May 28 22:50:31 2004 Return-Path: Delivered-To: freebsd-ports-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 8DCB616A4CF for ; Fri, 28 May 2004 22:50:31 -0700 (PDT) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 820CD43D41 for ; Fri, 28 May 2004 22:50:31 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) i4T5oPuo005995 for ; Fri, 28 May 2004 22:50:25 -0700 (PDT) (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.11/8.12.11/Submit) id i4T5oPBS005994; Fri, 28 May 2004 22:50:25 -0700 (PDT) (envelope-from gnats) Resent-Date: Fri, 28 May 2004 22:50:25 -0700 (PDT) Resent-Message-Id: <200405290550.i4T5oPBS005994@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-ports-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Paul Chvostek Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 17B9616A4CE for ; Fri, 28 May 2004 22:49:22 -0700 (PDT) Received: from haggis.it.ca (haggis.it.ca [216.126.86.9]) by mx1.FreeBSD.org (Postfix) with ESMTP id 92D6A43D2F for ; Fri, 28 May 2004 22:49:21 -0700 (PDT) (envelope-from paul@foo.it.ca) Received: from foo.it.ca (play [10.4.1.4]) by haggis.it.ca (8.12.11/8.12.11) with ESMTP id i4T5nD1u047874; Sat, 29 May 2004 01:49:13 -0400 (EDT) (envelope-from paul@foo.it.ca) Received: from foo.it.ca (localhost [127.0.0.1]) by foo.it.ca (8.12.10/8.12.6) with ESMTP id i4T5nDqC000779; Sat, 29 May 2004 01:49:13 -0400 (EDT) (envelope-from paul@foo.it.ca) Received: (from paul@localhost) by foo.it.ca (8.12.10/8.12.6/Submit) id i4T5nC1H000778; Sat, 29 May 2004 01:49:12 -0400 (EDT) Message-Id: <200405290549.i4T5nC1H000778@foo.it.ca> Date: Sat, 29 May 2004 01:49:12 -0400 (EDT) From: Paul Chvostek To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 cc: Paul Chvostek Subject: ports/67327: New port: net-mgmt/rotorouter - fake traceroute X-BeenThere: freebsd-ports-bugs@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list Reply-To: Paul Chvostek List-Id: Ports bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 29 May 2004 05:50:31 -0000 >Number: 67327 >Category: ports >Synopsis: New port: net-mgmt/rotorouter - fake traceroute >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-ports-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Fri May 28 22:50:24 PDT 2004 >Closed-Date: >Last-Modified: >Originator: Paul Chvostek >Release: FreeBSD 4.10-PRERELEASE i386 >Organization: >Environment: System: FreeBSD foo.it.ca 4.10-PRERELEASE FreeBSD 4.10-PRERELEASE #1: Sat May 1 23:10:02 EDT 2004 paul@foo.it.ca:/usr/obj/usr/src/sys/foo i386 >Description: Responds to traceroutes with "fake" path info, written by Julian Assange. No original source seems to exist for this, and Julian doesn't seem reachable. Firewall rules are required to actually make this thing work, but they depend on the targets you specify in your config file. The wish list includes some documentation. >How-To-Repeat: >Fix: --- rotorouter.shar begins here --- # This is a shell archive. Save it in a file, remove anything before # this line, and then unpack it by entering "sh file". Note, it may # create directories; files and directories will be owned by you and # have default permissions. # # This archive contains: # # rotorouter # rotorouter/pkg-plist # rotorouter/pkg-message # rotorouter/pkg-descr # rotorouter/Makefile # rotorouter/src # rotorouter/src/rotorouter.c # rotorouter/src/rotorouter.conf-example # rotorouter/src/rotorouter.sh # echo c - rotorouter mkdir -p rotorouter > /dev/null 2>&1 echo x - rotorouter/pkg-plist sed 's/^X//' >rotorouter/pkg-plist << 'END-of-rotorouter/pkg-plist' Xsbin/rotorouter Xetc/rc.d/rotorouter.sh X@unexec if [ -f %D/etc/rotorouter.conf ] && cmp -s %D/etc/rotorouter.conf %D/etc/rotorouter.conf-example; then rm -f %D/etc/rotorouter.conf; fi Xetc/rotorouter.conf-example END-of-rotorouter/pkg-plist echo x - rotorouter/pkg-message sed 's/^X//' >rotorouter/pkg-message << 'END-of-rotorouter/pkg-message' X======================================================================== X NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE X======================================================================== X XThe rotorouter port has been installed with an example configuration Xfile, located at %%PREFIX%%/etc/rotorouter.conf-example. X XYou need to build your own config file using local network information. X X======================================================================== END-of-rotorouter/pkg-message echo x - rotorouter/pkg-descr sed 's/^X//' >rotorouter/pkg-descr << 'END-of-rotorouter/pkg-descr' XA program for faking the standard unix udp-based traceroute. X XWWW: http://www.ussrback.com/UNIX/loggers/fakeroute.c X X- Paul Chvostek END-of-rotorouter/pkg-descr echo x - rotorouter/Makefile sed 's/^X//' >rotorouter/Makefile << 'END-of-rotorouter/Makefile' X# New ports collection makefile for: rotorouter X# Date created: Sat May 29 01:30:43 EDT 2004 X# Whom: Paul Chvostek X# X# $FreeBSD$ X# X# This port is self-contained in the src directory. X# X XPORTNAME= rotorouter XPORTVERSION= 1.0 XCATEGORIES= net-mgmt XMASTER_SITES= # nada XDISTFILES= # nil X XMAINTAINER= paul+ports@it.ca XCOMMENT= Traceroute log and fake X XNO_WRKSUBDIR= yes X XSRC= ${.CURDIR}/src X XSED_SCRIPT+= -e 's,%%PREFIX%%,${PREFIX},g' \ X -e 's,%%RC_SUBR%%,${RC_SUBR},g' X X.include X X.if ${OSVERSION} >= 500038 XRC_SUBR?= /etc/rc.subr X.else XUSE_RC_SUBR= yes X.endif X Xdo-fetch: X @${DO_NADA} X Xdo-build: X ${CC} -lpcap -o ${WRKSRC}/rotorouter ${SRC}/rotorouter.c X ${SED} ${SED_SCRIPT} < ${SRC}/rotorouter.sh > ${WRKSRC}/rotorouter.sh X Xdo-install: X @${INSTALL_DATA} -m 640 ${SRC}/rotorouter.conf-example ${PREFIX}/etc/ X @${INSTALL_DATA} -m 640 ${SRC}/rotorouter.conf-example ${PREFIX}/etc/rotorouter.conf X @${INSTALL_PROGRAM} ${WRKSRC}/rotorouter ${PREFIX}/sbin/ X @${INSTALL_SCRIPT} -m 751 ${WRKSRC}/rotorouter.sh ${PREFIX}/etc/rc.d/rotorouter.sh X Xpost-install: X @${SED} ${SED_SCRIPT} < ${PKGMESSAGE} X X.include END-of-rotorouter/Makefile echo c - rotorouter/src mkdir -p rotorouter/src > /dev/null 2>&1 echo x - rotorouter/src/rotorouter.c sed 's/^X//' >rotorouter/src/rotorouter.c << 'END-of-rotorouter/src/rotorouter.c' X/* fakeroute (c) 1996 Julian Assange X * All Rights Reserved X * X * config file ("hops" by default) contains tuples like thus: X XDest IP Hop Fake router ms latency X203.4.184.222 0 204.70.10.250 5 X203.4.184.222 1 204.70.10.250 10 X203.4.184.222 2 198.32.136.88 15 X203.4.184.222 3 137.209.200.202 20 X203.4.184.222 4 137.209.60.1 25 X203.4.184.222 5 198.26.127.26 30 X203.4.184.222 -1 203.4.184.222 35 X203.4.184.217 0 204.70.10.250 5 X203.4.184.217 1 204.70.10.250 10 X203.4.184.217 2 198.32.136.88 15 X203.4.184.217 3 137.209.200.202 20 X203.4.184.217 4 137.209.60.1 25 X203.4.184.217 5 198.26.127.26 30 X203.4.184.217 -1 203.4.184.222 35 X*/ X X#include X#include X#include X#include X X#include X X#include X#include X#include X X#include X#include X#include X#include X#include X X#include X X#include X X#define bool int X#define TRUE 1 X#define FALSE 0 X X#define ENDIAN_RAW_BUG 1 X Xtypedef u_short port_t; X Xpcap_t *pd; Xstruct bpf_program fcode; Xu_char *pcap_userdata; Xstruct in_addr localnet, netmask; Xchar ebuf[PCAP_ERRBUF_SIZE]; Xint raw; Xint a_max_ttl = 1; Xint a_timeout = 300; Xint a_verbose = 0; X Xvoid ether_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p); Xvoid ppp_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p); Xvoid analyze_udp(struct ip *ip); X Xstruct hop X{ X struct hop *next; X struct in_addr dst, hop; X int latency; /* delay */ X int ttl; X}; Xstruct hop *hops; X Xstruct udp_state X{ X struct udp_state *next; X struct in_addr src, dst; X port_t sport; X time_t last_packet; X}; X Xstruct udp_state *state; Xstruct udp_state *queue; X Xvoid Xpexit(char *err) X{ X perror(err); X exit(1); X} X Xvoid Xeexit(char *err) X{ X fprintf(stderr, "fatal error: %s\n", err); X exit(1); X} X Xvoid * Xxmalloc(int n) X{ X void *p=malloc(n); X if (!p) X pexit("malloc"); X return p; X} X Xu_short Xfast_icmp_cksum(struct icmp *icmp) /* well, for C anyway.. */ X{ X register u_short *u = (u_short *)icmp; X register int sum = 0; X X sum = *u++; X u++; /* skip checksum */ X sum += *u++; X sum += *u++; X sum += *u++; X sum += *u++; X sum += *u++; X sum += *u++; X sum += *u++; X sum += *u++; X sum += *u++; X sum += *u++; X sum += *u++; X sum += *u++; X sum += *u++; X sum += *u++; X sum += *u++; X sum += *u; X sum = (sum >> 16) + (sum & 0xffff); /* fold accumulated carries */ X sum += sum>>16; X return (u_short) ~sum; X} X Xstruct printer X{ X pcap_handler f; X int type; X}; X X/* XXX needed if using old bpf.h */ X#ifndef DLT_ATM_RFC1483 X#define DLT_ATM_RFC1483 11 X#endif X Xstatic struct printer printers[] = X{ X { ether_if_print, DLT_EN10MB }, X { ether_if_print, DLT_IEEE802 }, X/* X { sl_if_print, DLT_SLIP }, X*/ X { ppp_if_print, DLT_PPP }, X/* X { fddi_if_print, DLT_FDDI }, X { null_if_print, DLT_NULL }, X { atm_if_print, DLT_ATM_RFC1483 }, X*/ X { NULL, 0 }, X}; X Xstatic pcap_handler Xlookup_printer(int type) X{ X struct printer *p; X X for (p = printers; p->f; ++p) X if (type == p->type) X return p->f; X X fprintf(stderr, "unknown data link type 0x%x", type); X exit(1); X /* NOTREACHED */ X} X Xvoid Xopen_pcap(char *dev, bool f_promisc, char *filt, int usec) X{ X if (!dev) X { X dev = pcap_lookupdev(ebuf); X if (!dev) X eexit(ebuf); X } X pd = pcap_open_live(dev, 96, f_promisc, usec, ebuf); X if (!pd) X eexit(ebuf); X if (pcap_lookupnet(dev, &localnet.s_addr, &netmask.s_addr, ebuf) < 0) X eexit(ebuf); X if (pcap_compile(pd, &fcode, filt, 1, (u_long)netmask.s_addr) < 0) X eexit(pcap_geterr(pd)); X if (pcap_setfilter(pd, &fcode) < 0) X eexit(pcap_geterr(pd)); X} X Xvoid Xether_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) X{ X p += 14; X analyze_udp((struct ip *)p); X} X Xvoid Xppp_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) X{ X p += 4; X analyze_udp((struct ip *)p); X} X X Xstruct hop * Xfind_hop(struct in_addr dst, int ttl) X{ X struct hop *p, *ret=NULL; X for (p = hops; p; p=p->next) X { X if (p->dst.s_addr == dst.s_addr) X { X if (p->ttl == ttl) X return p; X if (p->ttl == -1) X ret = p; X } X } X return ret; X} X Xvoid Xicmp_reply(struct ip *iip, struct hop *hop) X{ X char buf[sizeof(struct ip) + sizeof(struct icmp) + 8]; X struct ip *ip =(struct ip *)buf; X struct icmp *i =(struct icmp *)(buf+sizeof(struct ip)); X static u_short ip_id; X bool f_dest = (hop->ttl == -1); X struct sockaddr_in in; X int len = sizeof (struct ip) + sizeof (struct icmp) + 8; /* don't bother with the options */ X memset(&in, 0, sizeof in); X in.sin_family = AF_INET; X ip->ip_hl = sizeof (struct ip) / 4; X ip->ip_v = 4; X ip->ip_tos = 0; X ip->ip_len = ENDIAN_RAW_BUG? len: htons(len); X ip->ip_id = htons(ip_id++); X ip->ip_off = 0; X ip->ip_ttl = 255; X ip->ip_p = IPPROTO_ICMP; X ip->ip_dst = in.sin_addr = iip->ip_src; X ip->ip_src = hop->hop; X ip->ip_sum = 0; /* let the os calculate it */ X i->icmp_type = f_dest? ICMP_UNREACH: ICMP_TIMXCEED; X i->icmp_code = f_dest? ICMP_UNREACH_PORT: ICMP_TIMXCEED_INTRANS; X memcpy(&i->icmp_ip, iip, sizeof (struct ip)+8); X i->icmp_cksum = fast_icmp_cksum(i); X if (a_verbose>0) X { X printf("rotorouter: sending %s %s", X f_dest? "ICMP_UNREACH_PORT": "ICMP_TIMXCEED", X inet_ntoa(ip->ip_src)); X printf(" -> %s for ttl %d\n", X inet_ntoa(ip->ip_dst), X iip->ip_ttl); X } X usleep(hop->latency); X if (sendto (raw, ip, len, 0, (struct sockaddr *)&in, sizeof in)!=len) X pexit("sendto"); X} X Xvoid Xanalyze_udp(struct ip *ip) X{ X struct udphdr *u; X struct hop *hop; X struct udp_state *p; X static time_t lastclean; X time_t t; X u = (struct udphdr *)((char *)ip+ip->ip_hl*4); X hop = find_hop(ip->ip_dst, ip->ip_ttl); X if (!hop) X return; X for (p = state; p; p = p->next) X { X if (p->src.s_addr == ip->ip_src.s_addr && X p->sport == u->uh_sport && X p->dst.s_addr == ip->ip_dst.s_addr) X goto found; X } X if (ip->ip_ttl > a_max_ttl) X return; X p = xmalloc(sizeof *p); X p->next = state; X p->src = ip->ip_src; X p->dst = ip->ip_dst; X p->sport = u->uh_sport; X state = p; Xfound: X p->last_packet = t = time(NULL); X icmp_reply(ip, hop); X if (t > lastclean+10) X { X struct udp_state *prev = NULL; X for (p=state; p;) X { X if (t > p->last_packet + a_timeout) X { X struct udp_state *p2 = p->next; X if (prev) X prev->next = p->next; X else X state = NULL; X free (p); X p = p2; X } else X { X prev = p; X p = p->next; X } X } X } X} X Xvoid Xopen_raw() X{ X int yes = 1; X raw = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); X if (raw<0) X pexit("socket"); X if (setsockopt(raw, IPPROTO_IP, IP_HDRINCL, (char *)&yes, sizeof(yes)) < 0) X pexit("IP_HDRINCL"); X} X Xvoid Xpopulate_hops(char *fn) X{ X FILE *fh; X char host[32]; X char hop[32]; X struct hop *p; X int latency; X int ttl; X int rules; X fh = fopen(fn, "r"); X if (!fh) X pexit(fn); X for (rules = 0; fscanf(fh, "%16s %d %16s %d%*[^\r\n]", host, &ttl, hop, &latency) == 4; rules++) X { X struct in_addr hostaddr, hopaddr; X hostaddr.s_addr = inet_addr(host); X if (hostaddr.s_addr == 0xffffffff) X { X fprintf(stderr, "bad address: %s\n", host); X exit(1); X } X hopaddr.s_addr = inet_addr(hop); X if (hopaddr.s_addr == 0xffffffff) X { X fprintf(stderr, "bad address: %s\n", hop); X exit(1); X } X p = malloc(sizeof *p); X p->dst = hostaddr; X p->hop = hopaddr; X p->ttl = ttl; X p->latency = latency; X p->next = hops; X hops = p; X X } X fprintf(stderr, "%d rotorouter rules loaded\n", rules); X} X Xvoid Xusage(char *av0) X{ X exit(1); X} X Xint Xmain(int argc, char **argv) X{ X int c; X pcap_handler printer; X char *a_iface = NULL; X char *a_filter = "udp"; X char *a_hops = "hops"; X int a_usec = 50; X bool f_promisc = TRUE; X while ((c=getopt(argc, argv, "i:ph:u:n:v"))!=-1) X { X switch(c) X { X case 'i': X a_iface = optarg; X break; X case 'p': X f_promisc = FALSE; X break; X case 'h': X a_hops = optarg; X break; X case 'u': X a_usec = atoi(optarg); X break; X case 't': X a_max_ttl = atoi(optarg); X break; X case 'n': X a_timeout = atoi(optarg); X break; X case 'v': X a_verbose++; X break; X default: X usage(argv[0]); X /* NOT REACHED */ X } X } X populate_hops(a_hops); X open_pcap(a_iface, f_promisc, a_filter, a_usec); X printer = lookup_printer(pcap_datalink(pd)); X open_raw(); X if (pcap_loop(pd, 0, printer, NULL) < 0) X { X fprintf(stderr, "%s: pcap_loop: %s\n", X argv[0], pcap_geterr(pd)); X exit(1); X } X pcap_close(pd); X exit(0); X} END-of-rotorouter/src/rotorouter.c echo x - rotorouter/src/rotorouter.conf-example sed 's/^X//' >rotorouter/src/rotorouter.conf-example << 'END-of-rotorouter/src/rotorouter.conf-example' X137.39.1.3 0 10.1.0.1 5 X137.39.1.3 1 10.2.0.2 10 X137.39.1.3 2 172.31.1.1 10 X137.39.1.3 -1 172.31.1.2 15 END-of-rotorouter/src/rotorouter.conf-example echo x - rotorouter/src/rotorouter.sh sed 's/^X//' >rotorouter/src/rotorouter.sh << 'END-of-rotorouter/src/rotorouter.sh' X#!/bin/sh X# X# $Id$ X# X X# PROVIDE: rotorouter X# REQUIRE: DAEMON X# BEFORE: LOGIN X# KEYWORD: FreeBSD shutdown X# X# Add the following lines to /etc/rc.conf to enable rotorouter: X# X# rotorouter_enable="YES" X# X# See rotorouter(8) for flags. X# X X. %%RC_SUBR%% X Xname=rotorouter Xrcvar=`set_rcvar` X Xcommand=%%PREFIX%%/sbin/${name} X X# set defaults X Xrotorouter_enable=${rotorouter_enable:-"NO"} Xrotorouter_flags="${rotorouter_flags:--h %%PREFIX%%/etc/rotorouter.conf}" X Xrotorouter_flags="${rotorouter_flags} &" X Xload_rc_config $name Xrun_rc_command "$1" X END-of-rotorouter/src/rotorouter.sh exit --- rotorouter.shar ends here --- >Release-Note: >Audit-Trail: >Unformatted: