summaryrefslogtreecommitdiff
path: root/dsniff/dsniff-2.4_beta1-debian-r1.patch
blob: f1e1934f16446cdbd782d4ec1d18e30d74677c7a (plain)
    1 diff --exclude='*~' -Naur dsniff-2.4.orig/arp.c dsniff-2.4/arp.c
    2 --- dsniff-2.4.orig/arp.c	2006-01-21 18:56:04.000000000 -0200
    3 +++ dsniff-2.4/arp.c	2006-01-21 18:56:37.000000000 -0200
    4 @@ -39,7 +39,7 @@
    5  
    6  #ifdef BSD
    7  int
    8 -arp_cache_lookup(in_addr_t ip, struct ether_addr *ether)
    9 +arp_cache_lookup(in_addr_t ip, struct ether_addr *ether, const char* linf)
   10  {
   11  	int mib[6];
   12  	size_t len;
   13 @@ -91,7 +91,7 @@
   14  #endif
   15  
   16  int
   17 -arp_cache_lookup(in_addr_t ip, struct ether_addr *ether)
   18 +arp_cache_lookup(in_addr_t ip, struct ether_addr *ether, const char* lif)
   19  {
   20  	int sock;
   21  	struct arpreq ar;
   22 @@ -99,7 +99,7 @@
   23  	
   24  	memset((char *)&ar, 0, sizeof(ar));
   25  #ifdef __linux__
   26 -	strncpy(ar.arp_dev, "eth0", sizeof(ar.arp_dev));   /* XXX - *sigh* */
   27 +	strncpy(ar.arp_dev, lif, strlen(lif));
   28  #endif
   29  	sin = (struct sockaddr_in *)&ar.arp_pa;
   30  	sin->sin_family = AF_INET;
   31 diff --exclude='*~' -Naur dsniff-2.4.orig/arp.h dsniff-2.4/arp.h
   32 --- dsniff-2.4.orig/arp.h	2006-01-21 18:56:04.000000000 -0200
   33 +++ dsniff-2.4/arp.h	2006-01-21 18:56:37.000000000 -0200
   34 @@ -11,6 +11,6 @@
   35  #ifndef _ARP_H_
   36  #define _ARP_H_
   37  
   38 -int	arp_cache_lookup(in_addr_t ip, struct ether_addr *ether);
   39 +int	arp_cache_lookup(in_addr_t ip, struct ether_addr *ether, const char* linf);
   40  
   41  #endif /* _ARP_H_ */
   42 diff --exclude='*~' -Naur dsniff-2.4.orig/arpspoof.c dsniff-2.4/arpspoof.c
   43 --- dsniff-2.4.orig/arpspoof.c	2006-01-21 18:56:04.000000000 -0200
   44 +++ dsniff-2.4/arpspoof.c	2006-01-21 18:56:45.000000000 -0200
   45 @@ -27,7 +27,7 @@
   46  
   47  extern char *ether_ntoa(struct ether_addr *);
   48  
   49 -static struct libnet_link_int *llif;
   50 +static libnet_t *l;
   51  static struct ether_addr spoof_mac, target_mac;
   52  static in_addr_t spoof_ip, target_ip;
   53  static char *intf;
   54 @@ -41,47 +41,41 @@
   55  }
   56  
   57  static int
   58 -arp_send(struct libnet_link_int *llif, char *dev,
   59 -	 int op, u_char *sha, in_addr_t spa, u_char *tha, in_addr_t tpa)
   60 +arp_send(libnet_t *l, int op, u_int8_t *sha,
   61 +	 in_addr_t spa, u_int8_t *tha, in_addr_t tpa)
   62  {
   63 -	char ebuf[128];
   64 -	u_char pkt[60];
   65 -	
   66  	if (sha == NULL &&
   67 -	    (sha = (u_char *)libnet_get_hwaddr(llif, dev, ebuf)) == NULL) {
   68 +	    (sha = (u_int8_t *)libnet_get_hwaddr(l)) == NULL) {
   69  		return (-1);
   70  	}
   71  	if (spa == 0) {
   72 -		if ((spa = libnet_get_ipaddr(llif, dev, ebuf)) == 0)
   73 +		if ((spa = libnet_get_ipaddr4(l)) == -1)
   74  			return (-1);
   75 -		spa = htonl(spa); /* XXX */
   76  	}
   77  	if (tha == NULL)
   78  		tha = "\xff\xff\xff\xff\xff\xff";
   79  	
   80 -	libnet_build_ethernet(tha, sha, ETHERTYPE_ARP, NULL, 0, pkt);
   81 +	libnet_autobuild_arp(op, sha, (u_int8_t *)&spa,
   82 +			     tha, (u_int8_t *)&tpa, l);
   83 +	libnet_build_ethernet(tha, sha, ETHERTYPE_ARP, NULL, 0, l, 0);
   84  	
   85 -	libnet_build_arp(ARPHRD_ETHER, ETHERTYPE_IP, ETHER_ADDR_LEN, 4,
   86 -			 op, sha, (u_char *)&spa, tha, (u_char *)&tpa,
   87 -			 NULL, 0, pkt + ETH_H);
   88 -
   89  	fprintf(stderr, "%s ",
   90  		ether_ntoa((struct ether_addr *)sha));
   91  
   92  	if (op == ARPOP_REQUEST) {
   93  		fprintf(stderr, "%s 0806 42: arp who-has %s tell %s\n",
   94  			ether_ntoa((struct ether_addr *)tha),
   95 -			libnet_host_lookup(tpa, 0),
   96 -			libnet_host_lookup(spa, 0));
   97 +			libnet_addr2name4(tpa, LIBNET_DONT_RESOLVE),
   98 +			libnet_addr2name4(spa, LIBNET_DONT_RESOLVE));
   99  	}
  100  	else {
  101  		fprintf(stderr, "%s 0806 42: arp reply %s is-at ",
  102  			ether_ntoa((struct ether_addr *)tha),
  103 -			libnet_host_lookup(spa, 0));
  104 +			libnet_addr2name4(spa, LIBNET_DONT_RESOLVE));
  105  		fprintf(stderr, "%s\n",
  106  			ether_ntoa((struct ether_addr *)sha));
  107  	}
  108 -	return (libnet_write_link_layer(llif, dev, pkt, sizeof(pkt)) == sizeof(pkt));
  109 +	return (libnet_write(l));
  110  }
  111  
  112  #ifdef __linux__
  113 @@ -113,13 +107,13 @@
  114  	int i = 0;
  115  
  116  	do {
  117 -		if (arp_cache_lookup(ip, mac) == 0)
  118 +		if (arp_cache_lookup(ip, mac, intf) == 0)
  119  			return (1);
  120  #ifdef __linux__
  121  		/* XXX - force the kernel to arp. feh. */
  122  		arp_force(ip);
  123  #else
  124 -		arp_send(llif, intf, ARPOP_REQUEST, NULL, 0, NULL, ip);
  125 +		arp_send(l, ARPOP_REQUEST, NULL, 0, NULL, ip);
  126  #endif
  127  		sleep(1);
  128  	}
  129 @@ -136,9 +130,9 @@
  130  	if (arp_find(spoof_ip, &spoof_mac)) {
  131  		for (i = 0; i < 3; i++) {
  132  			/* XXX - on BSD, requires ETHERSPOOF kernel. */
  133 -			arp_send(llif, intf, ARPOP_REPLY,
  134 -				 (u_char *)&spoof_mac, spoof_ip,
  135 -				 (target_ip ? (u_char *)&target_mac : NULL),
  136 +			arp_send(l, ARPOP_REPLY,
  137 +				 (u_int8_t *)&spoof_mac, spoof_ip,
  138 +				 (target_ip ? (u_int8_t *)&target_mac : NULL),
  139  				 target_ip);
  140  			sleep(1);
  141  		}
  142 @@ -151,7 +145,8 @@
  143  {
  144  	extern char *optarg;
  145  	extern int optind;
  146 -	char ebuf[PCAP_ERRBUF_SIZE];
  147 +	char pcap_ebuf[PCAP_ERRBUF_SIZE];
  148 +	char libnet_ebuf[LIBNET_ERRBUF_SIZE];
  149  	int c;
  150  	
  151  	intf = NULL;
  152 @@ -163,7 +158,7 @@
  153  			intf = optarg;
  154  			break;
  155  		case 't':
  156 -			if ((target_ip = libnet_name_resolve(optarg, 1)) == -1)
  157 +			if ((target_ip = libnet_name2addr4(l, optarg, LIBNET_RESOLVE)) == -1)
  158  				usage();
  159  			break;
  160  		default:
  161 @@ -176,26 +171,26 @@
  162  	if (argc != 1)
  163  		usage();
  164  	
  165 -	if ((spoof_ip = libnet_name_resolve(argv[0], 1)) == -1)
  166 +	if ((spoof_ip = libnet_name2addr4(l, argv[0], LIBNET_RESOLVE)) == -1)
  167  		usage();
  168  	
  169 -	if (intf == NULL && (intf = pcap_lookupdev(ebuf)) == NULL)
  170 -		errx(1, "%s", ebuf);
  171 +	if (intf == NULL && (intf = pcap_lookupdev(pcap_ebuf)) == NULL)
  172 +		errx(1, "%s", pcap_ebuf);
  173  	
  174 -	if ((llif = libnet_open_link_interface(intf, ebuf)) == 0)
  175 -		errx(1, "%s", ebuf);
  176 +	if ((l = libnet_init(LIBNET_LINK, intf, libnet_ebuf)) == NULL)
  177 +		errx(1, "%s", libnet_ebuf);
  178  	
  179  	if (target_ip != 0 && !arp_find(target_ip, &target_mac))
  180  		errx(1, "couldn't arp for host %s",
  181 -		     libnet_host_lookup(target_ip, 0));
  182 +		     libnet_addr2name4(target_ip, LIBNET_DONT_RESOLVE));
  183  	
  184  	signal(SIGHUP, cleanup);
  185  	signal(SIGINT, cleanup);
  186  	signal(SIGTERM, cleanup);
  187  	
  188  	for (;;) {
  189 -		arp_send(llif, intf, ARPOP_REPLY, NULL, spoof_ip,
  190 -			 (target_ip ? (u_char *)&target_mac : NULL),
  191 +		arp_send(l, ARPOP_REPLY, NULL, spoof_ip,
  192 +			 (target_ip ? (u_int8_t *)&target_mac : NULL),
  193  			 target_ip);
  194  		sleep(2);
  195  	}
  196 diff --exclude='*~' -Naur dsniff-2.4.orig/dnsspoof.8 dsniff-2.4/dnsspoof.8
  197 --- dsniff-2.4.orig/dnsspoof.8	2006-01-21 18:56:04.000000000 -0200
  198 +++ dsniff-2.4/dnsspoof.8	2006-01-21 18:56:50.000000000 -0200
  199 @@ -31,7 +31,7 @@
  200  address queries on the LAN with an answer of the local machine's IP
  201  address.
  202  .SH FILES
  203 -.IP \fI/usr/local/lib/dnsspoof.hosts\fR
  204 +.IP \fI/etc/dsniff/dnsspoof.hosts\fR
  205  Sample hosts file.
  206  .SH "SEE ALSO"
  207  dsniff(8), hosts(5)
  208 diff --exclude='*~' -Naur dsniff-2.4.orig/dnsspoof.c dsniff-2.4/dnsspoof.c
  209 --- dsniff-2.4.orig/dnsspoof.c	2006-01-21 18:56:04.000000000 -0200
  210 +++ dsniff-2.4/dnsspoof.c	2006-01-21 18:56:45.000000000 -0200
  211 @@ -38,7 +38,7 @@
  212  
  213  pcap_t		*pcap_pd = NULL;
  214  int		 pcap_off = -1;
  215 -int		 lnet_sock = -1;
  216 +libnet_t	*l;
  217  u_long		 lnet_ip = -1;
  218  
  219  static void
  220 @@ -90,19 +90,18 @@
  221  dns_init(char *dev, char *filename)
  222  {
  223  	FILE *f;
  224 -	struct libnet_link_int *llif;
  225 +	libnet_t *l;
  226 +	char libnet_ebuf[LIBNET_ERRBUF_SIZE];
  227  	struct dnsent *de;
  228  	char *ip, *name, buf[1024];
  229  
  230 -	if ((llif = libnet_open_link_interface(dev, buf)) == NULL)
  231 -		errx(1, "%s", buf);
  232 +	if ((l = libnet_init(LIBNET_LINK, dev, libnet_ebuf)) == NULL)
  233 +		errx(1, "%s", libnet_ebuf);
  234  	
  235 -	if ((lnet_ip = libnet_get_ipaddr(llif, dev, buf)) == -1)
  236 -		errx(1, "%s", buf);
  237 +	if ((lnet_ip = libnet_get_ipaddr4(l)) == -1)
  238 +		errx(1, "%s", libnet_geterror(l));
  239  
  240 -	lnet_ip = htonl(lnet_ip);
  241 -	
  242 -	libnet_close_link_interface(llif);
  243 +	libnet_destroy(l);
  244  
  245  	SLIST_INIT(&dns_entries);
  246  	
  247 @@ -180,7 +179,7 @@
  248  static void
  249  dns_spoof(u_char *u, const struct pcap_pkthdr *pkthdr, const u_char *pkt)
  250  {
  251 -	struct libnet_ip_hdr *ip;
  252 +	struct libnet_ipv4_hdr *ip;
  253  	struct libnet_udp_hdr *udp;
  254  	HEADER *dns;
  255  	char name[MAXHOSTNAMELEN];
  256 @@ -189,7 +188,7 @@
  257  	in_addr_t dst;
  258  	u_short type, class;
  259  
  260 -	ip = (struct libnet_ip_hdr *)(pkt + pcap_off);
  261 +	ip = (struct libnet_ipv4_hdr *)(pkt + pcap_off);
  262  	udp = (struct libnet_udp_hdr *)(pkt + pcap_off + (ip->ip_hl * 4));
  263  	dns = (HEADER *)(udp + 1);
  264  	p = (u_char *)(dns + 1);
  265 @@ -212,7 +211,7 @@
  266  	if (class != C_IN)
  267  		return;
  268  
  269 -	p = buf + IP_H + UDP_H + dnslen;
  270 +	p = buf + dnslen;
  271  	
  272  	if (type == T_A) {
  273  		if ((dst = dns_lookup_a(name)) == -1)
  274 @@ -234,38 +233,38 @@
  275  		anslen += 12;
  276  	}
  277  	else return;
  278 -	
  279 -	libnet_build_ip(UDP_H + dnslen + anslen, 0, libnet_get_prand(PRu16),
  280 -			0, 64, IPPROTO_UDP, ip->ip_dst.s_addr,
  281 -			ip->ip_src.s_addr, NULL, 0, buf);
  282 -	
  283 -	libnet_build_udp(ntohs(udp->uh_dport), ntohs(udp->uh_sport),
  284 -			 NULL, dnslen + anslen, buf + IP_H);
  285  
  286 -	memcpy(buf + IP_H + UDP_H, (u_char *)dns, dnslen);
  287 +	memcpy(buf, (u_char *)dns, dnslen);
  288  
  289 -	dns = (HEADER *)(buf + IP_H + UDP_H);
  290 +	dns = (HEADER *)buf;
  291  	dns->qr = dns->ra = 1;
  292  	if (type == T_PTR) dns->aa = 1;
  293  	dns->ancount = htons(1);
  294  
  295  	dnslen += anslen;
  296 +
  297 +	libnet_clear_packet(l);
  298 +	libnet_build_udp(ntohs(udp->uh_dport), ntohs(udp->uh_sport),
  299 +			 LIBNET_UDP_H + dnslen, 0,
  300 +			 (u_int8_t *)buf, dnslen, l, 0);
  301 +
  302 +	libnet_build_ipv4(LIBNET_IPV4_H + LIBNET_UDP_H + dnslen, 0,
  303 +			  libnet_get_prand(LIBNET_PRu16), 0, 64, IPPROTO_UDP, 0,
  304 +			  ip->ip_dst.s_addr, ip->ip_src.s_addr, NULL, 0, l, 0);
  305  	
  306 -	libnet_do_checksum(buf, IPPROTO_UDP, UDP_H + dnslen);
  307 -	
  308 -	if (libnet_write_ip(lnet_sock, buf, IP_H + UDP_H + dnslen) < 0)
  309 +	if (libnet_write(l) < 0)
  310  		warn("write");
  311  
  312  	fprintf(stderr, "%s.%d > %s.%d:  %d+ %s? %s\n",
  313 -	      libnet_host_lookup(ip->ip_src.s_addr, 0), ntohs(udp->uh_sport),
  314 -	      libnet_host_lookup(ip->ip_dst.s_addr, 0), ntohs(udp->uh_dport),
  315 +	      libnet_addr2name4(ip->ip_src.s_addr, 0), ntohs(udp->uh_sport),
  316 +	      libnet_addr2name4(ip->ip_dst.s_addr, 0), ntohs(udp->uh_dport),
  317  	      ntohs(dns->id), type == T_A ? "A" : "PTR", name);
  318  }
  319  
  320  static void
  321  cleanup(int sig)
  322  {
  323 -	libnet_close_raw_sock(lnet_sock);
  324 +	libnet_destroy(l);
  325  	pcap_close(pcap_pd);
  326  	exit(0);
  327  }
  328 @@ -276,6 +275,7 @@
  329  	extern char *optarg;
  330  	extern int optind;
  331  	char *p, *dev, *hosts, buf[1024];
  332 +	char ebuf[LIBNET_ERRBUF_SIZE];
  333  	int i;
  334  
  335  	dev = hosts = NULL;
  336 @@ -306,7 +306,7 @@
  337  		strlcpy(buf, p, sizeof(buf));
  338  	}
  339  	else snprintf(buf, sizeof(buf), "udp dst port 53 and not src %s",
  340 -		      libnet_host_lookup(lnet_ip, 0));
  341 +		      libnet_addr2name4(lnet_ip, LIBNET_DONT_RESOLVE));
  342  	
  343  	if ((pcap_pd = pcap_init(dev, buf, 128)) == NULL)
  344  		errx(1, "couldn't initialize sniffing");
  345 @@ -314,10 +314,10 @@
  346  	if ((pcap_off = pcap_dloff(pcap_pd)) < 0)
  347  		errx(1, "couldn't determine link layer offset");
  348  	
  349 -	if ((lnet_sock = libnet_open_raw_sock(IPPROTO_RAW)) == -1)
  350 +	if ((l = libnet_init(LIBNET_RAW4, dev, ebuf)) == NULL)
  351  		errx(1, "couldn't initialize sending");
  352  	
  353 -	libnet_seed_prand();
  354 +	libnet_seed_prand(l);
  355  	
  356  	signal(SIGHUP, cleanup);
  357  	signal(SIGINT, cleanup);
  358 diff --exclude='*~' -Naur dsniff-2.4.orig/dsniff.8 dsniff-2.4/dsniff.8
  359 --- dsniff-2.4.orig/dsniff.8	2006-01-21 18:56:04.000000000 -0200
  360 +++ dsniff-2.4/dsniff.8	2006-01-21 18:56:50.000000000 -0200
  361 @@ -10,7 +10,7 @@
  362  .nf
  363  .fi
  364  \fBdsniff\fR [\fB-c\fR] [\fB-d\fR] [\fB-m\fR] [\fB-n\fR] [\fB-i
  365 -\fIinterface\fR] [\fB-s \fIsnaplen\fR] [\fB-f \fIservices\fR]
  366 +\fIinterface\fR | \fB-p \fIpcapfile\fR] [\fB-s \fIsnaplen\fR] [\fB-f \fIservices\fR]
  367  [\fB-t \fItrigger[,...]\fR]]
  368  [\fB-r\fR|\fB-w\fR \fIsavefile\fR] [\fIexpression\fR]
  369  .SH DESCRIPTION
  370 @@ -45,6 +45,9 @@
  371  Do not resolve IP addresses to hostnames.
  372  .IP "\fB-i \fIinterface\fR"
  373  Specify the interface to listen on.
  374 +.IP "\fB-p \fIpcapfile\fR"
  375 +Rather than processing the contents of packets observed upon the network 
  376 +process the given PCAP capture file.
  377  .IP "\fB-s \fIsnaplen\fR"
  378  Analyze at most the first \fIsnaplen\fR bytes of each TCP connection,
  379  rather than the default of 1024.
  380 @@ -65,9 +68,9 @@
  381  On a hangup signal \fBdsniff\fR will dump its current trigger table to
  382  \fIdsniff.services\fR.
  383  .SH FILES
  384 -.IP \fI/usr/local/lib/dsniff.services\fR
  385 +.IP \fI/etc/dsniff/dsniff.services\fR
  386  Default trigger table
  387 -.IP \fI/usr/local/lib/dsniff.magic\fR
  388 +.IP \fI/etc/dsniff/dsniff.magic\fR
  389  Network protocol magic
  390  .SH "SEE ALSO"
  391  arpspoof(8), libnids(3), services(5), magic(5)
  392 diff --exclude='*~' -Naur dsniff-2.4.orig/dsniff.8.orig dsniff-2.4/dsniff.8.orig
  393 --- dsniff-2.4.orig/dsniff.8.orig	1969-12-31 21:00:00.000000000 -0300
  394 +++ dsniff-2.4/dsniff.8.orig	2006-01-21 18:56:40.000000000 -0200
  395 @@ -0,0 +1,84 @@
  396 +.TH DSNIFF 8
  397 +.ad
  398 +.fi
  399 +.SH NAME
  400 +dsniff
  401 +\-
  402 +password sniffer
  403 +.SH SYNOPSIS
  404 +.na
  405 +.nf
  406 +.fi
  407 +\fBdsniff\fR [\fB-c\fR] [\fB-d\fR] [\fB-m\fR] [\fB-n\fR] [\fB-i
  408 +\fIinterface\fR | \fB-p \fIpcapfile\fR] [\fB-s \fIsnaplen\fR] [\fB-f \fIservices\fR]
  409 +[\fB-t \fItrigger[,...]\fR]]
  410 +[\fB-r\fR|\fB-w\fR \fIsavefile\fR] [\fIexpression\fR]
  411 +.SH DESCRIPTION
  412 +.ad
  413 +.fi
  414 +\fBdsniff\fR is a password sniffer which handles FTP, Telnet, SMTP,
  415 +HTTP, POP, poppass, NNTP, IMAP, SNMP, LDAP, Rlogin, RIP, OSPF, PPTP
  416 +MS-CHAP, NFS, VRRP, YP/NIS, SOCKS, X11, CVS, IRC, AIM, ICQ, Napster,
  417 +PostgreSQL, Meeting Maker, Citrix ICA, Symantec pcAnywhere, NAI
  418 +Sniffer, Microsoft SMB, Oracle SQL*Net, Sybase and Microsoft SQL
  419 +protocols.
  420 +.LP
  421 +\fBdsniff\fR automatically detects and minimally parses each
  422 +application protocol, only saving the interesting bits, and uses
  423 +Berkeley DB as its output file format, only logging unique
  424 +authentication attempts. Full TCP/IP reassembly is provided by
  425 +libnids(3).
  426 +.LP
  427 +I wrote \fBdsniff\fR with honest intentions - to audit my own network,
  428 +and to demonstrate the insecurity of cleartext network protocols.
  429 +Please do not abuse this software.
  430 +.SH OPTIONS
  431 +.IP \fB-c\fR
  432 +Perform half-duplex TCP stream reassembly, to handle asymmetrically
  433 +routed traffic (such as when using arpspoof(8) to intercept client
  434 +traffic bound for the local gateway).
  435 +.IP \fB-d\fR
  436 +Enable debugging mode.
  437 +.IP \fB-m\fR
  438 +Enable automatic protocol detection.
  439 +.IP \fB-n\fR
  440 +Do not resolve IP addresses to hostnames.
  441 +.IP "\fB-i \fIinterface\fR"
  442 +Specify the interface to listen on.
  443 +.IP "\fB-p \fIpcapfile\fR"
  444 +Rather than processing the contents of packets observed upon the network 
  445 +process the given PCAP capture file.
  446 +.IP "\fB-s \fIsnaplen\fR"
  447 +Analyze at most the first \fIsnaplen\fR bytes of each TCP connection,
  448 +rather than the default of 1024.
  449 +.IP "\fB-f \fIservices\fR"
  450 +Load triggers from a \fIservices\fR file.
  451 +.IP "\fB -t \fItrigger\fR[,...]"
  452 +Load triggers from a comma-separated list, specified as
  453 +\fIport\fR/\fIproto\fR=\fIservice\fR (e.g. 80/tcp=http).
  454 +.IP "\fB-r \fIsavefile\fR"
  455 +Read sniffed sessions from a \fIsavefile\fR created with the \fB-w\fR
  456 +option.
  457 +.IP "\fB-w \fIfile\fR"
  458 +Write sniffed sessions to \fIsavefile\fR rather than parsing and
  459 +printing them out.
  460 +.IP "\fIexpression\fR"
  461 +Specify a tcpdump(8) filter expression to select traffic to sniff.
  462 +.LP
  463 +On a hangup signal \fBdsniff\fR will dump its current trigger table to
  464 +\fIdsniff.services\fR.
  465 +.SH FILES
  466 +.IP \fI/usr/local/lib/dsniff.services\fR
  467 +Default trigger table
  468 +.IP \fI/usr/local/lib/dsniff.magic\fR
  469 +Network protocol magic
  470 +.SH "SEE ALSO"
  471 +arpspoof(8), libnids(3), services(5), magic(5)
  472 +.SH AUTHOR
  473 +.na
  474 +.nf
  475 +Dug Song <dugsong@monkey.org>
  476 +.SH BUGS
  477 +\fBdsniff\fR's automatic protocol detection feature is based on the
  478 +classic file(1) command by Ian Darwin, and shares its historical
  479 +limitations and bugs.
  480 diff --exclude='*~' -Naur dsniff-2.4.orig/dsniff.c dsniff-2.4/dsniff.c
  481 --- dsniff-2.4.orig/dsniff.c	2006-01-21 18:56:04.000000000 -0200
  482 +++ dsniff-2.4/dsniff.c	2006-01-21 18:56:40.000000000 -0200
  483 @@ -46,8 +46,9 @@
  484  usage(void)
  485  {
  486  	fprintf(stderr, "Version: " VERSION "\n"
  487 -		"Usage: dsniff [-cdmn] [-i interface] [-s snaplen] [-f services]\n"
  488 -		"              [-t trigger[,...]] [-r|-w savefile] [expression]\n");
  489 +		"Usage: dsniff [-cdmn] [-i interface | -p pcapfile] [-s snaplen]\n"
  490 +		"              [-f services] [-t trigger[,...]] [-r|-w savefile]\n"
  491 +		"              [expression]\n");
  492  	exit(1);
  493  }
  494  
  495 @@ -79,7 +80,7 @@
  496  
  497  	services = savefile = triggers = NULL;
  498  	
  499 -	while ((c = getopt(argc, argv, "cdf:i:mnr:s:t:w:h?V")) != -1) {
  500 +	while ((c = getopt(argc, argv, "cdf:i:mnp:r:s:t:w:h?V")) != -1) {
  501  		switch (c) {
  502  		case 'c':
  503  			Opt_client = 1;
  504 @@ -99,6 +100,9 @@
  505  		case 'n':
  506  			Opt_dns = 0;
  507  			break;
  508 +		case 'p':
  509 +			nids_params.filename = optarg;
  510 +			break;
  511  		case 'r':
  512  			Opt_read = 1;
  513  			savefile = optarg;
  514 @@ -168,10 +172,23 @@
  515  	else nids_register_tcp(trigger_tcp);
  516  	
  517  	if (nids_params.pcap_filter != NULL) {
  518 -		warnx("listening on %s [%s]", nids_params.device,
  519 -		      nids_params.pcap_filter);
  520 +		if (nids_params.filename == NULL) {
  521 +			warnx("listening on %s [%s]", nids_params.device,
  522 +		        nids_params.pcap_filter);
  523 +		}
  524 +		else {
  525 +			warnx("using %s [%s]", nids_params.filename,
  526 +		        nids_params.pcap_filter);
  527 +		}
  528 +	}
  529 +	else {
  530 +		if (nids_params.filename == NULL) {
  531 +			warnx("listening on %s", nids_params.device);
  532 +		}
  533 +		else {
  534 +			warnx("using %s", nids_params.filename);
  535 +		}
  536  	}
  537 -	else warnx("listening on %s", nids_params.device);
  538  	
  539  	nids_run();
  540  	
  541 diff --exclude='*~' -Naur dsniff-2.4.orig/filesnarf.8 dsniff-2.4/filesnarf.8
  542 --- dsniff-2.4.orig/filesnarf.8	2006-01-21 18:56:04.000000000 -0200
  543 +++ dsniff-2.4/filesnarf.8	2006-01-21 18:56:40.000000000 -0200
  544 @@ -9,7 +9,7 @@
  545  .na
  546  .nf
  547  .fi
  548 -\fBfilesnarf\fR [\fB-i \fIinterface\fR] [[\fB-v\fR] \fIpattern [\fIexpression\fR]]
  549 +\fBfilesnarf\fR [\fB-i \fIinterface\fR | \fB-p \fIpcapfile\fR] [[\fB-v\fR] \fIpattern [\fIexpression\fR]]
  550  .SH DESCRIPTION
  551  .ad
  552  .fi
  553 @@ -18,6 +18,8 @@
  554  .SH OPTIONS
  555  .IP "\fB-i \fIinterface\fR"
  556  Specify the interface to listen on.
  557 +.IP "\fB-p \fIpcapfile\fR"
  558 +Process packets from the specified PCAP capture file instead of the network.
  559  .IP \fB-v\fR
  560  "Versus" mode. Invert the sense of matching, to select non-matching
  561  files.
  562 diff --exclude='*~' -Naur dsniff-2.4.orig/filesnarf.c dsniff-2.4/filesnarf.c
  563 --- dsniff-2.4.orig/filesnarf.c	2006-01-21 18:56:04.000000000 -0200
  564 +++ dsniff-2.4/filesnarf.c	2006-01-21 18:56:45.000000000 -0200
  565 @@ -51,7 +51,7 @@
  566  usage(void)
  567  {
  568  	fprintf(stderr, "Version: " VERSION "\n"
  569 -		"Usage: filesnarf [-i interface] [[-v] pattern [expression]]\n");
  570 +		"Usage: filesnarf [-i interface | -p pcapfile] [[-v] pattern [expression]]\n");
  571  	exit(1);
  572  }
  573  
  574 @@ -134,8 +134,8 @@
  575  	int fd;
  576  
  577  	warnx("%s.%d > %s.%d: %s (%d@%d)",
  578 -	      libnet_host_lookup(addr->daddr, 0), addr->dest,
  579 -	      libnet_host_lookup(addr->saddr, 0), addr->source,
  580 +	      libnet_addr2name4(addr->daddr, LIBNET_DONT_RESOLVE), addr->dest,
  581 +	      libnet_addr2name4(addr->saddr, LIBNET_DONT_RESOLVE), addr->source,
  582  	      ma->filename, len, ma->offset);
  583  	
  584  	if ((fd = open(ma->filename, O_WRONLY|O_CREAT, 0644)) >= 0) {
  585 @@ -353,7 +353,7 @@
  586  }
  587  
  588  static void
  589 -decode_udp_nfs(struct libnet_ip_hdr *ip)
  590 +decode_udp_nfs(struct libnet_ipv4_hdr *ip)
  591  {
  592  	static struct tuple4 addr;
  593  	struct libnet_udp_hdr *udp;
  594 @@ -464,11 +464,14 @@
  595  	extern int optind;
  596  	int c;
  597  
  598 -	while ((c = getopt(argc, argv, "i:vh?V")) != -1) {
  599 +	while ((c = getopt(argc, argv, "i:p:vh?V")) != -1) {
  600  		switch (c) {
  601  		case 'i':
  602  			nids_params.device = optarg;
  603  			break;
  604 +		case 'p':
  605 +			nids_params.filename = optarg;
  606 +			break;
  607  		case 'v':
  608  			Opt_invert = 1;
  609  			break;
  610 @@ -498,11 +501,24 @@
  611  	nids_register_ip(decode_udp_nfs);
  612  	nids_register_tcp(decode_tcp_nfs);
  613  
  614 -	if (nids_params.pcap_filter != NULL) {
  615 -		warnx("listening on %s [%s]", nids_params.device,
  616 -		      nids_params.pcap_filter);
  617 -	}
  618 -	else warnx("listening on %s", nids_params.device);
  619 +        if (nids_params.pcap_filter != NULL) {
  620 +                if (nids_params.filename == NULL) {
  621 +                        warnx("listening on %s [%s]", nids_params.device,
  622 +                              nids_params.pcap_filter);
  623 +                }
  624 +                else {
  625 +                        warnx("using %s [%s]", nids_params.filename,
  626 +                              nids_params.pcap_filter);
  627 +                }
  628 +        }
  629 +        else {
  630 +                if (nids_params.filename == NULL) {
  631 +                        warnx("listening on %s", nids_params.device);
  632 +                }
  633 +                else {
  634 +                        warnx("using %s", nids_params.filename);
  635 +                }
  636 +        }
  637  
  638  	nids_run();
  639  
  640 diff --exclude='*~' -Naur dsniff-2.4.orig/macof.c dsniff-2.4/macof.c
  641 --- dsniff-2.4.orig/macof.c	2006-01-21 18:56:04.000000000 -0200
  642 +++ dsniff-2.4/macof.c	2006-01-21 18:56:45.000000000 -0200
  643 @@ -48,8 +48,8 @@
  644  static void
  645  gen_mac(u_char *mac)
  646  {
  647 -	*((in_addr_t *)mac) = libnet_get_prand(PRu32);
  648 -	*((u_short *)(mac + 4)) = libnet_get_prand(PRu16);
  649 +	*((in_addr_t *)mac) = libnet_get_prand(LIBNET_PRu32);
  650 +	*((u_short *)(mac + 4)) = libnet_get_prand(LIBNET_PRu16);
  651  }
  652  
  653  int
  654 @@ -59,22 +59,23 @@
  655  	extern int optind;
  656  	int c, i;
  657  	struct libnet_link_int *llif;
  658 -	char ebuf[PCAP_ERRBUF_SIZE];
  659 +	char pcap_ebuf[PCAP_ERRBUF_SIZE];
  660 +	char libnet_ebuf[LIBNET_ERRBUF_SIZE];
  661  	u_char sha[ETHER_ADDR_LEN], tha[ETHER_ADDR_LEN];
  662  	in_addr_t src, dst;
  663  	u_short sport, dport;
  664  	u_int32_t seq;
  665 -	u_char pkt[ETH_H + IP_H + TCP_H];
  666 +	libnet_t *l;
  667  	
  668  	while ((c = getopt(argc, argv, "vs:d:e:x:y:i:n:h?V")) != -1) {
  669  		switch (c) {
  670  		case 'v':
  671  			break;
  672  		case 's':
  673 -			Src = libnet_name_resolve(optarg, 0);
  674 +			Src = libnet_name2addr4(l, optarg, 0);
  675  			break;
  676  		case 'd':
  677 -			Dst = libnet_name_resolve(optarg, 0);
  678 +			Dst = libnet_name2addr4(l, optarg, 0);
  679  			break;
  680  		case 'e':
  681  			Tha = (u_char *)ether_aton(optarg);
  682 @@ -101,13 +102,13 @@
  683  	if (argc != 0)
  684  		usage();
  685  	
  686 -	if (!Intf && (Intf = pcap_lookupdev(ebuf)) == NULL)
  687 -		errx(1, "%s", ebuf);
  688 +	if (!Intf && (Intf = pcap_lookupdev(pcap_ebuf)) == NULL)
  689 +		errx(1, "%s", pcap_ebuf);
  690  	
  691 -	if ((llif = libnet_open_link_interface(Intf, ebuf)) == 0)
  692 -		errx(1, "%s", ebuf);
  693 +	if ((l = libnet_init(LIBNET_LINK, Intf, libnet_ebuf)) == NULL)
  694 +		errx(1, "%s", libnet_ebuf);
  695  	
  696 -	libnet_seed_prand();
  697 +	libnet_seed_prand(l);
  698  	
  699  	for (i = 0; i != Repeat; i++) {
  700  		
  701 @@ -117,39 +118,37 @@
  702  		else memcpy(tha, Tha, sizeof(tha));
  703  		
  704  		if (Src != 0) src = Src;
  705 -		else src = libnet_get_prand(PRu32);
  706 +		else src = libnet_get_prand(LIBNET_PRu32);
  707  		
  708  		if (Dst != 0) dst = Dst;
  709 -		else dst = libnet_get_prand(PRu32);
  710 +		else dst = libnet_get_prand(LIBNET_PRu32);
  711  		
  712  		if (Sport != 0) sport = Sport;
  713 -		else sport = libnet_get_prand(PRu16);
  714 +		else sport = libnet_get_prand(LIBNET_PRu16);
  715  		
  716  		if (Dport != 0) dport = Dport;
  717 -		else dport = libnet_get_prand(PRu16);
  718 +		else dport = libnet_get_prand(LIBNET_PRu16);
  719  
  720 -		seq = libnet_get_prand(PRu32);
  721 -		
  722 -		libnet_build_ethernet(tha, sha, ETHERTYPE_IP, NULL, 0, pkt);
  723 -		
  724 -		libnet_build_ip(TCP_H, 0, libnet_get_prand(PRu16), 0, 64,
  725 -				IPPROTO_TCP, src, dst, NULL, 0, pkt + ETH_H);
  726 +		seq = libnet_get_prand(LIBNET_PRu32);
  727  		
  728  		libnet_build_tcp(sport, dport, seq, 0, TH_SYN, 512,
  729 -				 0, NULL, 0, pkt + ETH_H + IP_H);
  730 +				 0, 0, LIBNET_TCP_H, NULL, 0, l, 0);
  731 +		
  732 +		libnet_build_ipv4(LIBNET_TCP_H, 0,
  733 +				  libnet_get_prand(LIBNET_PRu16), 0, 64,
  734 +				  IPPROTO_TCP, 0, src, dst, NULL, 0, l, 0);
  735  		
  736 -		libnet_do_checksum(pkt + ETH_H, IPPROTO_IP, IP_H);
  737 -		libnet_do_checksum(pkt + ETH_H, IPPROTO_TCP, TCP_H);
  738 +		libnet_build_ethernet(tha, sha, ETHERTYPE_IP, NULL, 0, l, 0);
  739  		
  740 -		if (libnet_write_link_layer(llif, Intf, pkt, sizeof(pkt)) < 0)
  741 +		if (libnet_write(l) < 0)
  742  			errx(1, "write");
  743  
  744  		fprintf(stderr, "%s ",
  745  			ether_ntoa((struct ether_addr *)sha));
  746  		fprintf(stderr, "%s %s.%d > %s.%d: S %u:%u(0) win 512\n",
  747  			ether_ntoa((struct ether_addr *)tha),
  748 -			libnet_host_lookup(Src, 0), sport,
  749 -			libnet_host_lookup(Dst, 0), dport, seq, seq);
  750 +			libnet_addr2name4(Src, 0), sport,
  751 +			libnet_addr2name4(Dst, 0), dport, seq, seq);
  752  	}
  753  	exit(0);
  754  }
  755 diff --exclude='*~' -Naur dsniff-2.4.orig/mailsnarf.8 dsniff-2.4/mailsnarf.8
  756 --- dsniff-2.4.orig/mailsnarf.8	2006-01-21 18:56:04.000000000 -0200
  757 +++ dsniff-2.4/mailsnarf.8	2006-01-21 18:56:40.000000000 -0200
  758 @@ -9,7 +9,7 @@
  759  .na
  760  .nf
  761  .fi
  762 -\fBmailsnarf\fR [\fB-i \fIinterface\fR] [[\fB-v\fR] \fIpattern [\fIexpression\fR]]
  763 +\fBmailsnarf\fR [\fB-i \fIinterface\fR | \fB-p \fIpcapfile\fR] [[\fB-v\fR] \fIpattern [\fIexpression\fR]]
  764  .SH DESCRIPTION
  765  .ad
  766  .fi
  767 @@ -19,6 +19,8 @@
  768  .SH OPTIONS
  769  .IP "\fB-i \fIinterface\fR"
  770  Specify the interface to listen on.
  771 +.IP "\fB-p \fIpcapfile\fR"
  772 +Process packets from the specified PCAP capture file instead of the network.
  773  .IP \fB-v\fR
  774  "Versus" mode. Invert the sense of matching, to select non-matching
  775  messages.
  776 diff --exclude='*~' -Naur dsniff-2.4.orig/mailsnarf.c dsniff-2.4/mailsnarf.c
  777 --- dsniff-2.4.orig/mailsnarf.c	2006-01-21 18:56:04.000000000 -0200
  778 +++ dsniff-2.4/mailsnarf.c	2006-01-21 18:56:40.000000000 -0200
  779 @@ -59,7 +59,7 @@
  780  usage(void)
  781  {
  782  	fprintf(stderr, "Version: " VERSION "\n"
  783 -		"Usage: mailsnarf [-i interface] [[-v] pattern [expression]]\n");
  784 +		"Usage: mailsnarf [-i interface | -p pcapfile] [[-v] pattern [expression]]\n");
  785  	exit(1);
  786  }
  787  
  788 @@ -178,7 +178,7 @@
  789  	if (smtp->state != SMTP_DATA) {
  790  		while ((i = buf_index(&buf, "\r\n", 2)) >= 0) {
  791  			line = buf_tok(&buf, NULL, i + 2);
  792 -			line->base[line->end] = '\0';
  793 +			line->base[line->end-1] = '\0';
  794  			p = buf_ptr(line);
  795  			
  796  			if (strncasecmp(p, "RSET", 4) == 0) {
  797 @@ -344,11 +344,14 @@
  798  	extern int optind;
  799  	int c;
  800  	
  801 -	while ((c = getopt(argc, argv, "i:vh?V")) != -1) {
  802 +	while ((c = getopt(argc, argv, "i:p:vh?V")) != -1) {
  803  		switch (c) {
  804  		case 'i':
  805  			nids_params.device = optarg;
  806  			break;
  807 +                case 'p':
  808 +                        nids_params.filename = optarg;
  809 +                        break;
  810  		case 'v':
  811  			Opt_invert = 1;
  812  			break;
  813 @@ -378,10 +381,23 @@
  814  	nids_register_tcp(sniff_pop_session);
  815  
  816  	if (nids_params.pcap_filter != NULL) {
  817 -		warnx("listening on %s [%s]", nids_params.device,
  818 -		      nids_params.pcap_filter);
  819 -	}
  820 -	else warnx("listening on %s", nids_params.device);
  821 +                if (nids_params.filename == NULL) {
  822 +		        warnx("listening on %s [%s]", nids_params.device,
  823 +		              nids_params.pcap_filter);
  824 +                }
  825 +                else {
  826 +		        warnx("using %s [%s]", nids_params.filename,
  827 +		              nids_params.pcap_filter);
  828 +                }
  829 +	}
  830 +	else {
  831 +                if (nids_params.filename == NULL) {
  832 +                    warnx("listening on %s", nids_params.device);
  833 +                }
  834 +                else {
  835 +                    warnx("using %s", nids_params.filename);
  836 +                }
  837 +        }
  838  	
  839  	nids_run();
  840  	
  841 diff --exclude='*~' -Naur dsniff-2.4.orig/Makefile.in dsniff-2.4/Makefile.in
  842 --- dsniff-2.4.orig/Makefile.in	2006-01-21 18:56:04.000000000 -0200
  843 +++ dsniff-2.4/Makefile.in	2006-01-21 18:56:50.000000000 -0200
  844 @@ -11,7 +11,7 @@
  845  install_prefix  =
  846  prefix          = @prefix@
  847  exec_prefix	= @exec_prefix@
  848 -libdir		= @libdir@
  849 +libdir		= $(prefix)/share/dsniff
  850  sbindir         = @sbindir@
  851  mandir		= @mandir@
  852  
  853 @@ -37,8 +37,7 @@
  854  X11INC	= @X_CFLAGS@
  855  X11LIB	= @X_LIBS@ @X_PRE_LIBS@ -lXmu -lX11 @X_EXTRA_LIBS@
  856  
  857 -INCS	= -I. $(NIDSINC) $(PCAPINC) $(LNETINC) $(DBINC) $(SSLINC) $(X11INC) \
  858 -	  -I$(srcdir)/missing
  859 +INCS	= -I. $(X11INC) -I$(srcdir)/missing 
  860  LIBS	= @LIBS@ -L$(srcdir) -lmissing
  861  
  862  INSTALL	= @INSTALL@
  863 diff --exclude='*~' -Naur dsniff-2.4.orig/msgsnarf.8 dsniff-2.4/msgsnarf.8
  864 --- dsniff-2.4.orig/msgsnarf.8	2006-01-21 18:56:04.000000000 -0200
  865 +++ dsniff-2.4/msgsnarf.8	2006-01-21 18:56:40.000000000 -0200
  866 @@ -9,7 +9,7 @@
  867  .na
  868  .nf
  869  .fi
  870 -\fBmsgsnarf\fR [\fB-i \fIinterface\fR] [[\fB-v\fR] \fIpattern [\fIexpression\fR]]
  871 +\fBmsgsnarf\fR [\fB-i \fIinterface\fR | \fB-p \fIpcapfile\fR] [[\fB-v\fR] \fIpattern [\fIexpression\fR]]
  872  .SH DESCRIPTION
  873  .ad
  874  .fi
  875 @@ -19,6 +19,8 @@
  876  .SH OPTIONS
  877  .IP "\fB-i \fIinterface\fR"
  878  Specify the interface to listen on.
  879 +.IP "\fB-p \fIpcapfile\fR"
  880 +Process packets from the specified PCAP capture file instead of the network.
  881  .IP \fB-v\fR
  882  "Versus" mode. Invert the sense of matching, to select non-matching
  883  messages.
  884 diff --exclude='*~' -Naur dsniff-2.4.orig/msgsnarf.c dsniff-2.4/msgsnarf.c
  885 --- dsniff-2.4.orig/msgsnarf.c	2006-01-21 18:56:04.000000000 -0200
  886 +++ dsniff-2.4/msgsnarf.c	2006-01-21 18:56:40.000000000 -0200
  887 @@ -23,6 +23,7 @@
  888  #include <nids.h>
  889  #include <pcap.h>
  890  #include <pcaputil.h>
  891 +#include <time.h>
  892  
  893  #include "buf.h"
  894  #include "decode.h"
  895 @@ -44,7 +45,7 @@
  896  usage(void)
  897  {
  898  	fprintf(stderr, "Version: " VERSION "\n"
  899 -		"Usage: msgsnarf [-i interface] [[-v] pattern [expression]]\n");
  900 +		"Usage: msgsnarf [-i interface | -p pcapfile] [[-v] pattern [expression]]\n");
  901  	exit(1);
  902  }
  903  
  904 @@ -632,11 +633,14 @@
  905  	extern int optind;
  906  	int c;
  907  	
  908 -	while ((c = getopt(argc, argv, "i:hv?V")) != -1) {
  909 +	while ((c = getopt(argc, argv, "i:p:hv?V")) != -1) {
  910  		switch (c) {
  911  		case 'i':
  912  			nids_params.device = optarg;
  913  			break;
  914 +		case 'p':
  915 +			nids_params.filename = optarg;
  916 +			break;
  917  		case 'v':
  918  			Opt_invert = 1;
  919  			break;
  920 @@ -665,11 +669,24 @@
  921  	
  922  	nids_register_tcp(sniff_msgs);
  923  
  924 -	if (nids_params.pcap_filter != NULL) {
  925 -		warnx("listening on %s [%s]", nids_params.device,
  926 -		      nids_params.pcap_filter);
  927 -	}
  928 -	else warnx("listening on %s", nids_params.device);
  929 +        if (nids_params.pcap_filter != NULL) {
  930 +                if (nids_params.filename == NULL) {
  931 +                        warnx("listening on %s [%s]", nids_params.device,
  932 +                              nids_params.pcap_filter);
  933 +                }
  934 +                else {
  935 +                        warnx("using %s [%s]", nids_params.filename,
  936 +                              nids_params.pcap_filter);
  937 +                }
  938 +        }
  939 +        else {
  940 +                if (nids_params.filename == NULL) {
  941 +                    warnx("listening on %s", nids_params.device);
  942 +                }
  943 +                else {
  944 +                    warnx("using %s", nids_params.filename);
  945 +                }
  946 +        }
  947  
  948  	nids_run();
  949  	
  950 diff --exclude='*~' -Naur dsniff-2.4.orig/msgsnarf.c.orig dsniff-2.4/msgsnarf.c.orig
  951 --- dsniff-2.4.orig/msgsnarf.c.orig	1969-12-31 21:00:00.000000000 -0300
  952 +++ dsniff-2.4/msgsnarf.c.orig	2006-01-21 18:56:30.000000000 -0200
  953 @@ -0,0 +1,680 @@
  954 +/*
  955 + * msgsnarf.c
  956 + *
  957 + * Sniff chat messages (AIM, ICQ, IRC, MSN, Yahoo) on a network.
  958 + *
  959 + * Copyright (c) 1999 Dug Song <dugsong@monkey.org>
  960 + *
  961 + * $Id: msgsnarf.c,v 1.11 2001/03/15 08:33:04 dugsong Exp $
  962 + */
  963 +
  964 +#include "config.h"
  965 +
  966 +#include <sys/types.h>
  967 +#include <sys/queue.h>
  968 +#include <netinet/in.h>
  969 +
  970 +#include <stdio.h>
  971 +#include <stdlib.h>
  972 +#include <string.h>
  973 +#include <regex.h>
  974 +#include <err.h>
  975 +#include <libnet.h>
  976 +#include <nids.h>
  977 +#include <pcap.h>
  978 +#include <pcaputil.h>
  979 +#include <time.h>
  980 +
  981 +#include "buf.h"
  982 +#include "decode.h"
  983 +#include "version.h"
  984 +
  985 +struct client_info {
  986 +	char	       *nick;
  987 +	char	       *peer;
  988 +	char	       *type;
  989 +	in_addr_t	ip;
  990 +	SLIST_ENTRY(client_info) next;
  991 +};
  992 +
  993 +SLIST_HEAD(, client_info) client_list;
  994 +int		Opt_invert = 0;
  995 +regex_t	       *pregex = NULL;
  996 +
  997 +static void
  998 +usage(void)
  999 +{
 1000 +	fprintf(stderr, "Version: " VERSION "\n"
 1001 +		"Usage: msgsnarf [-i interface] [[-v] pattern [expression]]\n");
 1002 +	exit(1);
 1003 +}
 1004 +
 1005 +static char *
 1006 +timestamp(void)
 1007 +{
 1008 +	static char stamp[32];
 1009 +	struct tm *tm;
 1010 +	time_t now;
 1011 +
 1012 +	time(&now);
 1013 +	tm = localtime(&now);
 1014 +	strftime(stamp, sizeof(stamp), "%b %e %T", tm);
 1015 +
 1016 +	return (stamp);
 1017 +}
 1018 +
 1019 +static int
 1020 +regex_match(char *string)
 1021 +{
 1022 +	return (pregex == NULL ||
 1023 +		((regexec(pregex, string, 0, NULL, 0) == 0) ^ Opt_invert));
 1024 +}
 1025 +
 1026 +struct flap {
 1027 +	u_char	start;
 1028 +	u_char	channel;
 1029 +	u_short	seqnum;
 1030 +	u_short	datalen;
 1031 +};
 1032 +
 1033 +struct snac {
 1034 +	u_short		family;
 1035 +	u_short		subtype;
 1036 +	u_short		flags;
 1037 +	u_int32_t	reqid;
 1038 +};
 1039 +
 1040 +static int
 1041 +process_aim(struct client_info *info, u_char *data, int len)
 1042 +{
 1043 +	struct buf *msg, *word, buf;
 1044 +	struct flap *flap;
 1045 +	struct snac *snac;
 1046 +	u_char c, *p;
 1047 +	int i, reply;
 1048 +
 1049 +	buf_init(&buf, data, len);
 1050 +
 1051 +	if (buf_cmp(&buf, "FLAPON\r\n\r\n", 10) == 0)
 1052 +		buf_skip(&buf, 10);
 1053 +
 1054 +	while (buf_len(&buf) > sizeof(*flap)) {
 1055 +		flap = (struct flap *)buf_ptr(&buf);
 1056 +		flap->datalen = ntohs(flap->datalen);
 1057 +
 1058 +		i = sizeof(*flap) + flap->datalen;
 1059 +
 1060 +		if ((msg = buf_tok(&buf, NULL, i)) == NULL)
 1061 +			break;
 1062 +
 1063 +		buf_skip(msg, sizeof(*flap));
 1064 +		snac = (struct snac *)buf_ptr(msg);
 1065 +		
 1066 +		if (flap->start != 0x2a)
 1067 +			continue;
 1068 +		
 1069 +		if (flap->channel == 0x01) {
 1070 +			if (buf_cmp(msg, "\x00\x00\x00\x01\x00\x01\x00", 7) == 0) {
 1071 +				buf_skip(msg, 7);
 1072 +				buf_get(msg, &c, 1);
 1073 +
 1074 +				if ((word = buf_getbuf(msg, 0, c)) != NULL) {
 1075 +					if (info->nick) free(info->nick);
 1076 +					info->nick = buf_strdup(word);
 1077 +					buf_free(word);
 1078 +				}
 1079 +				buf_skip(msg, 3);
 1080 +				buf_get(msg, &c, 1);
 1081 +				buf_skip(msg, c + 4);
 1082 +
 1083 +				if (buf_cmp(msg, "ICQ", 3) == 0)
 1084 +					info->type = "ICQ";
 1085 +				else info->type = "AIM";
 1086 +			}
 1087 +		}
 1088 +		else if (flap->channel == 0x02) {
 1089 +			if (buf_cmp(msg, "toc_send_im ", 12) == 0) {
 1090 +				buf_skip(msg, 12);
 1091 +				
 1092 +				if ((word = buf_getword(msg, " ", 1)) == NULL)
 1093 +					continue;
 1094 +				
 1095 +				buf_skip(msg, 1);
 1096 +				
 1097 +				if (buf_len(msg) < 3) continue;
 1098 +				msg->end -= 2;
 1099 +				p = buf_strdup(msg);
 1100 +
 1101 +				if (regex_match(p))
 1102 +					printf("%s AIM %s > %.*s: %s\n",
 1103 +					       timestamp(), info->nick,
 1104 +					       buf_len(word), buf_ptr(word), p);
 1105 +				buf_free(word);
 1106 +				free(p);
 1107 +			}
 1108 +			else if (buf_cmp(msg, "IM_IN:", 6) == 0) {
 1109 +				buf_skip(msg, 6);
 1110 +				
 1111 +				if ((word = buf_getword(msg, ":", 1)) == NULL)
 1112 +					continue;
 1113 +				
 1114 +				buf_skip(msg, 2);
 1115 +				p = buf_strdup(msg);
 1116 +
 1117 +				if (regex_match(p))
 1118 +					printf("%s AIM %.*s > %s: %s\n",
 1119 +					       timestamp(), buf_len(word),
 1120 +					       buf_ptr(word), info->nick, p);
 1121 +				buf_free(word);
 1122 +				free(p);
 1123 +			}
 1124 +			else if (ntohs(snac->family) == 0x04) {
 1125 +				
 1126 +				if (ntohs(snac->subtype) == 0x06)
 1127 +					reply = 0;
 1128 +				else if (ntohs(snac->subtype) == 0x07)
 1129 +					reply = 1;
 1130 +				else continue;
 1131 +				
 1132 +				buf_skip(msg, sizeof(*snac) + 8);
 1133 +				buf_get(msg, &c, 1);
 1134 +				
 1135 +				if ((word = buf_getbuf(msg, 0, c)) == NULL)
 1136 +					continue;
 1137 +
 1138 +				/* XXX - ugh, this is totally bogus. help! */
 1139 +				if (buf_cmp(msg, "\x00\x02", 2) == 0) {
 1140 +					buf_skip(msg, 17);
 1141 +					while (buf_cmp(msg, "\x00", 1) == 0)
 1142 +						buf_skip(msg, 1);
 1143 +				}
 1144 +				else if (buf_cmp(msg, "\x00\x05", 2) == 0) {
 1145 +					buf_skip(msg, 97);
 1146 +				}
 1147 +				else if (buf_cmp(msg, "\x00\x00", 2) == 0) {
 1148 +					if (buf_skip(msg, 145) < 0)
 1149 +						buf_skip(msg, 57);
 1150 +				}
 1151 +				p = buf_strdup(msg);
 1152 +				
 1153 +				if (p && strlen(p) && regex_match(p)) {
 1154 +					if (reply) {
 1155 +						printf("%s %s %.*s > %s: %s\n",
 1156 +						       timestamp(), info->type,
 1157 +						       buf_len(word),
 1158 +						       buf_ptr(word),
 1159 +						       info->nick, p);
 1160 +					}
 1161 +					else printf("%s %s %s > %.*s: %s\n",
 1162 +						    timestamp(), info->type,
 1163 +						    info->nick, buf_len(word),
 1164 +						    buf_ptr(word), p);
 1165 +				}
 1166 +				buf_free(word);
 1167 +				if (p) free(p);
 1168 +			}
 1169 +		}
 1170 +	}
 1171 +	return (len - buf_len(&buf));
 1172 +}
 1173 +			
 1174 +static int
 1175 +process_irc(struct client_info *info, u_char *data, int len)
 1176 +{
 1177 +	struct buf *line, *word, *prefix, buf;
 1178 +	char *p;
 1179 +	int i;
 1180 +
 1181 +	buf_init(&buf, data, len);
 1182 +
 1183 +	while ((i = buf_index(&buf, "\n", 1)) >= 0) {
 1184 +		line = buf_tok(&buf, NULL, i);
 1185 +		buf_skip(&buf, 1);
 1186 +		
 1187 +		if (line->base[line->end-1] == '\r')
 1188 +			line->end--;
 1189 +		
 1190 +		if (buf_cmp(line, ":", 1) == 0) {
 1191 +			buf_skip(line, 1);
 1192 +			if ((prefix = buf_getword(line, " ", 1)) == NULL)
 1193 +				continue;
 1194 +			if ((i = buf_index(prefix, "!", 1)) < 0)
 1195 +				continue;
 1196 +			prefix->end = i;
 1197 +		}
 1198 +		else prefix = NULL;
 1199 +
 1200 +		if (buf_cmp(line, "JOIN ", 5) == 0 && prefix != NULL) {
 1201 +			buf_skip(line, 5);
 1202 +			if (buf_cmp(line, ":", 1) == 0)
 1203 +				buf_skip(line, 1);
 1204 +
 1205 +			printf("%s IRC *** %.*s ", timestamp(),
 1206 +			       buf_len(prefix), buf_ptr(prefix));
 1207 +
 1208 +			prefix->offset = prefix->end + 1;
 1209 +			prefix->end = prefix->size;
 1210 +
 1211 +			printf("(%.*s) has joined channel %.*s\n",
 1212 +			       buf_len(prefix), buf_ptr(prefix),
 1213 +			       buf_len(line), buf_ptr(line));
 1214 +		}
 1215 +		else if (buf_cmp(line, "PART ", 5) == 0 && prefix != NULL) {
 1216 +			buf_skip(line, 5);
 1217 +			if (buf_cmp(line, ":", 1) == 0)
 1218 +				buf_skip(line, 1);
 1219 +
 1220 +			if ((word = buf_getword(line, " :", 2)) == NULL)
 1221 +				continue;
 1222 +			
 1223 +			printf("%s IRC *** %.*s has left channel %.*s\n",
 1224 +			       timestamp(), buf_len(prefix), buf_ptr(prefix),
 1225 +			       buf_len(word), buf_ptr(word));
 1226 +
 1227 +			buf_free(word);
 1228 +		}
 1229 +		else if (buf_cmp(line, "QUIT ", 5) == 0 && prefix != NULL) {
 1230 +			buf_skip(line, 5);
 1231 +			if (buf_cmp(line, ":", 1) == 0)
 1232 +				buf_skip(line, 1);
 1233 +
 1234 +			printf("%s IRC *** Signoff: %.*s (%.*s)\n",
 1235 +			       timestamp(), buf_len(prefix), buf_ptr(prefix),
 1236 +			       buf_len(line), buf_ptr(line));
 1237 +		}
 1238 +		else if (buf_cmp(line, "NICK ", 5) == 0) {
 1239 +			buf_skip(line, 5);
 1240 +			if (buf_cmp(line, ":", 1) == 0)
 1241 +				buf_skip(line, 1);
 1242 +			
 1243 +			if (prefix != NULL) {
 1244 +				printf("%s IRC *** %.*s is now known as %.*s\n",
 1245 +				       timestamp(),
 1246 +				       buf_len(prefix), buf_ptr(prefix),
 1247 +				       buf_len(line), buf_ptr(line));
 1248 +			}
 1249 +			else {
 1250 +				if (info->nick) free(info->nick);
 1251 +				info->nick = buf_strdup(line);
 1252 +			}
 1253 +		}
 1254 +		else if (buf_cmp(line, "PRIVMSG ", 8) == 0) {
 1255 +			buf_skip(line, 8);
 1256 +			if ((word = buf_getword(line, " :", 2)) == NULL)
 1257 +				continue;
 1258 +			p = buf_strdup(line);
 1259 +			
 1260 +			if (regex_match(p)) {
 1261 +				if (strncmp(p + 1, "ACTION ", 7) == 0) {
 1262 +					printf("%s IRC * Action: ",
 1263 +					       timestamp());
 1264 +					
 1265 +					if (prefix != NULL) {
 1266 +						printf("%.*s %s\n",
 1267 +						       buf_len(prefix),
 1268 +						       buf_ptr(prefix), p + 8);
 1269 +					}
 1270 +					else printf("%s %s\n",
 1271 +						    info->nick, p + 8);
 1272 +				}
 1273 +				else {
 1274 +					if (prefix != NULL) {
 1275 +						printf("%s IRC %.*s > ",
 1276 +						       timestamp(),
 1277 +						       buf_len(prefix),
 1278 +						       buf_ptr(prefix));
 1279 +					}
 1280 +					else printf("%s IRC %s > ",
 1281 +						    timestamp(),
 1282 +						    info->nick);
 1283 +					
 1284 +					printf("%.*s: %s\n", buf_len(word),
 1285 +					       buf_ptr(word), p);
 1286 +				}
 1287 +			}
 1288 +			buf_free(word);
 1289 +			free(p);
 1290 +		}
 1291 +	}
 1292 +	return (len - buf_len(&buf));
 1293 +}
 1294 +
 1295 +static int
 1296 +process_msn(struct client_info *info, u_char *data, int len)
 1297 +{
 1298 +	struct buf *word, *line, buf;
 1299 +	char *p;
 1300 +	int i, reply;
 1301 +
 1302 +	buf_init(&buf, data, len);
 1303 +	
 1304 +	while ((i = buf_index(&buf, "\r\n", 2)) >= 0) {
 1305 +		line = buf_tok(&buf, NULL, i);
 1306 +		buf_skip(&buf, 2);
 1307 +		
 1308 +		if (buf_cmp(line, "USR ", 4) == 0) {
 1309 +			if ((i = buf_index(line, "MD5 ", 4)) > 0) {
 1310 +				buf_skip(line, i + 4);
 1311 +				
 1312 +				if (buf_cmp(line, "I ", 2) == 0) {
 1313 +					buf_skip(line, 2);
 1314 +					if (info->nick != NULL)
 1315 +						free(info->nick);
 1316 +					info->nick = buf_strdup(line);
 1317 +				}
 1318 +			}
 1319 +		}
 1320 +		else if (buf_cmp(line, "IRO ", 4) == 0) {
 1321 +			if ((i = buf_rindex(line, "1 ", 2)) < 0)
 1322 +				continue;
 1323 +			buf_skip(line, i + 2);
 1324 +			word = buf_getword(line, " ", 1);
 1325 +			if (info->peer != NULL) free(info->peer);
 1326 +			info->peer = buf_strdup(word);
 1327 +			buf_free(word);
 1328 +		}
 1329 +		else if (buf_cmp(line, "MSG ", 4) == 0) {
 1330 +			buf_skip(line, 4);
 1331 +			reply = 0;
 1332 +
 1333 +			if ((word = buf_getword(line, " ", 1)) == NULL)
 1334 +				continue;
 1335 +
 1336 +			if (buf_cmp(line, "N ", 2) == 0 ||
 1337 +			    buf_cmp(line, "U ", 2) == 0) {
 1338 +				reply = 1;
 1339 +			}
 1340 +			else {
 1341 +				if (info->peer != NULL) free(info->peer);
 1342 +				info->peer = buf_strdup(word);
 1343 +			}
 1344 +			buf_free(word);
 1345 +			
 1346 +			if ((i = buf_rindex(line, " ", 1)) < 0)
 1347 +				continue;
 1348 +			
 1349 +			buf_skip(line, i + 1);
 1350 +			p = buf_strdup(line);
 1351 +			i = atoi(p); free(p);
 1352 +			if (i <= 0) continue;
 1353 +			
 1354 +			if ((line = buf_tok(NULL, NULL, i)) == NULL)
 1355 +				break;
 1356 +			
 1357 +			if (buf_index(line, "Content-Type: text/plain", 24) > 0) {
 1358 +				if ((i = buf_rindex(line, "\r\n\r\n", 4)) < 0)
 1359 +					continue;
 1360 +				
 1361 +				buf_skip(line, i + 4);
 1362 +				p = buf_strdup(line);
 1363 +
 1364 +				if (regex_match(p)) {
 1365 +					if (reply) {
 1366 +						printf("%s MSN %s > %s: %s\n",
 1367 +						       timestamp(), info->nick,
 1368 +						       info->peer, p);
 1369 +					}
 1370 +					else printf("%s MSN %s > %s: %s\n",
 1371 +						    timestamp(), info->peer,
 1372 +						    info->nick, p);
 1373 +				}
 1374 +				free(p);
 1375 +			}
 1376 +		}
 1377 +	}
 1378 +	return (len - buf_len(&buf));
 1379 +}
 1380 +
 1381 +struct yhoo {
 1382 +	u_char		version[8];
 1383 +	u_int32_t	length;		/* all fields little-endian */
 1384 +	u_int32_t	service;
 1385 +	u_int32_t	connid;
 1386 +	u_int32_t	magic;
 1387 +	u_int32_t	unknown;
 1388 +	u_int32_t	type;
 1389 +	u_char		nick1[36];
 1390 +	u_char		nick2[36];
 1391 +};
 1392 +
 1393 +struct ymsg {
 1394 +	u_char		version[8];
 1395 +	u_short		length;
 1396 +	u_short		type;
 1397 +	u_int32_t	unknown1;
 1398 +	u_int32_t	unknown2;
 1399 +};
 1400 +
 1401 +static int
 1402 +process_yahoo(struct client_info *info, u_char *data, int len)
 1403 +{
 1404 +	struct yhoo *yhoo;
 1405 +	struct ymsg *ymsg;
 1406 +	struct buf *msg, *nick1, *nick2, buf;
 1407 +	int i, reply;
 1408 +	char *p;
 1409 +
 1410 +	buf_init(&buf, data, len);
 1411 +	
 1412 +	if (buf_cmp(&buf, "YMSG", 4) == 0) {
 1413 +		while (buf_len(&buf) > sizeof(*ymsg)) {
 1414 +			ymsg = (struct ymsg *)buf_ptr(&buf);
 1415 +			ymsg->length = ntohs(ymsg->length);
 1416 +			ymsg->type = ntohs(ymsg->type);
 1417 +
 1418 +			i = sizeof(*ymsg) + ymsg->length;
 1419 +
 1420 +			if ((msg = buf_tok(&buf, NULL, i)) == NULL)
 1421 +				break;
 1422 +			
 1423 +			buf_skip(msg, sizeof(*ymsg));
 1424 +			
 1425 +			if (ymsg->type != 0x06)
 1426 +				continue;
 1427 +			
 1428 +			reply = (buf_cmp(msg, "1", 1) != 0);
 1429 +			buf_skip(msg, 3);
 1430 +
 1431 +			nick1 = buf_getword(msg, "\xc0\x80", 2);
 1432 +			buf_skip(msg, 3);
 1433 +
 1434 +			nick2 = buf_getword(msg, "\xc0\x80", 2);
 1435 +			buf_skip(msg, 4);
 1436 +
 1437 +			msg->end -= 2;
 1438 +			p = buf_strdup(msg);
 1439 +
 1440 +			if (regex_match(p) && nick1 && nick2 && msg) {
 1441 +				printf("%s Yahoo ", timestamp());
 1442 +				if (reply)
 1443 +					printf("%.*s > %.*s: %s\n",
 1444 +					       buf_len(nick2), buf_ptr(nick2),
 1445 +					       buf_len(nick1), buf_ptr(nick1),
 1446 +					       p);
 1447 +				else printf("%.*s > %.*s: %s\n",
 1448 +					    buf_len(nick1), buf_ptr(nick1),
 1449 +					    buf_len(nick2), buf_ptr(nick2), p);
 1450 +			}
 1451 +			if (nick1) buf_free(nick1);
 1452 +			if (nick2) buf_free(nick2);
 1453 +			free(p);
 1454 +		}
 1455 +	}
 1456 +	else {
 1457 +		while (buf_len(&buf) > sizeof(*yhoo)) {
 1458 +			yhoo = (struct yhoo *)buf_ptr(&buf);
 1459 +			yhoo->length = pletohl(&yhoo->length);
 1460 +			yhoo->service = pletohl(&yhoo->service);
 1461 +			yhoo->type = pletohl(&yhoo->type);
 1462 +			yhoo->nick1[sizeof(yhoo->nick1) - 1] = '\0';
 1463 +			yhoo->nick2[sizeof(yhoo->nick2) - 1] = '\0';
 1464 +
 1465 +			i = sizeof(*yhoo) + yhoo->length;
 1466 +			
 1467 +			if ((msg = buf_tok(&buf, NULL, i)) == NULL)
 1468 +				break;
 1469 +			
 1470 +			buf_skip(msg, sizeof(*yhoo));
 1471 +			
 1472 +			if (yhoo->service != 6 || yhoo->type > 1)
 1473 +				continue;
 1474 +			
 1475 +			if ((nick1 = buf_getword(msg, ",", 1)) == NULL)
 1476 +				continue;
 1477 +			
 1478 +			if (memcmp(yhoo->version, "YHOO", 4) == 0) {
 1479 +				buf_skip(msg, 1);
 1480 +				reply = 0;
 1481 +			}
 1482 +			else reply = 1;
 1483 +
 1484 +			p = buf_strdup(msg);
 1485 +
 1486 +			if (regex_match(p)) {
 1487 +				if (reply)
 1488 +					printf("%s Yahoo %.*s > %s: %s\n",
 1489 +					       timestamp(),
 1490 +					       buf_len(nick1), buf_ptr(nick1),
 1491 +					       yhoo->nick2, p);
 1492 +				else
 1493 +					printf("%s Yahoo %s > %.*s: %s\n",
 1494 +					       timestamp(), yhoo->nick2,
 1495 +					       buf_len(nick1), buf_ptr(nick1),
 1496 +					       buf_ptr(msg));
 1497 +			}
 1498 +			free(p);
 1499 +		}
 1500 +	}
 1501 +	return (len - buf_len(&buf));
 1502 +}
 1503 +
 1504 +static void
 1505 +sniff_msgs(struct tcp_stream *ts, void **conn_save)
 1506 +{
 1507 +	struct client_info *c;
 1508 +	int (*process_msgs)(struct client_info *, u_char *, int);
 1509 +	int i;
 1510 +	
 1511 +	if (ts->addr.dest >= 6660 && ts->addr.dest <= 6680) {
 1512 +		process_msgs = process_irc;
 1513 +	}
 1514 +	else if (ts->addr.dest == 5190 || ts->addr.dest == 9898) {
 1515 +		process_msgs = process_aim;
 1516 +	}
 1517 +	else if (ts->addr.dest == 5050) {
 1518 +		process_msgs = process_yahoo;
 1519 +	}
 1520 +	else if (ts->addr.dest == 1863) {
 1521 +		process_msgs = process_msn;
 1522 +	}
 1523 +	else return;
 1524 +	
 1525 +	switch (ts->nids_state) {
 1526 +		
 1527 +	case NIDS_JUST_EST:
 1528 +		ts->server.collect = 1;
 1529 +		ts->client.collect = 1;
 1530 +
 1531 +		i = 0;
 1532 +		SLIST_FOREACH(c, &client_list, next) {
 1533 +			if (c->ip == ts->addr.saddr) {
 1534 +				i = 1; break;
 1535 +			}
 1536 +		}
 1537 +		if (i == 0) {
 1538 +			if ((c = malloc(sizeof(*c))) == NULL)
 1539 +				nids_params.no_mem("sniff_msgs");
 1540 +			c->ip = ts->addr.saddr;
 1541 +			c->nick = strdup("unknown");
 1542 +			SLIST_INSERT_HEAD(&client_list, c, next);
 1543 +		}
 1544 +		*conn_save = (void *)c;
 1545 +		break;
 1546 +
 1547 +	case NIDS_DATA:
 1548 +		c = (struct client_info *)*conn_save;
 1549 +		
 1550 +		if (ts->server.count_new > 0) {
 1551 +			i = process_msgs(c, ts->server.data,
 1552 +					 ts->server.count - ts->server.offset);
 1553 +			nids_discard(ts, i);
 1554 +		}
 1555 +		else if (ts->client.count_new > 0) {
 1556 +			i = process_msgs(c, ts->client.data,
 1557 +					 ts->client.count - ts->client.offset);
 1558 +			nids_discard(ts, i);
 1559 +		}
 1560 +		fflush(stdout);
 1561 +		break;
 1562 +		
 1563 +	default:
 1564 +		c = (struct client_info *)*conn_save;
 1565 +		
 1566 +		if (ts->server.count > 0)
 1567 +			process_msgs(c, ts->server.data,
 1568 +				     ts->server.count - ts->server.offset);
 1569 +		else if (ts->client.count > 0)
 1570 +			process_msgs(c, ts->client.data,
 1571 +				     ts->client.count - ts->client.offset);
 1572 +		fflush(stdout);
 1573 +		break;
 1574 +	}
 1575 +}
 1576 +
 1577 +static void
 1578 +null_syslog(int type, int errnum, struct ip *iph, void *data)
 1579 +{
 1580 +}
 1581 +
 1582 +int
 1583 +main(int argc, char *argv[])
 1584 +{
 1585 +	extern char *optarg;
 1586 +	extern int optind;
 1587 +	int c;
 1588 +	
 1589 +	while ((c = getopt(argc, argv, "i:hv?V")) != -1) {
 1590 +		switch (c) {
 1591 +		case 'i':
 1592 +			nids_params.device = optarg;
 1593 +			break;
 1594 +		case 'v':
 1595 +			Opt_invert = 1;
 1596 +			break;
 1597 +		default:
 1598 +			usage();
 1599 +		}
 1600 +	}
 1601 +	argc -= optind;
 1602 +	argv += optind;
 1603 +	
 1604 +	if (argc > 0 && strlen(argv[0])) {
 1605 +		if ((pregex = (regex_t *) malloc(sizeof(*pregex))) == NULL)
 1606 +			err(1, "malloc");
 1607 +		if (regcomp(pregex, argv[0], REG_EXTENDED|REG_NOSUB) != 0)
 1608 +			errx(1, "invalid regular expression");
 1609 +	}
 1610 +	if (argc > 1)
 1611 +		nids_params.pcap_filter = copy_argv(argv + 1);
 1612 +	nids_params.scan_num_hosts = 0;
 1613 +	nids_params.syslog = null_syslog;
 1614 +	
 1615 +	if (!nids_init())
 1616 +		errx(1, "%s", nids_errbuf);
 1617 +
 1618 +	SLIST_INIT(&client_list);
 1619 +	
 1620 +	nids_register_tcp(sniff_msgs);
 1621 +
 1622 +	if (nids_params.pcap_filter != NULL) {
 1623 +		warnx("listening on %s [%s]", nids_params.device,
 1624 +		      nids_params.pcap_filter);
 1625 +	}
 1626 +	else warnx("listening on %s", nids_params.device);
 1627 +
 1628 +	nids_run();
 1629 +	
 1630 +	/* NOTREACHED */
 1631 +	
 1632 +	exit(0);
 1633 +}
 1634 diff --exclude='*~' -Naur dsniff-2.4.orig/pathnames.h dsniff-2.4/pathnames.h
 1635 --- dsniff-2.4.orig/pathnames.h	2006-01-21 18:56:04.000000000 -0200
 1636 +++ dsniff-2.4/pathnames.h	2006-01-21 18:56:50.000000000 -0200
 1637 @@ -12,7 +12,7 @@
 1638  #define PATHNAMES_H
 1639  
 1640  #ifndef DSNIFF_LIBDIR
 1641 -#define DSNIFF_LIBDIR		"/usr/local/lib/"
 1642 +#define DSNIFF_LIBDIR		"/etc/dsniff/"
 1643  #endif
 1644  
 1645  #define DSNIFF_SERVICES		"dsniff.services"
 1646 diff --exclude='*~' -Naur dsniff-2.4.orig/record.c dsniff-2.4/record.c
 1647 --- dsniff-2.4.orig/record.c	2006-01-21 18:56:04.000000000 -0200
 1648 +++ dsniff-2.4/record.c	2006-01-21 18:56:45.000000000 -0200
 1649 @@ -65,8 +65,8 @@
 1650  	tm = localtime(&rec->time);
 1651  	strftime(tstr, sizeof(tstr), "%x %X", tm);
 1652  	
 1653 -	srcp = libnet_host_lookup(rec->src, Opt_dns);
 1654 -	dstp = libnet_host_lookup(rec->dst, Opt_dns);
 1655 +	srcp = libnet_addr2name4(rec->src, Opt_dns);
 1656 +	dstp = libnet_addr2name4(rec->dst, Opt_dns);
 1657  
 1658  	if ((pr = getprotobynumber(rec->proto)) == NULL)
 1659  		protop = "unknown";
 1660 diff --exclude='*~' -Naur dsniff-2.4.orig/sshcrypto.c dsniff-2.4/sshcrypto.c
 1661 --- dsniff-2.4.orig/sshcrypto.c	2006-01-21 18:56:04.000000000 -0200
 1662 +++ dsniff-2.4/sshcrypto.c	2006-01-21 18:56:26.000000000 -0200
 1663 @@ -14,6 +14,8 @@
 1664  
 1665  #include <sys/types.h>
 1666  #include <openssl/ssl.h>
 1667 +#include <openssl/blowfish.h>
 1668 +#include <openssl/des.h>
 1669  
 1670  #include <err.h>
 1671  #include <stdio.h>
 1672 diff --exclude='*~' -Naur dsniff-2.4.orig/sshmitm.c dsniff-2.4/sshmitm.c
 1673 --- dsniff-2.4.orig/sshmitm.c	2006-01-21 18:56:04.000000000 -0200
 1674 +++ dsniff-2.4/sshmitm.c	2006-01-21 18:56:45.000000000 -0200
 1675 @@ -389,7 +389,7 @@
 1676  	if (argc < 1)
 1677  		usage();
 1678  	
 1679 -	if ((ip = libnet_name_resolve(argv[0], 1)) == -1)
 1680 +	if ((ip = libnet_name2addr4(NULL, argv[0], LIBNET_RESOLVE)) == -1)
 1681  		usage();
 1682  
 1683  	if (argc == 2 && (rport = atoi(argv[1])) == 0)
 1684 diff --exclude='*~' -Naur dsniff-2.4.orig/sshow.8 dsniff-2.4/sshow.8
 1685 --- dsniff-2.4.orig/sshow.8	2006-01-21 18:56:04.000000000 -0200
 1686 +++ dsniff-2.4/sshow.8	2006-01-21 18:56:40.000000000 -0200
 1687 @@ -9,7 +9,7 @@
 1688  .na
 1689  .nf
 1690  .fi
 1691 -\fBsshow\fR [\fB-d\fR] [\fB-i \fIinterface\fR] [\fIexpression\fR]
 1692 +\fBsshow\fR [\fB-d\fR] [\fB-i \fIinterface\fR | \fB-p \fIpcapfile\fR] [\fIexpression\fR]
 1693  .SH DESCRIPTION
 1694  .ad
 1695  .fi
 1696 @@ -28,6 +28,8 @@
 1697  Enable verbose debugging output.
 1698  .IP "\fB-i \fIinterface\fR"
 1699  Specify the interface to listen on.
 1700 +.IP "\fB-p \fIpcapfile\fR"
 1701 +Process packets from the specified PCAP capture file instead of the network.
 1702  .IP "\fIexpression\fR"
 1703  Specify a tcpdump(8) filter expression to select traffic to sniff.
 1704  .SH "SEE ALSO"
 1705 diff --exclude='*~' -Naur dsniff-2.4.orig/sshow.c dsniff-2.4/sshow.c
 1706 --- dsniff-2.4.orig/sshow.c	2006-01-21 18:56:04.000000000 -0200
 1707 +++ dsniff-2.4/sshow.c	2006-01-21 18:56:40.000000000 -0200
 1708 @@ -15,6 +15,7 @@
 1709  
 1710  #include <sys/types.h>
 1711  #include <sys/times.h>
 1712 +#include <time.h>
 1713  
 1714  #include <netinet/in_systm.h>
 1715  #include <netinet/in.h>
 1716 @@ -81,7 +82,7 @@
 1717  static void
 1718  usage(void)
 1719  {
 1720 -	fprintf(stderr, "Usage: sshow [-d] [-i interface]\n");
 1721 +	fprintf(stderr, "Usage: sshow [-d] [-i interface | -p pcapfile]\n");
 1722  	exit(1);
 1723  }
 1724  
 1725 @@ -615,7 +616,7 @@
 1726  	extern int optind;
 1727  	int c;
 1728  	
 1729 -	while ((c = getopt(argc, argv, "di:h?")) != -1) {
 1730 +	while ((c = getopt(argc, argv, "di:p:h?")) != -1) {
 1731  		switch (c) {
 1732  		case 'd':
 1733  			debug++;
 1734 @@ -623,6 +624,9 @@
 1735  		case 'i':
 1736  			nids_params.device = optarg;
 1737  			break;
 1738 +		case 'p':
 1739 +			nids_params.filename = optarg;
 1740 +			break;
 1741  		default:
 1742  			usage();
 1743  			break;
 1744 @@ -651,11 +655,24 @@
 1745  	
 1746  	nids_register_tcp(process_event);
 1747  
 1748 -	if (nids_params.pcap_filter != NULL) {
 1749 -		warnx("listening on %s [%s]", nids_params.device,
 1750 -		      nids_params.pcap_filter);
 1751 -	}
 1752 -	else warnx("listening on %s", nids_params.device);
 1753 +        if (nids_params.pcap_filter != NULL) {
 1754 +                if (nids_params.filename == NULL) {
 1755 +                        warnx("listening on %s [%s]", nids_params.device,
 1756 +                              nids_params.pcap_filter);
 1757 +                }
 1758 +                else {
 1759 +                        warnx("using %s [%s]", nids_params.filename,
 1760 +                              nids_params.pcap_filter);
 1761 +                }
 1762 +        }
 1763 +        else {
 1764 +                if (nids_params.filename == NULL) {
 1765 +                    warnx("listening on %s", nids_params.device);
 1766 +                }
 1767 +                else {
 1768 +                    warnx("using %s", nids_params.filename);
 1769 +                }
 1770 +        }
 1771  
 1772  	nids_run();
 1773  	
 1774 diff --exclude='*~' -Naur dsniff-2.4.orig/sshow.c.orig dsniff-2.4/sshow.c.orig
 1775 --- dsniff-2.4.orig/sshow.c.orig	1969-12-31 21:00:00.000000000 -0300
 1776 +++ dsniff-2.4/sshow.c.orig	2006-01-21 18:56:30.000000000 -0200
 1777 @@ -0,0 +1,664 @@
 1778 +/*
 1779 + * sshow.c
 1780 + *
 1781 + * Passive SSH traffic analysis.
 1782 + *
 1783 + * http://www.openwall.com/advisories/OW-003-ssh-traffic-analysis.txt
 1784 + *
 1785 + * Copyright (c) 2000-2001 Solar Designer <solar@openwall.com>
 1786 + * Copyright (c) 2000 Dug Song <dugsong@monkey.org>
 1787 + *
 1788 + * $Id: sshow.c,v 1.2 2001/03/19 06:52:15 dugsong Exp $
 1789 + */
 1790 +
 1791 +#include "config.h"
 1792 +
 1793 +#include <sys/types.h>
 1794 +#include <sys/times.h>
 1795 +#include <time.h>
 1796 +
 1797 +#include <netinet/in_systm.h>
 1798 +#include <netinet/in.h>
 1799 +#include <netinet/ip.h>
 1800 +#include <netinet/tcp.h>
 1801 +#include <arpa/inet.h>
 1802 +
 1803 +#include <stdio.h>
 1804 +#include <stdlib.h>
 1805 +#include <string.h>
 1806 +#include <ctype.h>
 1807 +#include <unistd.h>
 1808 +#include <signal.h>
 1809 +#include <errno.h>
 1810 +#include <err.h>
 1811 +#include <nids.h>
 1812 +#include <pcap.h>
 1813 +
 1814 +#include "pcaputil.h"
 1815 +
 1816 +#if !defined(NIDS_MAJOR) || (NIDS_MAJOR == 1 && NIDS_MINOR < 15)
 1817 +#error This program requires libnids 1.15+
 1818 +#endif
 1819 +
 1820 +#define HISTORY_SIZE			16
 1821 +
 1822 +typedef struct {
 1823 +	u_int min, max;
 1824 +} range;
 1825 +
 1826 +typedef struct {
 1827 +	int direction;			/* 0 for client to server */
 1828 +	clock_t timestamp;		/* timestamp of this packet */
 1829 +	u_int cipher_size;		/* ciphertext size */
 1830 +	range plain_range;		/* possible plaintext sizes */
 1831 +} record;
 1832 +
 1833 +struct history {
 1834 +	record packets[HISTORY_SIZE];	/* recent packets (circular list) */
 1835 +	int index;			/* next (free) index into packets[] */
 1836 +	u_int directions;		/* recent directions (bitmask) */
 1837 +	clock_t timestamps[2];		/* last timestamps in each direction */
 1838 +};
 1839 +
 1840 +struct line {
 1841 +	int input_count;		/* input packets (client to server) */
 1842 +	int input_size;			/* input size (estimated) */
 1843 +	int input_last;			/* last input packet size */
 1844 +	int echo_count;			/* echo packets (server to client) */
 1845 +};
 1846 +
 1847 +struct session {
 1848 +	int protocol;		/* -1 not SSH, 0 unknown, 1 or 2 once known */
 1849 +	int state;		/* 1 after username, 2 after authentication */
 1850 +	int compressed;		/* whether compression is known to be used */
 1851 +	struct history history;	/* session history */
 1852 +	struct line line;	/* current command line */
 1853 +};
 1854 +
 1855 +static int debug = 0;
 1856 +
 1857 +static clock_t now;
 1858 +
 1859 +static void
 1860 +usage(void)
 1861 +{
 1862 +	fprintf(stderr, "Usage: sshow [-d] [-i interface]\n");
 1863 +	exit(1);
 1864 +}
 1865 +
 1866 +static clock_t
 1867 +add_history(struct session *session, int direction,
 1868 +	    u_int cipher_size, range *plain_range)
 1869 +{
 1870 +	record *current;
 1871 +	clock_t delay;
 1872 +
 1873 +	current = &session->history.packets[session->history.index++];
 1874 +	session->history.index %= HISTORY_SIZE;
 1875 +
 1876 +	current->direction = direction;
 1877 +	current->timestamp = now;
 1878 +	current->cipher_size = cipher_size;
 1879 +	current->plain_range = *plain_range;
 1880 +
 1881 +	session->history.directions <<= 1;
 1882 +	session->history.directions |= direction;
 1883 +
 1884 +	delay = now - session->history.timestamps[direction];
 1885 +	session->history.timestamps[direction] = now;
 1886 +
 1887 +	return (delay);
 1888 +}
 1889 +
 1890 +static record *
 1891 +get_history(struct session *session, int age)
 1892 +{
 1893 +	int index;
 1894 +
 1895 +	index = session->history.index + (HISTORY_SIZE - 1) - age;
 1896 +	index %= HISTORY_SIZE;
 1897 +
 1898 +	return (&session->history.packets[index]);
 1899 +}
 1900 +
 1901 +static char *
 1902 +s_saddr(struct tcp_stream *ts)
 1903 +{
 1904 +	static char output[32];
 1905 +
 1906 +	snprintf(output, sizeof(output), "%s:%u",
 1907 +		inet_ntoa(*((struct in_addr *)&ts->addr.saddr)),
 1908 +		ts->addr.source);
 1909 +	return (output);
 1910 +}
 1911 +
 1912 +static char *
 1913 +s_daddr(struct tcp_stream *ts)
 1914 +{
 1915 +	static char output[32];
 1916 +
 1917 +	snprintf(output, sizeof(output), "%s:%u",
 1918 +		inet_ntoa(*((struct in_addr *)&ts->addr.daddr)),
 1919 +		ts->addr.dest);
 1920 +	return (output);
 1921 +}
 1922 +
 1923 +static char *
 1924 +s_range(range *range)
 1925 +{
 1926 +	static char output[32];
 1927 +
 1928 +	snprintf(output, sizeof(output),
 1929 +		range->min == range->max ? "%u" : "%u to %u",
 1930 +		range->min, range->max);
 1931 +	return (output);
 1932 +}
 1933 +
 1934 +static void
 1935 +print_data(struct half_stream *stream, u_int count)
 1936 +{
 1937 +	u_int i;
 1938 +	int printable;
 1939 +
 1940 +	printable = 1;
 1941 +	for (i = 0; i < count; i++) {
 1942 +		printf("%02x%c", (int)(u_char)stream->data[i],
 1943 +			i < count - 1 && i % 24 != 23
 1944 +			? ' ' : '\n');
 1945 +		printable &=
 1946 +			isprint(stream->data[i]) ||
 1947 +			stream->data[i] == '\n';
 1948 +	}
 1949 +	if (printable && count >= 4 && !memcmp(stream->data, "SSH-", 4))
 1950 +		fwrite(stream->data, count, 1, stdout);
 1951 +}
 1952 +
 1953 +static u_int
 1954 +ssh1_plain_size(struct half_stream *stream)
 1955 +{
 1956 +	if (stream->count_new < 4) return (0);
 1957 +
 1958 +	return (u_int)(u_char)stream->data[3] |
 1959 +		((u_int)(u_char)stream->data[2] << 8) |
 1960 +		((u_int)(u_char)stream->data[1] << 16) |
 1961 +		((u_int)(u_char)stream->data[0] << 24);
 1962 +}
 1963 +
 1964 +static u_int
 1965 +ssh1_cipher_size(struct half_stream *stream)
 1966 +{
 1967 +	return (4 + ((ssh1_plain_size(stream) + 8) & ~7));
 1968 +}
 1969 +
 1970 +static range *
 1971 +ssh1_plain_range(struct half_stream *stream)
 1972 +{
 1973 +	static range output;
 1974 +
 1975 +	output.min = output.max = ssh1_plain_size(stream) - 5;
 1976 +	return (&output);
 1977 +}
 1978 +
 1979 +static range *
 1980 +ssh2_plain_range(struct half_stream *stream)
 1981 +{
 1982 +	static range output;
 1983 +
 1984 +	output.max = stream->count_new - 16;
 1985 +	/* Assume min padding + 8-byte cipher blocksize */
 1986 +	output.min = output.max - 7;
 1987 +	if ((int)output.min < 0) output.min = 0;
 1988 +	return (&output);
 1989 +}
 1990 +
 1991 +static void
 1992 +client_to_server(struct tcp_stream *ts, struct session *session,
 1993 +		 u_int cipher_size, range *plain_range)
 1994 +{
 1995 +	clock_t delay;
 1996 +	int payload;
 1997 +
 1998 +	delay = add_history(session, 0, cipher_size, plain_range);
 1999 +
 2000 +	if (debug)
 2001 +		printf("- %s -> %s: DATA (%s bytes, %.2f seconds)\n",
 2002 +			s_saddr(ts), s_daddr(ts), s_range(plain_range),
 2003 +			(float)delay / CLK_TCK);
 2004 +	if (debug > 1)
 2005 +		print_data(&ts->server, cipher_size);
 2006 +
 2007 +	payload = plain_range->min;
 2008 +	if (session->state == 2 && payload > 0) {
 2009 +		session->line.input_count++;
 2010 +		session->line.input_last = payload;
 2011 +		if (session->protocol == 1)
 2012 +			payload -= 4;
 2013 +		else {
 2014 +			payload -= 20 + 1;
 2015 +			/* Assume several SSH-2 packets in this IP packet */
 2016 +			if (payload % 44 == 0) {
 2017 +				session->line.input_count += payload / 44;
 2018 +				/* One character per SSH-2 packet (typical) */
 2019 +				payload += payload / 44;
 2020 +				payload %= 44;
 2021 +			}
 2022 +			payload++;
 2023 +		}
 2024 +		if (payload <= 0) {
 2025 +			if (payload < 0 && !session->compressed &&
 2026 +			    session->protocol == 1) {
 2027 +				session->compressed = 1;
 2028 +				printf("+ %s -> %s: Compression detected, "
 2029 +					"guesses will be much less reliable\n",
 2030 +					s_saddr(ts), s_daddr(ts));
 2031 +			}
 2032 +			payload = 1;
 2033 +		}
 2034 +		session->line.input_size += payload;
 2035 +	}
 2036 +}
 2037 +
 2038 +static void
 2039 +server_to_client(struct tcp_stream *ts, struct session *session,
 2040 +		 u_int cipher_size, range *plain_range)
 2041 +{
 2042 +	clock_t delay;
 2043 +	int skip;
 2044 +	range string_range;
 2045 +	
 2046 +	delay = add_history(session, 1, cipher_size, plain_range);
 2047 +	
 2048 +	if (debug)
 2049 +		printf("- %s <- %s: DATA (%s bytes, %.2f seconds)\n",
 2050 +		       s_saddr(ts), s_daddr(ts), s_range(plain_range),
 2051 +		       (float)delay / CLK_TCK);
 2052 +	if (debug > 1)
 2053 +		print_data(&ts->client, cipher_size);
 2054 +	
 2055 +/*
 2056 + * Some of the checks may want to skip over multiple server responses.
 2057 + * For example, there's a debugging packet sent for every option found
 2058 + * in authorized_keys, but we can't use those packets in our pattern.
 2059 + */
 2060 +	skip = 0;
 2061 +	while (((session->history.directions >> skip) & 3) == 3)
 2062 +		if (++skip > HISTORY_SIZE - 5) break;
 2063 +	
 2064 +	if (session->state == 0 &&
 2065 +	    session->protocol == 1 &&
 2066 +	    ((session->history.directions >> skip) & 7) == 5 &&
 2067 +	    plain_range->min == 0 &&
 2068 +	    get_history(session, skip + 1)->plain_range.min > 4 &&
 2069 +	    get_history(session, skip + 2)->plain_range.min == 0) {
 2070 +		session->state = 1;
 2071 +		string_range = get_history(session, skip + 1)->plain_range;
 2072 +		string_range.min -= 4; string_range.max -= 4;
 2073 +		printf("+ %s -> %s: GUESS: Username length is %s\n",
 2074 +		       s_saddr(ts), s_daddr(ts), s_range(&string_range));
 2075 +		return;
 2076 +	}
 2077 +	
 2078 +	if (session->state == 1 &&
 2079 +#ifdef USE_TIMING
 2080 +	    now - get_history(session, 2)->timestamp >= CLK_TCK &&
 2081 +#endif
 2082 +	    session->protocol == 1 &&
 2083 +	    (session->history.directions & 7) == 5 &&
 2084 +	    plain_range->min == 0 &&
 2085 +	    get_history(session, 1)->plain_range.min > 4 &&
 2086 +	    get_history(session, 2)->plain_range.min == 0) {
 2087 +		session->state = 2;
 2088 +		string_range = get_history(session, 1)->plain_range;
 2089 +		string_range.min -= 4; string_range.max -= 4;
 2090 +		printf("+ %s -> %s: GUESS: Password authentication, "
 2091 +		       "password length %s %s%s\n",
 2092 +		       s_saddr(ts), s_daddr(ts),
 2093 +		       string_range.min == 32 ? "appears to be" : "is",
 2094 +		       s_range(&string_range),
 2095 +		       string_range.min == 32 ? " (padded?)" : "");
 2096 +	}
 2097 +	
 2098 +	if (session->state == 0 &&
 2099 +	    session->protocol == 2 &&
 2100 +	    (session->history.directions & 7) == 5) {
 2101 +		if (plain_range->min == 4 + 9) {
 2102 +			string_range = get_history(session, 1)->plain_range;
 2103 +			
 2104 +			if (string_range.min > 500 && string_range.min < 600) {
 2105 +				session->state = 2;
 2106 +				printf("+ %s -> %s: GUESS: DSA "
 2107 +				       "authentication accepted\n",
 2108 +				       s_saddr(ts), s_daddr(ts));
 2109 +			} else
 2110 +				if (string_range.min > 42 + 9) {
 2111 +					session->state = 2;
 2112 +					printf("+ %s -> %s: GUESS: Password "
 2113 +					       "authentication accepted\n",
 2114 +					       s_saddr(ts), s_daddr(ts));
 2115 +				}
 2116 +		} else if (plain_range->min > 12 + 9 &&
 2117 +			   plain_range->min < 56 + 9) {
 2118 +			string_range = get_history(session, 1)->plain_range;
 2119 +			
 2120 +			if (string_range.min > 500 && string_range.min < 600)
 2121 +				printf("+ %s -> %s: GUESS: DSA "
 2122 +				       "authentication failed\n",
 2123 +				       s_saddr(ts), s_daddr(ts));
 2124 +			else if (string_range.min > 42 + 9)
 2125 +				printf("+ %s -> %s: GUESS: Password "
 2126 +				       "authentication failed\n",
 2127 +				       s_saddr(ts), s_daddr(ts));
 2128 +		}
 2129 +	}
 2130 +	
 2131 +	if (session->state == 1 &&
 2132 +	    session->protocol == 1 &&
 2133 +	    (session->history.directions & 3) == 1 &&
 2134 +	    plain_range->min == 0 &&
 2135 +	    get_history(session, 1)->plain_range.min == 130) {
 2136 +		printf("+ %s -> %s: GUESS: RSA authentication refused\n",
 2137 +		       s_saddr(ts), s_daddr(ts));
 2138 +	}
 2139 +	
 2140 +	if (session->state == 1 &&
 2141 +	    session->protocol == 1 &&
 2142 +	    skip >= 1 &&
 2143 +	    ((session->history.directions >> (skip - 1)) & 037) == 013 &&
 2144 +	    plain_range->min == 0 &&
 2145 +	    get_history(session, skip - 1 + 2)->plain_range.min == 16 &&
 2146 +	    get_history(session, skip - 1 + 3)->plain_range.min == 130 &&
 2147 +	    get_history(session, skip - 1 + 4)->plain_range.min == 130) {
 2148 +		char *what;
 2149 +		
 2150 +		switch (get_history(session, 1)->plain_range.min - 4) {
 2151 +		case 28:
 2152 +			/* "RSA authentication accepted." */
 2153 +			session->state = 2;
 2154 +			if (skip > 1 && (what = alloca(64))) {
 2155 +				snprintf(what, 64, "accepted "
 2156 +					 "(%d+ authorized_keys option%s)",
 2157 +					 skip - 1, skip - 1 == 1 ? "" : "s");
 2158 +				break;
 2159 +			}
 2160 +			what = "accepted";
 2161 +			break;
 2162 +			
 2163 +		case 47:
 2164 +			/* "Wrong response to RSA authentication challenge." */
 2165 +			what = "failed";
 2166 +			break;
 2167 +			
 2168 +		default:
 2169 +			what = "???";
 2170 +		}
 2171 +		printf("+ %s -> %s: GUESS: RSA authentication %s\n",
 2172 +		       s_saddr(ts), s_daddr(ts), what);
 2173 +	}
 2174 +	
 2175 +	if (session->state == 2) {
 2176 +		session->line.echo_count++;
 2177 +		
 2178 +		/* Check for backspace */
 2179 +		if (session->protocol == 1 && !session->compressed &&
 2180 +		    plain_range->min == 4 + 3 &&
 2181 +		    session->line.input_size >= 2)
 2182 +			session->line.input_size -= 2;
 2183 +		
 2184 +		if (plain_range->min > 4 + session->line.input_last &&
 2185 +		    session->line.input_count >= 2 &&
 2186 +		    session->line.input_size >= 2) {
 2187 +			int size;
 2188 +			char *what;
 2189 +			
 2190 +			size = session->line.input_size;
 2191 +			if (session->line.echo_count + 1 >=
 2192 +			    session->line.input_count &&
 2193 +			    size <= (session->line.input_count << 2) &&
 2194 +			    size < 0x100) {
 2195 +				what = "(command) line";
 2196 +			}
 2197 +			else {
 2198 +				if (session->line.echo_count <= 2 &&
 2199 +				    size <= (session->line.input_count << 1) &&
 2200 +				    size >= 2 + 1 && size <= 40 + 1) {
 2201 +					what = "password";
 2202 +				}
 2203 +				else what = NULL;
 2204 +			}
 2205 +			if (debug) {
 2206 +				printf("- %s -> %s: sent %d packets "
 2207 +				       "(%d characters), seen %d replies\n",
 2208 +				       s_saddr(ts), s_daddr(ts),
 2209 +				       session->line.input_count, size,
 2210 +				       session->line.echo_count);
 2211 +			}
 2212 +			if (what) {
 2213 +				printf("+ %s -> %s: GUESS: "
 2214 +				       "a %s of %d character%s\n",
 2215 +				       s_saddr(ts), s_daddr(ts),
 2216 +				       what, size - 1, size == 2 ? "" : "s");
 2217 +			}
 2218 +		}
 2219 +		if (plain_range->min <= 0 ||
 2220 +		    plain_range->min > 4 + session->line.input_last) {
 2221 +			session->line.input_count = 0;
 2222 +			session->line.input_size = 0;
 2223 +			session->line.echo_count = 0;
 2224 +		}
 2225 +	}
 2226 +}
 2227 +
 2228 +static void
 2229 +process_data(struct tcp_stream *ts, struct session *session)
 2230 +{
 2231 +	u_int have, need;
 2232 +	char *lf;
 2233 +	
 2234 +	if (session->protocol < 0) return;
 2235 +	
 2236 +	if (ts->client.count_new &&
 2237 +	    (have = ts->client.count - ts->client.offset)) {
 2238 +		switch (session->protocol) {
 2239 +		case 1:
 2240 +			if (have < (need = ssh1_cipher_size(&ts->client))) {
 2241 +				if (debug) {
 2242 +					printf("- %s <- %s: got %u of "
 2243 +					       "%u bytes\n", s_saddr(ts),
 2244 +					       s_daddr(ts), have, need);
 2245 +				}
 2246 +				nids_discard(ts, 0);
 2247 +				return;
 2248 +			}
 2249 +			if (have != need && debug) {
 2250 +				printf("- %s <- %s: left %u bytes\n",
 2251 +				       s_saddr(ts), s_daddr(ts),
 2252 +				       have - need);
 2253 +			}
 2254 +			nids_discard(ts, need);
 2255 +			server_to_client(ts, session, need,
 2256 +				ssh1_plain_range(&ts->client));
 2257 +			return;
 2258 +			
 2259 +		case 2:
 2260 +			server_to_client(ts, session, have,
 2261 +					 ssh2_plain_range(&ts->client));
 2262 +			return;
 2263 +			
 2264 +		default:
 2265 +			break;
 2266 +		}
 2267 +	}
 2268 +	if (ts->server.count_new &&
 2269 +	    (have = ts->server.count - ts->server.offset)) {
 2270 +		if (!session->protocol) {
 2271 +			lf = (char *)memchr(ts->server.data, '\n', have);
 2272 +			if (have < 7 || (!lf && have < 0x100)) {
 2273 +				nids_discard(ts, 0);
 2274 +				return;
 2275 +			}
 2276 +			if (lf && !memcmp(ts->server.data, "SSH-", 4))
 2277 +				session->protocol = ts->server.data[4] - '0';
 2278 +			/* some clients announce SSH-1.99 instead of SSH-2.0 */
 2279 +			if (session->protocol == 1 &&
 2280 +			    ts->server.data[5] == '.' &&
 2281 +			    ts->server.data[6] == '9') {
 2282 +				session->protocol = 2;
 2283 +			}
 2284 +			if (session->protocol != 1 && session->protocol != 2) {
 2285 +				session->protocol = -1;
 2286 +				if (debug) {
 2287 +					printf("- %s -> %s: not SSH\n",
 2288 +					       s_saddr(ts), s_daddr(ts));
 2289 +				}
 2290 +				return;
 2291 +			}
 2292 +			need = lf - ts->server.data + 1;
 2293 +			nids_discard(ts, need);
 2294 +			printf("+ %s -> %s: SSH protocol %d\n",
 2295 +			       s_saddr(ts), s_daddr(ts), session->protocol);
 2296 +			if (debug)
 2297 +				print_data(&ts->server, have);
 2298 +			return;
 2299 +		}
 2300 +		
 2301 +		switch (session->protocol) {
 2302 +		case 1:
 2303 +			if (have < (need = ssh1_cipher_size(&ts->server))) {
 2304 +				if (debug) {
 2305 +					printf("- %s -> %s: got %u of "
 2306 +					       "%u bytes\n", s_saddr(ts),
 2307 +					       s_daddr(ts), have, need);
 2308 +				}
 2309 +				nids_discard(ts, 0);
 2310 +				return;
 2311 +			}
 2312 +			if (have != need && debug) {
 2313 +				printf("- %s -> %s: left %u bytes\n",
 2314 +				       s_saddr(ts), s_daddr(ts),
 2315 +				       have - need);
 2316 +			}
 2317 +			nids_discard(ts, need);
 2318 +			client_to_server(ts, session, need,
 2319 +					 ssh1_plain_range(&ts->server));
 2320 +			return;
 2321 +			
 2322 +		case 2:
 2323 +			client_to_server(ts, session, have,
 2324 +					 ssh2_plain_range(&ts->server));
 2325 +		}
 2326 +	}
 2327 +}
 2328 +
 2329 +static void
 2330 +process_event(struct tcp_stream *ts, struct session **session)
 2331 +{
 2332 +	struct tms buf;
 2333 +	char *what;
 2334 +	
 2335 +	now = times(&buf);
 2336 +	what = NULL;
 2337 +	
 2338 +	switch (ts->nids_state) {
 2339 +	case NIDS_JUST_EST:
 2340 +		ts->client.collect = 1;
 2341 +		ts->server.collect = 1;
 2342 +		if (debug) {
 2343 +			printf("- %s -> %s: ESTABLISHED\n",
 2344 +			       s_saddr(ts), s_daddr(ts));
 2345 +		}
 2346 +		if (!(*session = calloc(1, sizeof(**session)))) {
 2347 +			err(1, "calloc");
 2348 +		}
 2349 +		(*session)->history.timestamps[0] = now;
 2350 +		(*session)->history.timestamps[1] = now;
 2351 +		return;
 2352 +		
 2353 +	case NIDS_CLOSE:
 2354 +		what = "CLOSED";
 2355 +		
 2356 +	case NIDS_RESET:
 2357 +		if (!what) what = "RESET";
 2358 +		
 2359 +	case NIDS_TIMED_OUT:
 2360 +		if (!what) what = "TIMED OUT";
 2361 +		if ((*session)->protocol > 0) {
 2362 +			printf("+ %s -- %s: %s\n",
 2363 +			       s_saddr(ts), s_daddr(ts), what);
 2364 +		}
 2365 +		else if (debug) {
 2366 +			printf("- %s -- %s: %s\n",
 2367 +			       s_saddr(ts), s_daddr(ts), what);
 2368 +		}
 2369 +		free(*session);
 2370 +		return;
 2371 +		
 2372 +	case NIDS_DATA:
 2373 +		process_data(ts, *session);
 2374 +		return;
 2375 +	}
 2376 +}
 2377 +
 2378 +static void
 2379 +null_syslog(int type, int errnum, struct ip *iph, void *data)
 2380 +{
 2381 +}
 2382 +
 2383 +static void
 2384 +cleanup(int signum)
 2385 +{
 2386 +	exit(0);	/* Just so that atexit(3) jobs are called */
 2387 +}
 2388 +
 2389 +int
 2390 +main(int argc, char *argv[])
 2391 +{
 2392 +	extern char *optarg;
 2393 +	extern int optind;
 2394 +	int c;
 2395 +	
 2396 +	while ((c = getopt(argc, argv, "di:h?")) != -1) {
 2397 +		switch (c) {
 2398 +		case 'd':
 2399 +			debug++;
 2400 +			break;
 2401 +		case 'i':
 2402 +			nids_params.device = optarg;
 2403 +			break;
 2404 +		default:
 2405 +			usage();
 2406 +			break;
 2407 +		}
 2408 +	}
 2409 +	argc -= optind;
 2410 +	argv += optind;
 2411 +	
 2412 +	signal(SIGTERM, cleanup);
 2413 +	signal(SIGINT, cleanup);
 2414 +	signal(SIGHUP, cleanup);
 2415 +	
 2416 +	setlinebuf(stdout);
 2417 +	
 2418 +	if (argc > 0) {
 2419 +		nids_params.pcap_filter = copy_argv(argv);
 2420 +	}
 2421 +	else nids_params.pcap_filter = "tcp";
 2422 +	
 2423 +	nids_params.syslog = null_syslog;
 2424 +	nids_params.scan_num_hosts = 0;
 2425 +	nids_params.one_loop_less = 1;
 2426 +	
 2427 +	if (!nids_init())
 2428 +		errx(1, "nids_init: %s", nids_errbuf);
 2429 +	
 2430 +	nids_register_tcp(process_event);
 2431 +
 2432 +	if (nids_params.pcap_filter != NULL) {
 2433 +		warnx("listening on %s [%s]", nids_params.device,
 2434 +		      nids_params.pcap_filter);
 2435 +	}
 2436 +	else warnx("listening on %s", nids_params.device);
 2437 +
 2438 +	nids_run();
 2439 +	
 2440 +	return (0);
 2441 +}
 2442 diff --exclude='*~' -Naur dsniff-2.4.orig/tcpkill.c dsniff-2.4/tcpkill.c
 2443 --- dsniff-2.4.orig/tcpkill.c	2006-01-21 18:56:04.000000000 -0200
 2444 +++ dsniff-2.4/tcpkill.c	2006-01-21 18:56:45.000000000 -0200
 2445 @@ -39,17 +39,18 @@
 2446  static void
 2447  tcp_kill_cb(u_char *user, const struct pcap_pkthdr *pcap, const u_char *pkt)
 2448  {
 2449 -	struct libnet_ip_hdr *ip;
 2450 +	struct libnet_ipv4_hdr *ip;
 2451  	struct libnet_tcp_hdr *tcp;
 2452 -	u_char ctext[64], buf[IP_H + TCP_H];
 2453 +	u_char ctext[64];
 2454  	u_int32_t seq, win;
 2455 -	int i, *sock, len;
 2456 +	int i, len;
 2457 +	libnet_t *l;
 2458  
 2459 -	sock = (int *)user;
 2460 +	l = (libnet_t *)user;
 2461  	pkt += pcap_off;
 2462  	len = pcap->caplen - pcap_off;
 2463  
 2464 -	ip = (struct libnet_ip_hdr *)pkt;
 2465 +	ip = (struct libnet_ipv4_hdr *)pkt;
 2466  	if (ip->ip_p != IPPROTO_TCP)
 2467  		return;
 2468  	
 2469 @@ -57,34 +58,31 @@
 2470  	if (tcp->th_flags & (TH_SYN|TH_FIN|TH_RST))
 2471  		return;
 2472  
 2473 -	libnet_build_ip(TCP_H, 0, 0, 0, 64, IPPROTO_TCP,
 2474 -			ip->ip_dst.s_addr, ip->ip_src.s_addr,
 2475 -			NULL, 0, buf);
 2476 -
 2477 -	libnet_build_tcp(ntohs(tcp->th_dport), ntohs(tcp->th_sport),
 2478 -			 0, 0, TH_RST, 0, 0, NULL, 0, buf + IP_H);
 2479 -	
 2480  	seq = ntohl(tcp->th_ack);
 2481  	win = ntohs(tcp->th_win);
 2482  	
 2483  	snprintf(ctext, sizeof(ctext), "%s:%d > %s:%d:",
 2484 -		 libnet_host_lookup(ip->ip_src.s_addr, 0),
 2485 +		 libnet_addr2name4(ip->ip_src.s_addr, LIBNET_DONT_RESOLVE),
 2486  		 ntohs(tcp->th_sport),
 2487 -		 libnet_host_lookup(ip->ip_dst.s_addr, 0),
 2488 +		 libnet_addr2name4(ip->ip_dst.s_addr, LIBNET_DONT_RESOLVE),
 2489  		 ntohs(tcp->th_dport));
 2490  	
 2491 -	ip = (struct libnet_ip_hdr *)buf;
 2492 -	tcp = (struct libnet_tcp_hdr *)(ip + 1);
 2493 -	
 2494  	for (i = 0; i < Opt_severity; i++) {
 2495 -		ip->ip_id = libnet_get_prand(PRu16);
 2496  		seq += (i * win);
 2497 -		tcp->th_seq = htonl(seq);
 2498  		
 2499 -		libnet_do_checksum(buf, IPPROTO_TCP, TCP_H);
 2500 +		libnet_clear_packet(l);
 2501 +		
 2502 +		libnet_build_tcp(ntohs(tcp->th_dport), ntohs(tcp->th_sport),
 2503 +				 seq, 0, TH_RST, 0, 0, 0, LIBNET_TCP_H, 
 2504 +				 NULL, 0, l, 0);
 2505 +		
 2506 +		libnet_build_ipv4(LIBNET_IPV4_H + LIBNET_TCP_H, 0,
 2507 +				  libnet_get_prand(LIBNET_PRu16), 0, 64,
 2508 +				  IPPROTO_TCP, 0, ip->ip_dst.s_addr,
 2509 +				  ip->ip_src.s_addr, NULL, 0, l, 0);
 2510  		
 2511 -		if (libnet_write_ip(*sock, buf, sizeof(buf)) < 0)
 2512 -			warn("write_ip");
 2513 +		if (libnet_write(l) < 0)
 2514 +			warn("write");
 2515  		
 2516  		fprintf(stderr, "%s R %lu:%lu(0) win 0\n", ctext, seq, seq);
 2517  	}
 2518 @@ -95,8 +93,10 @@
 2519  {
 2520  	extern char *optarg;
 2521  	extern int optind;
 2522 -	int c, sock;
 2523 +	int c;
 2524  	char *p, *intf, *filter, ebuf[PCAP_ERRBUF_SIZE];
 2525 +	char libnet_ebuf[LIBNET_ERRBUF_SIZE];
 2526 +	libnet_t *l;
 2527  	pcap_t *pd;
 2528  	
 2529  	intf = NULL;
 2530 @@ -136,14 +136,14 @@
 2531  	if ((pcap_off = pcap_dloff(pd)) < 0)
 2532  		errx(1, "couldn't determine link layer offset");
 2533  	
 2534 -	if ((sock = libnet_open_raw_sock(IPPROTO_RAW)) == -1)
 2535 +	if ((l = libnet_init(LIBNET_RAW4, intf, libnet_ebuf)) == NULL)
 2536  		errx(1, "couldn't initialize sending");
 2537  	
 2538 -	libnet_seed_prand();
 2539 +	libnet_seed_prand(l);
 2540  	
 2541  	warnx("listening on %s [%s]", intf, filter);
 2542  	
 2543 -	pcap_loop(pd, -1, tcp_kill_cb, (u_char *)&sock);
 2544 +	pcap_loop(pd, -1, tcp_kill_cb, (u_char *)l);
 2545    
 2546  	/* NOTREACHED */
 2547  	
 2548 diff --exclude='*~' -Naur dsniff-2.4.orig/tcpnice.c dsniff-2.4/tcpnice.c
 2549 --- dsniff-2.4.orig/tcpnice.c	2006-01-21 18:56:04.000000000 -0200
 2550 +++ dsniff-2.4/tcpnice.c	2006-01-21 18:56:45.000000000 -0200
 2551 @@ -41,107 +41,106 @@
 2552  }
 2553  
 2554  static void
 2555 -send_tcp_window_advertisement(int sock, struct libnet_ip_hdr *ip,
 2556 +send_tcp_window_advertisement(libnet_t *l, struct libnet_ipv4_hdr *ip,
 2557  			     struct libnet_tcp_hdr *tcp)
 2558  {
 2559  	int len;
 2560  	
 2561  	ip->ip_hl = 5;
 2562 -	ip->ip_len = htons(IP_H + TCP_H);
 2563 -	ip->ip_id = libnet_get_prand(PRu16);
 2564 -	memcpy(buf, (u_char *)ip, IP_H);
 2565 +	ip->ip_len = htons(LIBNET_IPV4_H + LIBNET_TCP_H);
 2566 +	ip->ip_id = libnet_get_prand(LIBNET_PRu16);
 2567 +	memcpy(buf, (u_char *)ip, LIBNET_IPV4_H);
 2568  	
 2569  	tcp->th_off = 5;
 2570  	tcp->th_win = htons(MIN_WIN);
 2571 -	memcpy(buf + IP_H, (u_char *)tcp, TCP_H);
 2572 +	memcpy(buf + LIBNET_IPV4_H, (u_char *)tcp, LIBNET_TCP_H);
 2573  	
 2574 -	libnet_do_checksum(buf, IPPROTO_TCP, TCP_H);
 2575 +	libnet_do_checksum(l, buf, IPPROTO_TCP, LIBNET_TCP_H);
 2576  	
 2577 -	len = IP_H + TCP_H;
 2578 +	len = LIBNET_IPV4_H + LIBNET_TCP_H;
 2579  	
 2580 -	if (libnet_write_ip(sock, buf, len) != len)
 2581 +	if (libnet_write_raw_ipv4(l, buf, len) != len)
 2582  		warn("write");
 2583  	
 2584  	fprintf(stderr, "%s:%d > %s:%d: . ack %lu win %d\n",
 2585 -		libnet_host_lookup(ip->ip_src.s_addr, 0), ntohs(tcp->th_sport),
 2586 -		libnet_host_lookup(ip->ip_dst.s_addr, 0), ntohs(tcp->th_dport),
 2587 +		libnet_addr2name4(ip->ip_src.s_addr, 0), ntohs(tcp->th_sport),
 2588 +		libnet_addr2name4(ip->ip_dst.s_addr, 0), ntohs(tcp->th_dport),
 2589  		ntohl(tcp->th_ack), 1);
 2590  }
 2591  
 2592  static void
 2593 -send_icmp_source_quench(int sock, struct libnet_ip_hdr *ip)
 2594 +send_icmp_source_quench(libnet_t *l, struct libnet_ipv4_hdr *ip)
 2595  {
 2596 -	struct libnet_icmp_hdr *icmp;
 2597 +	struct libnet_icmpv4_hdr *icmp;
 2598  	int len;
 2599  	
 2600  	len = (ip->ip_hl * 4) + 8;
 2601  
 2602 -	libnet_build_ip(ICMP_ECHO_H + len, 0, libnet_get_prand(PRu16),
 2603 -			0, 64, IPPROTO_ICMP, ip->ip_dst.s_addr,
 2604 -			ip->ip_src.s_addr, NULL, 0, buf);
 2605 -	
 2606 -	icmp = (struct libnet_icmp_hdr *)(buf + IP_H);
 2607 +	icmp = (struct libnet_icmpv4_hdr *)(buf + LIBNET_IPV4_H);
 2608  	icmp->icmp_type = ICMP_SOURCEQUENCH;
 2609  	icmp->icmp_code = 0;
 2610 -	memcpy((u_char *)icmp + ICMP_ECHO_H, (u_char *)ip, len);
 2611 +	memcpy((u_char *)icmp + LIBNET_ICMPV4_ECHO_H, (u_char *)ip, len);
 2612  	
 2613 -	libnet_do_checksum(buf, IPPROTO_ICMP, ICMP_ECHO_H + len);
 2614 +	len += LIBNET_ICMPV4_ECHO_H;
 2615  	
 2616 -	len += (IP_H + ICMP_ECHO_H);
 2617 +	libnet_build_ipv4(LIBNET_IPV4_H + len, 0,
 2618 +			  libnet_get_prand(LIBNET_PRu16), 0, 64, IPPROTO_ICMP,
 2619 +			  0, ip->ip_dst.s_addr, ip->ip_src.s_addr,
 2620 +			  (u_int8_t *) icmp, len, l, 0);
 2621  	
 2622 -	if (libnet_write_ip(sock, buf, len) != len)
 2623 +	if (libnet_write(l) != len)
 2624  		warn("write");
 2625  	
 2626  	fprintf(stderr, "%s > %s: icmp: source quench\n",
 2627 -		libnet_host_lookup(ip->ip_dst.s_addr, 0),
 2628 -		libnet_host_lookup(ip->ip_src.s_addr, 0));
 2629 +		libnet_addr2name4(ip->ip_dst.s_addr, 0),
 2630 +		libnet_addr2name4(ip->ip_src.s_addr, 0));
 2631  }
 2632  
 2633  static void
 2634 -send_icmp_frag_needed(int sock, struct libnet_ip_hdr *ip)
 2635 +send_icmp_frag_needed(libnet_t *l, struct libnet_ipv4_hdr *ip)
 2636  {
 2637 -	struct libnet_icmp_hdr *icmp;
 2638 +	struct libnet_icmpv4_hdr *icmp;
 2639  	int len;
 2640  
 2641  	len = (ip->ip_hl * 4) + 8;
 2642  	
 2643 -	libnet_build_ip(ICMP_MASK_H + len, 4, libnet_get_prand(PRu16),
 2644 -			0, 64, IPPROTO_ICMP, ip->ip_dst.s_addr,
 2645 -			ip->ip_src.s_addr, NULL, 0, buf);
 2646 -
 2647 -	icmp = (struct libnet_icmp_hdr *)(buf + IP_H);
 2648 +	icmp = (struct libnet_icmpv4_hdr *)(buf + LIBNET_IPV4_H);
 2649  	icmp->icmp_type = ICMP_UNREACH;
 2650  	icmp->icmp_code = ICMP_UNREACH_NEEDFRAG;
 2651  	icmp->hun.frag.pad = 0;
 2652  	icmp->hun.frag.mtu = htons(MIN_MTU);
 2653 -	memcpy((u_char *)icmp + ICMP_MASK_H, (u_char *)ip, len);
 2654 +	memcpy((u_char *)icmp + LIBNET_ICMPV4_MASK_H, (u_char *)ip, len);
 2655  
 2656 -	libnet_do_checksum(buf, IPPROTO_ICMP, ICMP_MASK_H + len);
 2657 -	
 2658 -	len += (IP_H + ICMP_MASK_H);
 2659 +	len += LIBNET_ICMPV4_MASK_H;
 2660 +
 2661 +	libnet_build_ipv4(LIBNET_IPV4_H + len, 4,
 2662 +			  libnet_get_prand(LIBNET_PRu16), 0, 64, IPPROTO_ICMP,
 2663 +			  0, ip->ip_dst.s_addr, ip->ip_src.s_addr,
 2664 +			  (u_int8_t *) icmp, len, l, 0);
 2665  	
 2666 -	if (libnet_write_ip(sock, buf, len) != len)
 2667 +	if (libnet_write(l) != len)
 2668  		warn("write");
 2669  	
 2670  	fprintf(stderr, "%s > %s: icmp: ",
 2671 -		libnet_host_lookup(ip->ip_dst.s_addr, 0),
 2672 -		libnet_host_lookup(ip->ip_src.s_addr, 0));
 2673 +		libnet_addr2name4(ip->ip_dst.s_addr, 0),
 2674 +		libnet_addr2name4(ip->ip_src.s_addr, 0));
 2675  	fprintf(stderr, "%s unreachable - need to frag (mtu %d)\n",
 2676 -		libnet_host_lookup(ip->ip_src.s_addr, 0), MIN_MTU);
 2677 +		libnet_addr2name4(ip->ip_src.s_addr, 0), MIN_MTU);
 2678  }
 2679  
 2680  static void
 2681  tcp_nice_cb(u_char *user, const struct pcap_pkthdr *pcap, const u_char *pkt)
 2682  {
 2683 -	struct libnet_ip_hdr *ip;
 2684 +	struct libnet_ipv4_hdr *ip;
 2685  	struct libnet_tcp_hdr *tcp;
 2686 -	int *sock, len;
 2687 +	int len;
 2688 +	libnet_t *l;
 2689  
 2690 -	sock = (int *)user;
 2691 +	l = (libnet_t *)user;
 2692  	pkt += pcap_off;
 2693  	len = pcap->caplen - pcap_off;
 2694  
 2695 -	ip = (struct libnet_ip_hdr *)pkt;
 2696 +	ip = (struct libnet_ipv4_hdr *)pkt;
 2697  	if (ip->ip_p != IPPROTO_TCP)
 2698  		return;
 2699  	
 2700 @@ -151,11 +150,11 @@
 2701  	
 2702  	if (ntohs(ip->ip_len) > (ip->ip_hl << 2) + (tcp->th_off << 2)) {
 2703  		if (Opt_icmp)
 2704 -			send_icmp_source_quench(*sock, ip);
 2705 +			send_icmp_source_quench(l, ip);
 2706  		if (Opt_win)
 2707 -			send_tcp_window_advertisement(*sock, ip, tcp);
 2708 +			send_tcp_window_advertisement(l, ip, tcp);
 2709  		if (Opt_pmtu)
 2710 -			send_icmp_frag_needed(*sock, ip);
 2711 +			send_icmp_frag_needed(l, ip);
 2712  	}
 2713  }
 2714  
 2715 @@ -164,8 +163,10 @@
 2716  {
 2717  	extern char *optarg;
 2718  	extern int optind;
 2719 -	int c, sock;
 2720 +	int c;
 2721  	char *intf, *filter, ebuf[PCAP_ERRBUF_SIZE];
 2722 +	char libnet_ebuf[LIBNET_ERRBUF_SIZE];
 2723 +	libnet_t *l;
 2724  	pcap_t *pd;
 2725  	
 2726  	intf = NULL;
 2727 @@ -209,14 +210,14 @@
 2728  	if ((pcap_off = pcap_dloff(pd)) < 0)
 2729  		errx(1, "couldn't determine link layer offset");
 2730  	
 2731 -	if ((sock = libnet_open_raw_sock(IPPROTO_RAW)) == -1)
 2732 +	if ((l = libnet_init(LIBNET_RAW4, intf, libnet_ebuf)) == NULL)
 2733  		errx(1, "couldn't initialize sending");
 2734  	
 2735 -	libnet_seed_prand();
 2736 +	libnet_seed_prand(l);
 2737  	
 2738  	warnx("listening on %s [%s]", intf, filter);
 2739  	
 2740 -	pcap_loop(pd, -1, tcp_nice_cb, (u_char *)&sock);
 2741 +	pcap_loop(pd, -1, tcp_nice_cb, (u_char *)l);
 2742  	
 2743  	/* NOTREACHED */
 2744  	
 2745 diff --exclude='*~' -Naur dsniff-2.4.orig/tcp_raw.c dsniff-2.4/tcp_raw.c
 2746 --- dsniff-2.4.orig/tcp_raw.c	2006-01-21 18:56:04.000000000 -0200
 2747 +++ dsniff-2.4/tcp_raw.c	2006-01-21 18:56:45.000000000 -0200
 2748 @@ -119,7 +119,7 @@
 2749  }
 2750  
 2751  struct iovec *
 2752 -tcp_raw_input(struct libnet_ip_hdr *ip, struct libnet_tcp_hdr *tcp, int len)
 2753 +tcp_raw_input(struct libnet_ipv4_hdr *ip, struct libnet_tcp_hdr *tcp, int len)
 2754  {
 2755  	struct tha tha;
 2756  	struct tcp_conn *conn;
 2757 @@ -131,7 +131,7 @@
 2758  
 2759  	/* Verify TCP checksum. */
 2760  	cksum = tcp->th_sum;
 2761 -	libnet_do_checksum((u_char *) ip, IPPROTO_TCP, len);
 2762 +	libnet_do_checksum(NULL, (u_char *) ip, IPPROTO_TCP, len);
 2763  
 2764  	if (cksum != tcp->th_sum)
 2765  		return (NULL);
 2766 diff --exclude='*~' -Naur dsniff-2.4.orig/tcp_raw.h dsniff-2.4/tcp_raw.h
 2767 --- dsniff-2.4.orig/tcp_raw.h	2006-01-21 18:56:04.000000000 -0200
 2768 +++ dsniff-2.4/tcp_raw.h	2006-01-21 18:56:45.000000000 -0200
 2769 @@ -15,7 +15,7 @@
 2770  				   u_short sport, u_short dport,
 2771  				   u_char *buf, int len);
 2772  
 2773 -struct iovec   *tcp_raw_input(struct libnet_ip_hdr *ip,
 2774 +struct iovec   *tcp_raw_input(struct libnet_ipv4_hdr *ip,
 2775  			      struct libnet_tcp_hdr *tcp, int len);
 2776  
 2777  void		tcp_raw_timeout(int timeout, tcp_raw_callback_t callback);
 2778 diff --exclude='*~' -Naur dsniff-2.4.orig/trigger.c dsniff-2.4/trigger.c
 2779 --- dsniff-2.4.orig/trigger.c	2006-01-21 18:56:04.000000000 -0200
 2780 +++ dsniff-2.4/trigger.c	2006-01-21 18:56:45.000000000 -0200
 2781 @@ -276,7 +276,7 @@
 2782  }
 2783  	
 2784  void
 2785 -trigger_ip(struct libnet_ip_hdr *ip)
 2786 +trigger_ip(struct libnet_ipv4_hdr *ip)
 2787  {
 2788  	struct trigger *t, tr;
 2789  	u_char *buf;
 2790 @@ -305,7 +305,7 @@
 2791  
 2792  /* libnids needs a nids_register_udp()... */
 2793  void
 2794 -trigger_udp(struct libnet_ip_hdr *ip)
 2795 +trigger_udp(struct libnet_ipv4_hdr *ip)
 2796  {
 2797  	struct trigger *t, tr;
 2798  	struct libnet_udp_hdr *udp;
 2799 @@ -437,7 +437,7 @@
 2800  }
 2801  
 2802  void
 2803 -trigger_tcp_raw(struct libnet_ip_hdr *ip)
 2804 +trigger_tcp_raw(struct libnet_ipv4_hdr *ip)
 2805  {
 2806  	struct trigger *t, tr;
 2807  	struct libnet_tcp_hdr *tcp;
 2808 diff --exclude='*~' -Naur dsniff-2.4.orig/trigger.h dsniff-2.4/trigger.h
 2809 --- dsniff-2.4.orig/trigger.h	2006-01-21 18:56:04.000000000 -0200
 2810 +++ dsniff-2.4/trigger.h	2006-01-21 18:56:45.000000000 -0200
 2811 @@ -24,10 +24,10 @@
 2812  int	trigger_set_tcp(int port, char *name);
 2813  int	trigger_set_rpc(int program, char *name);
 2814  
 2815 -void	trigger_ip(struct libnet_ip_hdr *ip);
 2816 -void	trigger_udp(struct libnet_ip_hdr *ip);
 2817 +void	trigger_ip(struct libnet_ipv4_hdr *ip);
 2818 +void	trigger_udp(struct libnet_ipv4_hdr *ip);
 2819  void	trigger_tcp(struct tcp_stream *ts, void **conn_save);
 2820 -void	trigger_tcp_raw(struct libnet_ip_hdr *ip);
 2821 +void	trigger_tcp_raw(struct libnet_ipv4_hdr *ip);
 2822  void	trigger_tcp_raw_timeout(int signal);
 2823  void	trigger_rpc(int program, int proto, int port);
 2824  
 2825 diff --exclude='*~' -Naur dsniff-2.4.orig/urlsnarf.8 dsniff-2.4/urlsnarf.8
 2826 --- dsniff-2.4.orig/urlsnarf.8	2006-01-21 18:56:04.000000000 -0200
 2827 +++ dsniff-2.4/urlsnarf.8	2006-01-21 18:56:40.000000000 -0200
 2828 @@ -9,7 +9,7 @@
 2829  .na
 2830  .nf
 2831  .fi
 2832 -\fBurlsnarf\fR [\fB-n\fR] [\fB-i \fIinterface\fR]  [[\fB-v\fR] \fIpattern [\fIexpression\fR]]
 2833 +\fBurlsnarf\fR [\fB-n\fR] [\fB-i \fIinterface\fR | \fB-p \fIpcapfile\fR]  [[\fB-v\fR] \fIpattern [\fIexpression\fR]]
 2834  .SH DESCRIPTION
 2835  .ad
 2836  .fi
 2837 @@ -21,6 +21,9 @@
 2838  .IP \fB-n\fR
 2839  Do not resolve IP addresses to hostnames.
 2840  .IP "\fB-i \fIinterface\fR"
 2841 +Specify the interface to listen on.
 2842 +.IP "\fB-p \fIpcapfile\fR"
 2843 +Process packets from the specified PCAP capture file instead of the network.
 2844  .IP \fB-v\fR
 2845  "Versus" mode. Invert the sense of matching, to select non-matching
 2846  URLs.
 2847 diff --exclude='*~' -Naur dsniff-2.4.orig/urlsnarf.c dsniff-2.4/urlsnarf.c
 2848 --- dsniff-2.4.orig/urlsnarf.c	2006-01-21 18:56:04.000000000 -0200
 2849 +++ dsniff-2.4/urlsnarf.c	2006-01-21 18:56:45.000000000 -0200
 2850 @@ -41,7 +41,7 @@
 2851  usage(void)
 2852  {
 2853  	fprintf(stderr, "Version: " VERSION "\n"
 2854 -		"Usage: urlsnarf [-n] [-i interface] [[-v] pattern [expression]]\n");
 2855 +		"Usage: urlsnarf [-n] [-i interface | -p pcapfile] [[-v] pattern [expression]]\n");
 2856  	exit(1);
 2857  }
 2858  
 2859 @@ -68,7 +68,7 @@
 2860  		 t->tm_hour - gmt.tm_hour);
 2861  	tz = hours * 60 + t->tm_min - gmt.tm_min;
 2862  	
 2863 -	len = strftime(tstr, sizeof(tstr), "%e/%b/%Y:%X", t);
 2864 +	len = strftime(tstr, sizeof(tstr), "%d/%b/%Y:%X", t);
 2865  	if (len < 0 || len > sizeof(tstr) - 5)
 2866  		return (NULL);
 2867  	
 2868 @@ -145,14 +145,14 @@
 2869  		if (user == NULL)
 2870  			user = "-";
 2871  		if (vhost == NULL)
 2872 -			vhost = libnet_host_lookup(addr->daddr, Opt_dns);
 2873 +			vhost = libnet_addr2name4(addr->daddr, Opt_dns);
 2874  		if (referer == NULL)
 2875  			referer = "-";
 2876  		if (agent == NULL)
 2877  			agent = "-";
 2878  		
 2879  		printf("%s - %s [%s] \"%s http://%s%s\" - - \"%s\" \"%s\"\n",
 2880 -		       libnet_host_lookup(addr->saddr, Opt_dns),
 2881 +		       libnet_addr2name4(addr->saddr, Opt_dns),
 2882  		       user, timestamp(), req, vhost, uri, referer, agent);
 2883  	}
 2884  	fflush(stdout);
 2885 @@ -201,11 +201,14 @@
 2886  	extern int optind;
 2887  	int c;
 2888  	
 2889 -	while ((c = getopt(argc, argv, "i:nvh?V")) != -1) {
 2890 +	while ((c = getopt(argc, argv, "i:p:nvh?V")) != -1) {
 2891  		switch (c) {
 2892  		case 'i':
 2893  			nids_params.device = optarg;
 2894  			break;
 2895 +		case 'p':
 2896 +			nids_params.filename = optarg;
 2897 +			break;
 2898  		case 'n':
 2899  			Opt_dns = 0;
 2900  			break;
 2901 @@ -238,8 +241,24 @@
 2902  	
 2903  	nids_register_tcp(sniff_http_client);
 2904  
 2905 -	warnx("listening on %s [%s]", nids_params.device,
 2906 -	      nids_params.pcap_filter);
 2907 +        if (nids_params.pcap_filter != NULL) {
 2908 +                if (nids_params.filename == NULL) {
 2909 +                        warnx("listening on %s [%s]", nids_params.device,
 2910 +                              nids_params.pcap_filter);
 2911 +                }
 2912 +                else {
 2913 +                        warnx("using %s [%s]", nids_params.filename,
 2914 +                              nids_params.pcap_filter);
 2915 +                }
 2916 +        }
 2917 +        else {
 2918 +                if (nids_params.filename == NULL) {
 2919 +                    warnx("listening on %s", nids_params.device);
 2920 +                }
 2921 +                else {
 2922 +                    warnx("using %s", nids_params.filename);
 2923 +                }
 2924 +        }
 2925  
 2926  	nids_run();
 2927  	
 2928 diff --exclude='*~' -Naur dsniff-2.4.orig/webmitm.c dsniff-2.4/webmitm.c
 2929 --- dsniff-2.4.orig/webmitm.c	2006-01-21 18:56:04.000000000 -0200
 2930 +++ dsniff-2.4/webmitm.c	2006-01-21 18:56:45.000000000 -0200
 2931 @@ -242,7 +242,7 @@
 2932  			word = buf_tok(&msg, "/", 1);
 2933  			vhost = buf_strdup(word);
 2934  		}
 2935 -		ssin.sin_addr.s_addr = libnet_name_resolve(vhost, 1);
 2936 +		ssin.sin_addr.s_addr = libnet_name2addr4(NULL, vhost, 1);
 2937  		free(vhost);
 2938  		
 2939  		if (ssin.sin_addr.s_addr == ntohl(INADDR_LOOPBACK) ||
 2940 @@ -510,7 +510,7 @@
 2941  	argv += optind;
 2942  
 2943  	if (argc == 1) {
 2944 -		if ((static_host = libnet_name_resolve(argv[0], 1)) == -1)
 2945 +		if ((static_host = libnet_name2addr4(NULL, argv[0], 1)) == -1)
 2946  			usage();
 2947  	}
 2948  	else if (argc != 0) usage();
 2949 diff --exclude='*~' -Naur dsniff-2.4.orig/webspy.8 dsniff-2.4/webspy.8
 2950 --- dsniff-2.4.orig/webspy.8	2006-01-21 18:56:04.000000000 -0200
 2951 +++ dsniff-2.4/webspy.8	2006-01-21 18:56:40.000000000 -0200
 2952 @@ -9,7 +9,7 @@
 2953  .na
 2954  .nf
 2955  .fi
 2956 -\fBwebspy\fR [\fB-i \fIinterface\fR] \fIhost\fR
 2957 +\fBwebspy\fR [\fB-i \fIinterface\fR | \fB-p \fIpcapfile\fR] \fIhost\fR
 2958  .SH DESCRIPTION
 2959  .ad
 2960  .fi
 2961 @@ -20,6 +20,8 @@
 2962  .SH OPTIONS
 2963  .IP "\fB-i \fIinterface\fR"
 2964  Specify the interface to listen on.
 2965 +.IP "\fB-p \fIpcapfile\fR"
 2966 +Process packets from the specified PCAP capture file instead of the network.
 2967  .IP \fIhost\fR
 2968  Specify the web client to spy on.
 2969  .SH "SEE ALSO"
 2970 diff --exclude='*~' -Naur dsniff-2.4.orig/webspy.c dsniff-2.4/webspy.c
 2971 --- dsniff-2.4.orig/webspy.c	2006-01-21 18:56:04.000000000 -0200
 2972 +++ dsniff-2.4/webspy.c	2006-01-21 18:56:45.000000000 -0200
 2973 @@ -42,7 +42,7 @@
 2974  usage(void)
 2975  {
 2976  	fprintf(stderr, "Version: " VERSION "\n"
 2977 -		"Usage: %s [-i interface] host\n", progname);
 2978 +		"Usage: %s [-i interface | -p pcapfile] host\n", progname);
 2979  	exit(1);
 2980  }
 2981  
 2982 @@ -126,7 +126,7 @@
 2983  		if (auth == NULL)
 2984  			auth = "";
 2985  		if (vhost == NULL)
 2986 -			vhost = libnet_host_lookup(addr->daddr, 0);
 2987 +			vhost = libnet_addr2name4(addr->daddr, 0);
 2988  		
 2989  		snprintf(cmd, sizeof(cmd), "openURL(http://%s%s%s%s)",
 2990  			 auth, *auth ? "@" : "", vhost, uri);
 2991 @@ -184,11 +184,14 @@
 2992  	extern int optind;
 2993  	int c;
 2994  	
 2995 -	while ((c = getopt(argc, argv, "i:h?V")) != -1) {
 2996 +	while ((c = getopt(argc, argv, "i:p:h?V")) != -1) {
 2997  		switch (c) {
 2998  		case 'i':
 2999  			nids_params.device = optarg;
 3000  			break;
 3001 +		case 'p':
 3002 +			nids_params.filename = optarg;
 3003 +			break;
 3004  		default:
 3005  			usage();
 3006  		}
 3007 @@ -202,7 +205,7 @@
 3008  	cmdtab[0] = cmd;
 3009  	cmdtab[1] = NULL;
 3010  	
 3011 -	if ((host = libnet_name_resolve(argv[0], 1)) == -1)
 3012 +	if ((host = libnet_name2addr4(NULL, argv[0], 1)) == -1)
 3013  		errx(1, "unknown host");
 3014  	
 3015  	if ((dpy = XOpenDisplay(NULL)) == NULL)
 3016 @@ -216,7 +219,13 @@
 3017  	
 3018  	nids_register_tcp(sniff_http_client);
 3019  
 3020 -	warnx("listening on %s", nids_params.device);
 3021 +        if (nids_params.filename == NULL) {
 3022 +                warnx("listening on %s", nids_params.device);
 3023 +        }
 3024 +        else {
 3025 +                warnx("using %s", nids_params.filename);
 3026 +        }
 3027 +
 3028  
 3029  	nids_run();
 3030  	
 3031 diff --exclude='*~' -Naur dsniff-2.4.orig/webspy.c.orig dsniff-2.4/webspy.c.orig
 3032 --- dsniff-2.4.orig/webspy.c.orig	1969-12-31 21:00:00.000000000 -0300
 3033 +++ dsniff-2.4/webspy.c.orig	2006-01-21 18:56:40.000000000 -0200
 3034 @@ -0,0 +1,235 @@
 3035 +/*
 3036 + * webspy.c
 3037 + *
 3038 + * Sniff a user's web session, follow it real-time in our browser.
 3039 + *
 3040 + * Copyright (c) 1999 Dug Song <dugsong@monkey.org>
 3041 + *
 3042 + * $Id: webspy.c,v 1.28 2001/03/15 08:33:05 dugsong Exp $
 3043 + */
 3044 +
 3045 +#include "config.h"
 3046 +
 3047 +#include <sys/types.h>
 3048 +#include <sys/socket.h>
 3049 +#include <netinet/in.h>
 3050 +#include <arpa/inet.h>
 3051 +#include <netdb.h>
 3052 +
 3053 +#include <stdio.h>
 3054 +#include <stdlib.h>
 3055 +#include <unistd.h>
 3056 +#include <string.h>
 3057 +#include <err.h>
 3058 +#include <X11/Xlib.h>
 3059 +#include <libnet.h>
 3060 +#include <nids.h>
 3061 +
 3062 +#include "base64.h"
 3063 +#include "buf.h"
 3064 +#include "version.h"
 3065 +
 3066 +/* for jwz's remote.c. */
 3067 +extern int mozilla_remote_commands (Display *, Window, char **);
 3068 +char	*expected_mozilla_version = "4.7";
 3069 +char	*progname = "webspy";
 3070 +
 3071 +Display		*dpy;
 3072 +char		 cmd[2048], *cmdtab[2];
 3073 +in_addr_t	 host;
 3074 +
 3075 +static void
 3076 +usage(void)
 3077 +{
 3078 +	fprintf(stderr, "Version: " VERSION "\n"
 3079 +		"Usage: %s [-i interface | -p pcapfile] host\n", progname);
 3080 +	exit(1);
 3081 +}
 3082 +
 3083 +static int
 3084 +is_display_uri(char *uri)
 3085 +{
 3086 +	static char *good_prefixes[] = { NULL };
 3087 +	static char *good_suffixes[] = { ".html", ".htm", "/", ".shtml",
 3088 +					 ".cgi", ".asp", ".php3", ".txt",
 3089 +					 ".xml", ".asc", NULL };
 3090 +	int len, slen;
 3091 +	char **pp, *p;
 3092 +	
 3093 +	/* Get URI length, without QUERY_INFO */
 3094 +	if ((p = strchr(uri, '?')) != NULL) {
 3095 +		len = p - uri;
 3096 +	}
 3097 +	else len = strlen(uri);
 3098 +	
 3099 +	for (pp = good_suffixes; *pp != NULL; pp++) {
 3100 +		if (len < (slen = strlen(*pp))) continue;
 3101 +		if (strncasecmp(&uri[len - slen], *pp, slen) == 0)
 3102 +			return (1);
 3103 +	}
 3104 +	for (pp = good_prefixes; *pp != NULL; pp++) {
 3105 +		if (len < (slen = strlen(*pp))) continue;
 3106 +		if (strncasecmp(uri, *pp, slen) == 0)
 3107 +			return (1);
 3108 +	}
 3109 +	return (0);
 3110 +}
 3111 +
 3112 +/*
 3113 +  XXX - we should really be sniffing (and HTML-parsing) the returned
 3114 +  pages, not just the request URLs. this is why we don't handle
 3115 +  frames, some CGIs, banner ads, etc. correctly.
 3116 +*/
 3117 +static int
 3118 +process_http_request(struct tuple4 *addr, u_char *data, int len)
 3119 +{
 3120 +	struct buf *msg, buf;
 3121 +	char *p, *req, *uri, *vhost, *auth;
 3122 +	int i;
 3123 +
 3124 +	buf_init(&buf, data, len);
 3125 +	
 3126 +	while ((i = buf_index(&buf, "\r\n\r\n", 4)) >= 0) {
 3127 +		msg = buf_tok(&buf, NULL, i);
 3128 +		msg->base[msg->end] = '\0';
 3129 +		buf_skip(&buf, 4);
 3130 +
 3131 +		req = strtok(buf_ptr(msg), "\r\n");
 3132 +
 3133 +		if (strncmp(req, "GET ", 4) != 0 &&
 3134 +		    strncmp(req, "POST ", 5) != 0 &&
 3135 +		    strncmp(req, "CONNECT ", 8) != 0)
 3136 +			continue;
 3137 +		
 3138 +		vhost = auth = NULL;
 3139 +		uri = strchr(req, ' '); *uri++ = '\0'; strtok(uri, " ");
 3140 +		
 3141 +		if (strncmp(uri, "http://", 7) == 0) {
 3142 +			vhost = uri + 7;
 3143 +			uri = strchr(vhost, '/');
 3144 +			memmove(uri + 1, uri, strlen(uri));
 3145 +		}
 3146 +		if (!is_display_uri(uri))
 3147 +			continue;
 3148 +		
 3149 +		while ((p = strtok(NULL, "\r\n")) != NULL) {
 3150 +			if (strncasecmp(p, "Authorization: Basic ", 21) == 0) {
 3151 +				p += 21;
 3152 +				i = base64_pton(p, p, strlen(p));
 3153 +				p[i] = '\0';
 3154 +				auth = p;
 3155 +			}
 3156 +			else if (strncasecmp(p, "Host: ", 6) == 0) {
 3157 +				vhost = p + 6;
 3158 +			}
 3159 +		}
 3160 +		if (auth == NULL)
 3161 +			auth = "";
 3162 +		if (vhost == NULL)
 3163 +			vhost = libnet_host_lookup(addr->daddr, 0);
 3164 +		
 3165 +		snprintf(cmd, sizeof(cmd), "openURL(http://%s%s%s%s)",
 3166 +			 auth, *auth ? "@" : "", vhost, uri);
 3167 +		fprintf(stderr, "%s\n", cmd);
 3168 +		
 3169 +		mozilla_remote_commands(dpy, 0, cmdtab);
 3170 +	}
 3171 +	return (len - buf_len(&buf));
 3172 +}
 3173 +
 3174 +static void
 3175 +sniff_http_client(struct tcp_stream *ts, void **yoda)
 3176 +{
 3177 +	int i;
 3178 +	
 3179 +	/* Only handle HTTP client traffic. */
 3180 +	if (ts->addr.saddr != host ||
 3181 +	    (ts->addr.dest != 80 && ts->addr.dest != 3128 &&
 3182 +	     ts->addr.dest != 8080))
 3183 +		return;
 3184 +	
 3185 +	switch (ts->nids_state) {
 3186 +	case NIDS_JUST_EST:
 3187 +		/* Collect data. */
 3188 +		ts->server.collect = 1;
 3189 +		
 3190 +	case NIDS_DATA:
 3191 +		if (ts->server.count_new != 0) {
 3192 +			i = process_http_request(&ts->addr, ts->server.data,
 3193 +						 ts->server.count -
 3194 +						 ts->server.offset);
 3195 +			nids_discard(ts, i);
 3196 +		}
 3197 +		break;
 3198 +		
 3199 +	default:
 3200 +		if (ts->server.count != 0) {
 3201 +			process_http_request(&ts->addr, ts->server.data,
 3202 +					     ts->server.count -
 3203 +					     ts->server.offset);
 3204 +		}
 3205 +		break;
 3206 +	}
 3207 +}
 3208 +
 3209 +static void
 3210 +null_syslog(int type, int errnum, struct ip *iph, void *data)
 3211 +{
 3212 +}
 3213 +
 3214 +int
 3215 +main(int argc, char *argv[])
 3216 +{
 3217 +	extern char *optarg;
 3218 +	extern int optind;
 3219 +	int c;
 3220 +	
 3221 +	while ((c = getopt(argc, argv, "i:p:h?V")) != -1) {
 3222 +		switch (c) {
 3223 +		case 'i':
 3224 +			nids_params.device = optarg;
 3225 +			break;
 3226 +		case 'p':
 3227 +			nids_params.filename = optarg;
 3228 +			break;
 3229 +		default:
 3230 +			usage();
 3231 +		}
 3232 +	}
 3233 +	argc -= optind;
 3234 +	argv += optind;
 3235 +	
 3236 +	if (argc != 1)
 3237 +		usage();
 3238 +	
 3239 +	cmdtab[0] = cmd;
 3240 +	cmdtab[1] = NULL;
 3241 +	
 3242 +	if ((host = libnet_name_resolve(argv[0], 1)) == -1)
 3243 +		errx(1, "unknown host");
 3244 +	
 3245 +	if ((dpy = XOpenDisplay(NULL)) == NULL)
 3246 +		errx(1, "connection to local X server failed!");
 3247 +	
 3248 +	nids_params.scan_num_hosts = 0;
 3249 +	nids_params.syslog = null_syslog;
 3250 +	
 3251 +	if (!nids_init())
 3252 +		errx(1, "%s", nids_errbuf);
 3253 +	
 3254 +	nids_register_tcp(sniff_http_client);
 3255 +
 3256 +        if (nids_params.filename == NULL) {
 3257 +                warnx("listening on %s", nids_params.device);
 3258 +        }
 3259 +        else {
 3260 +                warnx("using %s", nids_params.filename);
 3261 +        }
 3262 +
 3263 +
 3264 +	nids_run();
 3265 +	
 3266 +	/* NOTREACHED */
 3267 +	
 3268 +	exit(0);
 3269 +}

Generated by cgit