diff -ur libpcap-orig/gencode.c libpcap-portrange/gencode.c
--- libpcap-orig/gencode.c	Wed Apr 23 22:17:41 2003
+++ libpcap-portrange/gencode.c	Wed Apr 23 22:18:46 2003
@@ -185,11 +185,14 @@
 #endif
 static struct block *gen_ipfrag(void);
 static struct block *gen_portatom(int, bpf_int32);
+static struct block *gen_portrangeatom(int, bpf_int32, bpf_int32);
 #ifdef INET6
 static struct block *gen_portatom6(int, bpf_int32);
 #endif
 struct block *gen_portop(int, int, int);
 static struct block *gen_port(int, int, int);
+struct block *gen_portrangeop(int, int, int, int);
+static struct block *gen_portrange(int, int, int, int);
 #ifdef INET6
 struct block *gen_portop6(int, int, int);
 static struct block *gen_port6(int, int, int);
@@ -3212,6 +3215,120 @@
 }
 #endif /* INET6 */
 
+/* gen_portrange code */
+struct block *
+gen_portrangeatom (off, v1, v2)
+	int off;
+	bpf_int32 v1, v2; /* suppose that v1 <= v2 */
+{
+	struct slist *s1;
+	struct slist *s2;
+
+	struct block *b1;
+	struct block *b1bis;
+	struct block *b2;
+
+	s1 = new_stmt(BPF_LDX|BPF_MSH|BPF_B);
+	s1->s.k = off_nl;
+
+	s1->next = new_stmt(BPF_LD|BPF_IND|BPF_H);
+	s1->next->s.k = off_nl + off;
+
+	b1 = new_block(JMP(BPF_JGE));
+	b1->stmts = s1;
+	b1->s.k = v1;
+
+	s2 = new_stmt(BPF_LDX|BPF_MSH|BPF_B);
+	s2->s.k = off_nl;
+
+	s2->next = new_stmt(BPF_LD|BPF_IND|BPF_H);
+	s2->next->s.k = off_nl + off;
+
+	b2 = new_block(JMP(BPF_JGT));
+	gen_not (b2);
+	b2->stmts = s2;
+	b2->s.k = v2;
+
+	gen_and (b1, b2); 
+
+	return b2;
+}
+
+struct block *
+gen_portrangeop (port1, port2, ip_proto, dir)
+	int port1, port2;
+	int ip_proto;
+	int dir;
+{
+	struct block *b0, *b1, *tmp;
+
+	tmp = gen_cmp(off_nl + 9, BPF_B, (bpf_int32)ip_proto);
+	b0 = gen_ipfrag();
+	gen_and(tmp, b0);
+
+	switch (dir) {
+	case Q_SRC:
+		b1 = gen_portrangeatom (0, (bpf_int32)port1, (bpf_int32)port2);
+		break;
+
+	case Q_DST:
+		b1 = gen_portrangeatom (2, (bpf_int32)port1, (bpf_int32)port2);
+		break;
+
+	case Q_OR:
+	case Q_DEFAULT:
+		tmp = gen_portrangeatom (0, (bpf_int32)port1, (bpf_int32)port2);
+		b1 = gen_portrangeatom (2, (bpf_int32)port1, (bpf_int32)port2);
+		gen_or (tmp, b1);
+		break;
+
+	case Q_AND:
+		tmp = gen_portrangeatom (0, (bpf_int32)port1, (bpf_int32)port2);
+		b1 = gen_portrangeatom (2, (bpf_int32)port1, (bpf_int32)port2);
+		gen_and(tmp, b1);
+		break;
+
+	default:
+		abort ();
+	}
+	gen_and(b0, b1);
+
+	return b1;
+}
+
+static struct block *
+gen_portrange (port1, port2, ip_proto, dir)
+	int port1, port2;
+	int ip_proto;
+	int dir;
+{
+	struct block *b0, *b1, *tmp;
+
+	/* ether proto ip */
+	b0 =  gen_linktype(ETHERTYPE_IP);
+
+	switch (ip_proto) {
+	case IPPROTO_UDP:
+	case IPPROTO_TCP:
+	case IPPROTO_SCTP:
+		b1 = gen_portrangeop(port1, port2, ip_proto, dir);
+		break;
+
+	case PROTO_UNDEF:
+		tmp = gen_portrangeop(port1, port2, IPPROTO_TCP, dir);
+		b1 = gen_portrangeop(port1, port2, IPPROTO_UDP, dir);
+		gen_or(tmp, b1);
+		tmp = gen_portrangeop(port1, port2, IPPROTO_SCTP, dir);
+		gen_or(tmp, b1);
+		break;
+
+	default:
+		abort();
+	}
+	gen_and(b0, b1);
+	return b1;
+}
+
 static int
 lookup_proto(name, proto)
 	register const char *name;
@@ -3780,6 +3897,7 @@
 #endif /*INET6*/
 	struct block *b, *tmp;
 	int port, real_proto;
+	int port1, port2;
 
 	switch (q.addr) {
 
@@ -3987,6 +4105,46 @@
 	    }
 #endif /* INET6 */
 
+	case Q_PORTRANGE:
+		if (proto != Q_DEFAULT &&
+		    proto != Q_UDP && proto != Q_TCP && proto != Q_SCTP)
+			bpf_error("illegal qualifier of 'portrange'");
+		if (pcap_nametoportrange(name, &port1, &port2, &real_proto) == 0) 
+			bpf_error("unknown range port '%s'", name);
+
+		if (proto == Q_UDP) {
+			if (real_proto == IPPROTO_TCP)
+				bpf_error("range port '%s' is tcp", name);
+			else if (real_proto == IPPROTO_SCTP)
+				bpf_error("range port '%s' is sctp", name);
+		else
+			real_proto = IPPROTO_UDP;
+		}
+
+		if (proto == Q_TCP) {
+			if (real_proto == IPPROTO_UDP)
+				bpf_error("range port '%s' is udp", name);
+			else if (real_proto == IPPROTO_SCTP)
+				bpf_error("range port '%s' is sctp", name);
+		else
+			real_proto = IPPROTO_TCP;
+		}
+
+		if (proto == Q_SCTP) {
+			if (real_proto == IPPROTO_UDP)
+				bpf_error("range port '%s' is udp", name);
+			else if (real_proto == IPPROTO_TCP)
+				bpf_error("range port '%s' is tcp", name);
+			else
+				real_proto = IPPROTO_SCTP;	
+		}
+
+		/* XXX INET6 TODO */
+		if (port1 < port2)
+			return gen_portrange (port1, port2, real_proto, dir);
+
+		return gen_portrange (port2, port1, real_proto, dir);
+
 	case Q_GATEWAY:
 #ifndef INET6
 		eaddr = pcap_ether_hostton(name);
@@ -4132,6 +4290,20 @@
 		return b;
 	    }
 #endif /* INET6 */
+
+	case Q_PORTRANGE:
+		if (proto == Q_UDP)
+			proto = IPPROTO_UDP;
+		else if (proto == Q_TCP)
+			proto = IPPROTO_TCP;
+		else if (proto == Q_SCTP)
+			proto = IPPROTO_SCTP;
+		else if (proto == Q_DEFAULT)
+			proto = PROTO_UNDEF;
+		else
+			bpf_error("illegal qualifier of 'port'");
+
+		return (gen_portrange ((int)v, (int)v, proto, dir));
 
 	case Q_GATEWAY:
 		bpf_error("'gateway' requires a name");
diff -ur libpcap-orig/gencode.h libpcap-portrange/gencode.h
--- libpcap-orig/gencode.h	Wed Apr 23 22:17:41 2003
+++ libpcap-portrange/gencode.h	Wed Apr 23 22:18:52 2003
@@ -63,6 +63,7 @@
 #define Q_GATEWAY	4
 #define Q_PROTO		5
 #define Q_PROTOCHAIN	6
+#define Q_PORTRANGE	7
 
 /* Protocol qualifiers. */
 
diff -ur libpcap-orig/grammar.y libpcap-portrange/grammar.y
--- libpcap-orig/grammar.y	Wed Apr 23 22:17:41 2003
+++ libpcap-portrange/grammar.y	Wed Apr 23 22:20:03 2003
@@ -115,7 +115,7 @@
 %type	<blk>	atmfieldvalue atmvalue atmlistvalue
 
 %token  DST SRC HOST GATEWAY
-%token  NET MASK PORT LESS GREATER PROTO PROTOCHAIN CBYTE
+%token  NET MASK PORT PORTRANGE LESS GREATER PROTO PROTOCHAIN CBYTE
 %token  ARP RARP IP SCTP TCP UDP ICMP IGMP IGRP PIM VRRP
 %token  ATALK AARP DECNET LAT SCA MOPRC MOPDL
 %token  TK_BROADCAST TK_MULTICAST
@@ -272,6 +272,7 @@
 aqual:	  HOST			{ $$ = Q_HOST; }
 	| NET			{ $$ = Q_NET; }
 	| PORT			{ $$ = Q_PORT; }
+	| PORTRANGE		{ $$ = Q_PORTRANGE; }
 	;
 /* non-directional address type qualifiers */
 ndaqual:  GATEWAY		{ $$ = Q_GATEWAY; }
diff -ur libpcap-orig/nametoaddr.c libpcap-portrange/nametoaddr.c
--- libpcap-orig/nametoaddr.c	Wed Apr 23 22:17:41 2003
+++ libpcap-portrange/nametoaddr.c	Wed Apr 23 22:18:57 2003
@@ -209,6 +209,52 @@
 }
 
 int
+pcap_nametoportrange(const char *name, int *port1, int *port2, int *proto)
+{
+	u_int p1, p2;
+	char *off, *cpy;
+	int save_proto;
+
+    if (sscanf((char *)name, "%d-%d", &p1, &p2) != 2)
+    {
+		if ((cpy = strdup (name)) == NULL)
+			return 0;
+
+		if ((off = strchr (cpy, '-')) == NULL)
+		{
+			free (cpy);
+			return 0;
+		}
+
+		*off = '\0';
+
+        if (pcap_nametoport(cpy, port1, proto) == 0)
+		{
+			free (cpy);
+            return 0;
+		}
+		save_proto = *proto;
+
+        if (pcap_nametoport(off + 1, port2, proto) == 0)
+		{
+			free (cpy);
+            return 0;
+		}
+
+		if (*proto != save_proto)
+			*proto = PROTO_UNDEF;
+    }
+    else
+    {
+        *port1 = p1;
+        *port2 = p2;
+		*proto = PROTO_UNDEF;
+    }
+
+	return 1;
+}
+
+int
 pcap_nametoproto(const char *str)
 {
 	struct protoent *p;
diff -ur libpcap-orig/pcap-namedb.h libpcap-portrange/pcap-namedb.h
--- libpcap-orig/pcap-namedb.h	Wed Apr 23 22:17:41 2003
+++ libpcap-portrange/pcap-namedb.h	Wed Apr 23 22:19:01 2003
@@ -65,6 +65,7 @@
 bpf_u_int32 pcap_nametonetaddr(const char *);
 
 int	pcap_nametoport(const char *, int *, int *);
+int 	pcap_nametoportrange(const char *, int *, int *, int *);
 int	pcap_nametoproto(const char *);
 int	pcap_nametoeproto(const char *);
 /*
diff -ur libpcap-orig/scanner.l libpcap-portrange/scanner.l
--- libpcap-orig/scanner.l	Wed Apr 23 22:17:42 2003
+++ libpcap-portrange/scanner.l	Wed Apr 23 22:19:04 2003
@@ -234,6 +234,7 @@
 net		return NET;
 mask		return MASK;
 port		return PORT;
+portrange	return PORTRANGE;
 proto		return PROTO;
 protochain	{
 #ifdef NO_PROTOCHAIN
