diff --git a/sbin/ipfw/ipfw.8 b/sbin/ipfw/ipfw.8 index 7198d049561c..1830b0b6eeea 100644 --- a/sbin/ipfw/ipfw.8 +++ b/sbin/ipfw/ipfw.8 @@ -256,9 +256,7 @@ The sense of the match can be inverted by preceding an address with the ``not'' modifier, causing all other addresses to be matched instead. This does not affect the selection of port numbers. .Pp -With the TCP and UDP -.Em protocols , -optional +With the TCP and UDP protocols, optional .Em ports may be specified as: .Pp @@ -268,9 +266,9 @@ may be specified as: .Pp Service names (from .Pa /etc/services ) -may not be used instead of a numeric port value. -Also, note that a range may only be specified as the first value, -and the port list is limited to +may be used instead of numeric port values. +A range may only be specified as the first value, +and the length of the port list is limited to .Dv IP_FW_MAX_PORTS (as defined in .Pa /usr/src/sys/netinet/ip_fw.h ) @@ -459,8 +457,9 @@ This rule diverts all incoming packets from 192.168.2.0/24 to divert port 5000: .Pp .Dl ipfw divert 5000 all from 192.168.2.0/24 to any in .Sh SEE ALSO -.Xr divert 4 , .Xr ip 4 , +.Xr ipfirewall 4 , +.Xr divert 4 , .Xr protocols 5 , .Xr services 5 , .Xr reboot 8 , @@ -484,6 +483,8 @@ Incoming packet fragments diverted by are reassembled before delivery to the socket, whereas fragments diverted via .Ar tee are not. +.Pp +Port aliases containing dashes cannot be first in a list. .Sh AUTHORS Ugen J. S. Antsilevich, Poul-Henning Kamp, diff --git a/sbin/ipfw/ipfw.c b/sbin/ipfw/ipfw.c index 223e2e80d92a..5c6625553683 100644 --- a/sbin/ipfw/ipfw.c +++ b/sbin/ipfw/ipfw.c @@ -16,7 +16,7 @@ * * NEW command line interface for IP firewall facility * - * $Id: ipfw.c,v 1.43 1997/06/02 05:02:33 julian Exp $ + * $Id: ipfw.c,v 1.44 1997/06/13 06:27:12 charnier Exp $ * */ @@ -548,6 +548,37 @@ add_port(cnt, ptr, off, port) (*cnt)++; } +static int +lookup_port(const char *arg, int test, int nodash) +{ + int val; + char *earg, buf[32]; + struct servent *s; + + snprintf(buf, sizeof(buf), "%s", arg); + buf[strcspn(arg, nodash ? "-," : ",")] = 0; + val = (int) strtoul(buf, &earg, 0); + if (!*buf || *earg) { + setservent(1); + if ((s = getservbyname(buf, NULL))) { + val = htons(s->s_port); + } else { + if (!test) { + errx(1, "unknown port ``%s''", arg); + } + val = -1; + } + } else { + if (val < 0 || val > 0xffff) { + if (!test) { + errx(1, "port ``%s'' out of range", arg); + } + val = -1; + } + } + return(val); +} + int fill_port(cnt, ptr, off, arg) u_short *cnt, *ptr, off; @@ -556,17 +587,17 @@ fill_port(cnt, ptr, off, arg) char *s; int initial_range = 0; - s = strchr(arg,'-'); - if (s) { + s = arg + strcspn(arg, "-,"); /* first port name can't have a dash */ + if (*s == '-') { *s++ = '\0'; if (strchr(arg, ',')) errx(1, "port range must be first in list"); - add_port(cnt, ptr, off, *arg ? atoi(arg) : 0x0000); + add_port(cnt, ptr, off, *arg ? lookup_port(arg, 0, 0) : 0x0000); arg = s; s = strchr(arg,','); if (s) *s++ = '\0'; - add_port(cnt, ptr, off, *arg ? atoi(arg) : 0xffff); + add_port(cnt, ptr, off, *arg ? lookup_port(arg, 0, 0) : 0xffff); arg = s; initial_range = 1; } @@ -574,7 +605,7 @@ fill_port(cnt, ptr, off, arg) s = strchr(arg,','); if (s) *s++ = '\0'; - add_port(cnt, ptr, off, atoi(arg)); + add_port(cnt, ptr, off, lookup_port(arg, 0, 0)); arg = s; } return initial_range; @@ -843,7 +874,7 @@ add(ac,av) fill_ip(&rule.fw_src, &rule.fw_smsk, &ac, &av); - if (ac && isdigit(**av)) { + if (ac && (isdigit(**av) || lookup_port(*av, 1, 1) >= 0)) { u_short nports = 0; if (fill_port(&nports, rule.fw_pts, 0, *av)) @@ -866,7 +897,7 @@ add(ac,av) fill_ip(&rule.fw_dst, &rule.fw_dmsk, &ac, &av); - if (ac && isdigit(**av)) { + if (ac && (isdigit(**av) || lookup_port(*av, 1, 1) >= 0)) { u_short nports = 0; if (fill_port(&nports,