From 643a3e07da92388e2536cd76a3901cb3a8da820c Mon Sep 17 00:00:00 2001 From: Bruce M Simpson Date: Mon, 14 Jun 2004 16:56:13 +0000 Subject: Committed (with some fixups), thanks! PR: ports/67327 Submitted by: Paul Chvostek --- net-mgmt/rotorouter/Makefile | 45 +++ net-mgmt/rotorouter/files/rotorouter.c | 434 ++++++++++++++++++++++ net-mgmt/rotorouter/files/rotorouter.conf-example | 4 + net-mgmt/rotorouter/files/rotorouter.sh | 34 ++ net-mgmt/rotorouter/pkg-descr | 5 + net-mgmt/rotorouter/pkg-message | 10 + net-mgmt/rotorouter/pkg-plist | 3 + 7 files changed, 535 insertions(+) create mode 100644 net-mgmt/rotorouter/Makefile create mode 100644 net-mgmt/rotorouter/files/rotorouter.c create mode 100644 net-mgmt/rotorouter/files/rotorouter.conf-example create mode 100644 net-mgmt/rotorouter/files/rotorouter.sh create mode 100644 net-mgmt/rotorouter/pkg-descr create mode 100644 net-mgmt/rotorouter/pkg-message create mode 100644 net-mgmt/rotorouter/pkg-plist (limited to 'net-mgmt/rotorouter') diff --git a/net-mgmt/rotorouter/Makefile b/net-mgmt/rotorouter/Makefile new file mode 100644 index 000000000000..c26c404ef6c5 --- /dev/null +++ b/net-mgmt/rotorouter/Makefile @@ -0,0 +1,45 @@ +# New ports collection makefile for: rotorouter +# Date created: Sat May 29 01:30:43 EDT 2004 +# Whom: Paul Chvostek +# +# $FreeBSD$ +# +# This port is self-contained in the src directory. +# + +PORTNAME= rotorouter +PORTVERSION= 1.0 +CATEGORIES= net-mgmt +MASTER_SITES= # nada +DISTFILES= # nil + +MAINTAINER= paul+ports@it.ca +COMMENT= Traceroute attempt logger and result spoofer + +NO_WRKSUBDIR= yes + +SED_SCRIPT+= -e 's,%%PREFIX%%,${PREFIX},g' \ + -e 's,%%RC_SUBR%%,${RC_SUBR},g' + +.include + +USE_RC_SUBR= yes + +do-extract: + ${MKDIR} ${WRKSRC} + ${CP} ${FILESDIR}/rotorouter.c ${WRKSRC} + +do-build: + ${CC} -lpcap -o ${WRKSRC}/rotorouter ${WRKSRC}/rotorouter.c + ${SED} ${SED_SCRIPT} < ${FILESDIR}/rotorouter.sh > ${WRKSRC}/rotorouter.sh + +do-install: + @${INSTALL_DATA} -m 640 ${FILESDIR}/rotorouter.conf-example ${PREFIX}/etc + @${INSTALL_DATA} -m 640 ${FILESDIR}/rotorouter.conf-example ${PREFIX}/etc/rotorouter.conf + @${INSTALL_PROGRAM} ${WRKSRC}/rotorouter ${PREFIX}/sbin/ + @${INSTALL_SCRIPT} -m 751 ${WRKSRC}/rotorouter.sh ${PREFIX}/etc/rc.d/rotorouter.sh + +post-install: + @${SED} ${SED_SCRIPT} < ${PKGMESSAGE} + +.include diff --git a/net-mgmt/rotorouter/files/rotorouter.c b/net-mgmt/rotorouter/files/rotorouter.c new file mode 100644 index 000000000000..86546b6594d6 --- /dev/null +++ b/net-mgmt/rotorouter/files/rotorouter.c @@ -0,0 +1,434 @@ +/* fakeroute (c) 1996 Julian Assange + * All Rights Reserved + * + * config file ("hops" by default) contains tuples like thus: + +Dest IP Hop Fake router ms latency +203.4.184.222 0 204.70.10.250 5 +203.4.184.222 1 204.70.10.250 10 +203.4.184.222 2 198.32.136.88 15 +203.4.184.222 3 137.209.200.202 20 +203.4.184.222 4 137.209.60.1 25 +203.4.184.222 5 198.26.127.26 30 +203.4.184.222 -1 203.4.184.222 35 +203.4.184.217 0 204.70.10.250 5 +203.4.184.217 1 204.70.10.250 10 +203.4.184.217 2 198.32.136.88 15 +203.4.184.217 3 137.209.200.202 20 +203.4.184.217 4 137.209.60.1 25 +203.4.184.217 5 198.26.127.26 30 +203.4.184.217 -1 203.4.184.222 35 +*/ + +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include + +#define bool int +#define TRUE 1 +#define FALSE 0 + +#define ENDIAN_RAW_BUG 1 + +typedef u_short port_t; + +pcap_t *pd; +struct bpf_program fcode; +u_char *pcap_userdata; +struct in_addr localnet, netmask; +char ebuf[PCAP_ERRBUF_SIZE]; +int raw; +int a_max_ttl = 1; +int a_timeout = 300; +int a_verbose = 0; + +void ether_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p); +void ppp_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p); +void analyze_udp(struct ip *ip); + +struct hop +{ + struct hop *next; + struct in_addr dst, hop; + int latency; /* delay */ + int ttl; +}; +struct hop *hops; + +struct udp_state +{ + struct udp_state *next; + struct in_addr src, dst; + port_t sport; + time_t last_packet; +}; + +struct udp_state *state; +struct udp_state *queue; + +void +pexit(char *err) +{ + perror(err); + exit(1); +} + +void +eexit(char *err) +{ + fprintf(stderr, "fatal error: %s\n", err); + exit(1); +} + +void * +xmalloc(int n) +{ + void *p=malloc(n); + if (!p) + pexit("malloc"); + return p; +} + +u_short +fast_icmp_cksum(struct icmp *icmp) /* well, for C anyway.. */ +{ + register u_short *u = (u_short *)icmp; + register int sum = 0; + + sum = *u++; + u++; /* skip checksum */ + sum += *u++; + sum += *u++; + sum += *u++; + sum += *u++; + sum += *u++; + sum += *u++; + sum += *u++; + sum += *u++; + sum += *u++; + sum += *u++; + sum += *u++; + sum += *u++; + sum += *u++; + sum += *u++; + sum += *u++; + sum += *u; + sum = (sum >> 16) + (sum & 0xffff); /* fold accumulated carries */ + sum += sum>>16; + return (u_short) ~sum; +} + +struct printer +{ + pcap_handler f; + int type; +}; + +/* XXX needed if using old bpf.h */ +#ifndef DLT_ATM_RFC1483 +#define DLT_ATM_RFC1483 11 +#endif + +static struct printer printers[] = +{ + { ether_if_print, DLT_EN10MB }, + { ether_if_print, DLT_IEEE802 }, +/* + { sl_if_print, DLT_SLIP }, +*/ + { ppp_if_print, DLT_PPP }, +/* + { fddi_if_print, DLT_FDDI }, + { null_if_print, DLT_NULL }, + { atm_if_print, DLT_ATM_RFC1483 }, +*/ + { NULL, 0 }, +}; + +static pcap_handler +lookup_printer(int type) +{ + struct printer *p; + + for (p = printers; p->f; ++p) + if (type == p->type) + return p->f; + + fprintf(stderr, "unknown data link type 0x%x", type); + exit(1); + /* NOTREACHED */ +} + +void +open_pcap(char *dev, bool f_promisc, char *filt, int usec) +{ + if (!dev) + { + dev = pcap_lookupdev(ebuf); + if (!dev) + eexit(ebuf); + } + pd = pcap_open_live(dev, 96, f_promisc, usec, ebuf); + if (!pd) + eexit(ebuf); + if (pcap_lookupnet(dev, &localnet.s_addr, &netmask.s_addr, ebuf) < 0) + eexit(ebuf); + if (pcap_compile(pd, &fcode, filt, 1, (u_long)netmask.s_addr) < 0) + eexit(pcap_geterr(pd)); + if (pcap_setfilter(pd, &fcode) < 0) + eexit(pcap_geterr(pd)); +} + +void +ether_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) +{ + p += 14; + analyze_udp((struct ip *)p); +} + +void +ppp_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) +{ + p += 4; + analyze_udp((struct ip *)p); +} + + +struct hop * +find_hop(struct in_addr dst, int ttl) +{ + struct hop *p, *ret=NULL; + for (p = hops; p; p=p->next) + { + if (p->dst.s_addr == dst.s_addr) + { + if (p->ttl == ttl) + return p; + if (p->ttl == -1) + ret = p; + } + } + return ret; +} + +void +icmp_reply(struct ip *iip, struct hop *hop) +{ + char buf[sizeof(struct ip) + sizeof(struct icmp) + 8]; + struct ip *ip =(struct ip *)buf; + struct icmp *i =(struct icmp *)(buf+sizeof(struct ip)); + static u_short ip_id; + bool f_dest = (hop->ttl == -1); + struct sockaddr_in in; + int len = sizeof (struct ip) + sizeof (struct icmp) + 8; /* don't bother with the options */ + memset(&in, 0, sizeof in); + in.sin_family = AF_INET; + ip->ip_hl = sizeof (struct ip) / 4; + ip->ip_v = 4; + ip->ip_tos = 0; + ip->ip_len = ENDIAN_RAW_BUG? len: htons(len); + ip->ip_id = htons(ip_id++); + ip->ip_off = 0; + ip->ip_ttl = 255; + ip->ip_p = IPPROTO_ICMP; + ip->ip_dst = in.sin_addr = iip->ip_src; + ip->ip_src = hop->hop; + ip->ip_sum = 0; /* let the os calculate it */ + i->icmp_type = f_dest? ICMP_UNREACH: ICMP_TIMXCEED; + i->icmp_code = f_dest? ICMP_UNREACH_PORT: ICMP_TIMXCEED_INTRANS; + memcpy(&i->icmp_ip, iip, sizeof (struct ip)+8); + i->icmp_cksum = fast_icmp_cksum(i); + if (a_verbose>0) + { + printf("rotorouter: sending %s %s", + f_dest? "ICMP_UNREACH_PORT": "ICMP_TIMXCEED", + inet_ntoa(ip->ip_src)); + printf(" -> %s for ttl %d\n", + inet_ntoa(ip->ip_dst), + iip->ip_ttl); + } + usleep(hop->latency); + if (sendto (raw, ip, len, 0, (struct sockaddr *)&in, sizeof in)!=len) + pexit("sendto"); +} + +void +analyze_udp(struct ip *ip) +{ + struct udphdr *u; + struct hop *hop; + struct udp_state *p; + static time_t lastclean; + time_t t; + u = (struct udphdr *)((char *)ip+ip->ip_hl*4); + hop = find_hop(ip->ip_dst, ip->ip_ttl); + if (!hop) + return; + for (p = state; p; p = p->next) + { + if (p->src.s_addr == ip->ip_src.s_addr && + p->sport == u->uh_sport && + p->dst.s_addr == ip->ip_dst.s_addr) + goto found; + } + if (ip->ip_ttl > a_max_ttl) + return; + p = xmalloc(sizeof *p); + p->next = state; + p->src = ip->ip_src; + p->dst = ip->ip_dst; + p->sport = u->uh_sport; + state = p; +found: + p->last_packet = t = time(NULL); + icmp_reply(ip, hop); + if (t > lastclean+10) + { + struct udp_state *prev = NULL; + for (p=state; p;) + { + if (t > p->last_packet + a_timeout) + { + struct udp_state *p2 = p->next; + if (prev) + prev->next = p->next; + else + state = NULL; + free (p); + p = p2; + } else + { + prev = p; + p = p->next; + } + } + } +} + +void +open_raw() +{ + int yes = 1; + raw = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); + if (raw<0) + pexit("socket"); + if (setsockopt(raw, IPPROTO_IP, IP_HDRINCL, (char *)&yes, sizeof(yes)) < 0) + pexit("IP_HDRINCL"); +} + +void +populate_hops(char *fn) +{ + FILE *fh; + char host[32]; + char hop[32]; + struct hop *p; + int latency; + int ttl; + int rules; + fh = fopen(fn, "r"); + if (!fh) + pexit(fn); + for (rules = 0; fscanf(fh, "%16s %d %16s %d%*[^\r\n]", host, &ttl, hop, &latency) == 4; rules++) + { + struct in_addr hostaddr, hopaddr; + hostaddr.s_addr = inet_addr(host); + if (hostaddr.s_addr == 0xffffffff) + { + fprintf(stderr, "bad address: %s\n", host); + exit(1); + } + hopaddr.s_addr = inet_addr(hop); + if (hopaddr.s_addr == 0xffffffff) + { + fprintf(stderr, "bad address: %s\n", hop); + exit(1); + } + p = malloc(sizeof *p); + p->dst = hostaddr; + p->hop = hopaddr; + p->ttl = ttl; + p->latency = latency; + p->next = hops; + hops = p; + + } + fprintf(stderr, "%d rotorouter rules loaded\n", rules); +} + +void +usage(char *av0) +{ + exit(1); +} + +int +main(int argc, char **argv) +{ + int c; + pcap_handler printer; + char *a_iface = NULL; + char *a_filter = "udp"; + char *a_hops = "hops"; + int a_usec = 50; + bool f_promisc = TRUE; + while ((c=getopt(argc, argv, "i:ph:u:n:v"))!=-1) + { + switch(c) + { + case 'i': + a_iface = optarg; + break; + case 'p': + f_promisc = FALSE; + break; + case 'h': + a_hops = optarg; + break; + case 'u': + a_usec = atoi(optarg); + break; + case 't': + a_max_ttl = atoi(optarg); + break; + case 'n': + a_timeout = atoi(optarg); + break; + case 'v': + a_verbose++; + break; + default: + usage(argv[0]); + /* NOT REACHED */ + } + } + populate_hops(a_hops); + open_pcap(a_iface, f_promisc, a_filter, a_usec); + printer = lookup_printer(pcap_datalink(pd)); + open_raw(); + if (pcap_loop(pd, 0, printer, NULL) < 0) + { + fprintf(stderr, "%s: pcap_loop: %s\n", + argv[0], pcap_geterr(pd)); + exit(1); + } + pcap_close(pd); + exit(0); +} diff --git a/net-mgmt/rotorouter/files/rotorouter.conf-example b/net-mgmt/rotorouter/files/rotorouter.conf-example new file mode 100644 index 000000000000..f1f5994a7769 --- /dev/null +++ b/net-mgmt/rotorouter/files/rotorouter.conf-example @@ -0,0 +1,4 @@ +137.39.1.3 0 10.1.0.1 5 +137.39.1.3 1 10.2.0.2 10 +137.39.1.3 2 172.31.1.1 10 +137.39.1.3 -1 172.31.1.2 15 diff --git a/net-mgmt/rotorouter/files/rotorouter.sh b/net-mgmt/rotorouter/files/rotorouter.sh new file mode 100644 index 000000000000..6d511432211b --- /dev/null +++ b/net-mgmt/rotorouter/files/rotorouter.sh @@ -0,0 +1,34 @@ +#!/bin/sh +# +# $Id$ +# + +# PROVIDE: rotorouter +# REQUIRE: DAEMON +# BEFORE: LOGIN +# KEYWORD: FreeBSD shutdown +# +# Add the following lines to /etc/rc.conf to enable rotorouter: +# +# rotorouter_enable="YES" +# +# See rotorouter(8) for flags. +# + +. %%RC_SUBR%% + +name=rotorouter +rcvar=`set_rcvar` + +command=%%PREFIX%%/sbin/${name} + +# set defaults + +rotorouter_enable=${rotorouter_enable:-"NO"} +rotorouter_flags="${rotorouter_flags:--h %%PREFIX%%/etc/rotorouter.conf}" + +rotorouter_flags="${rotorouter_flags} &" + +load_rc_config $name +run_rc_command "$1" + diff --git a/net-mgmt/rotorouter/pkg-descr b/net-mgmt/rotorouter/pkg-descr new file mode 100644 index 000000000000..bb95a86d3e94 --- /dev/null +++ b/net-mgmt/rotorouter/pkg-descr @@ -0,0 +1,5 @@ +A program for faking the standard unix udp-based traceroute. + +WWW: http://www.ussrback.com/UNIX/loggers/fakeroute.c + +- Paul Chvostek diff --git a/net-mgmt/rotorouter/pkg-message b/net-mgmt/rotorouter/pkg-message new file mode 100644 index 000000000000..c81a7726fcab --- /dev/null +++ b/net-mgmt/rotorouter/pkg-message @@ -0,0 +1,10 @@ +======================================================================== + NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE +======================================================================== + +The rotorouter port has been installed with an example configuration +file, located at %%PREFIX%%/etc/rotorouter.conf-example. + +You need to build your own config file using local network information. + +======================================================================== diff --git a/net-mgmt/rotorouter/pkg-plist b/net-mgmt/rotorouter/pkg-plist new file mode 100644 index 000000000000..c37e17316203 --- /dev/null +++ b/net-mgmt/rotorouter/pkg-plist @@ -0,0 +1,3 @@ +sbin/rotorouter +etc/rc.d/rotorouter.sh +etc/rotorouter.conf-example -- cgit v1.2.3