filter.c (78189) | filter.c (81634) |
---|---|
1/*- 2 * Copyright (c) 1996 - 2001 Brian Somers <brian@Awfulhak.org> 3 * based on work by Toshiharu OHNO <tony-o@iij.ad.jp> 4 * Internet Initiative Japan, Inc (IIJ) 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 11 unchanged lines hidden (view full) --- 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * | 1/*- 2 * Copyright (c) 1996 - 2001 Brian Somers <brian@Awfulhak.org> 3 * based on work by Toshiharu OHNO <tony-o@iij.ad.jp> 4 * Internet Initiative Japan, Inc (IIJ) 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 11 unchanged lines hidden (view full) --- 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * |
28 * $FreeBSD: head/usr.sbin/ppp/filter.c 78189 2001-06-13 21:52:19Z brian $ | 28 * $FreeBSD: head/usr.sbin/ppp/filter.c 81634 2001-08-14 16:05:52Z brian $ |
29 */ 30 31#include <sys/param.h> 32#include <netinet/in.h> 33#include <arpa/inet.h> 34#include <netdb.h> 35#include <netinet/in_systm.h> 36#include <netinet/ip.h> | 29 */ 30 31#include <sys/param.h> 32#include <netinet/in.h> 33#include <arpa/inet.h> 34#include <netdb.h> 35#include <netinet/in_systm.h> 36#include <netinet/ip.h> |
37#include <sys/socket.h> |
|
37#include <sys/un.h> 38 39#include <stdio.h> 40#include <stdlib.h> 41#include <strings.h> 42#include <termios.h> 43 44#include "layer.h" --- 6 unchanged lines hidden (view full) --- 51#include "throughput.h" 52#include "lqr.h" 53#include "hdlc.h" 54#include "fsm.h" 55#include "lcp.h" 56#include "ccp.h" 57#include "link.h" 58#include "slcompress.h" | 38#include <sys/un.h> 39 40#include <stdio.h> 41#include <stdlib.h> 42#include <strings.h> 43#include <termios.h> 44 45#include "layer.h" --- 6 unchanged lines hidden (view full) --- 52#include "throughput.h" 53#include "lqr.h" 54#include "hdlc.h" 55#include "fsm.h" 56#include "lcp.h" 57#include "ccp.h" 58#include "link.h" 59#include "slcompress.h" |
60#include "ncpaddr.h" 61#include "ip.h" |
|
59#include "ipcp.h" 60#include "filter.h" 61#include "descriptor.h" 62#include "prompt.h" 63#include "mp.h" 64#ifndef NORADIUS 65#include "radius.h" 66#endif | 62#include "ipcp.h" 63#include "filter.h" 64#include "descriptor.h" 65#include "prompt.h" 66#include "mp.h" 67#ifndef NORADIUS 68#include "radius.h" 69#endif |
70#include "ipv6cp.h" 71#include "ncp.h" |
|
67#include "bundle.h" 68 | 72#include "bundle.h" 73 |
69static int filter_Nam2Proto(int, char const *const *); | |
70static int filter_Nam2Op(const char *); 71 | 74static int filter_Nam2Op(const char *); 75 |
72static const u_int32_t netmasks[33] = { 73 0x00000000, 74 0x80000000, 0xC0000000, 0xE0000000, 0xF0000000, 75 0xF8000000, 0xFC000000, 0xFE000000, 0xFF000000, 76 0xFF800000, 0xFFC00000, 0xFFE00000, 0xFFF00000, 77 0xFFF80000, 0xFFFC0000, 0xFFFE0000, 0xFFFF0000, 78 0xFFFF8000, 0xFFFFC000, 0xFFFFE000, 0xFFFFF000, 79 0xFFFFF800, 0xFFFFFC00, 0xFFFFFE00, 0xFFFFFF00, 80 0xFFFFFF80, 0xFFFFFFC0, 0xFFFFFFE0, 0xFFFFFFF0, 81 0xFFFFFFF8, 0xFFFFFFFC, 0xFFFFFFFE, 0xFFFFFFFF, 82}; 83 84struct in_addr 85bits2mask(int bits) 86{ 87 struct in_addr result; 88 89 result.s_addr = htonl(netmasks[bits]); 90 return result; 91} 92 93int 94ParseAddr(struct ipcp *ipcp, const char *data, 95 struct in_addr *paddr, struct in_addr *pmask, int *pwidth) 96{ 97 int bits, len; 98 char *wp; 99 const char *cp; 100 101 if (pmask) 102 pmask->s_addr = INADDR_BROADCAST; /* Assume 255.255.255.255 as default */ 103 104 cp = pmask || pwidth ? strchr(data, '/') : NULL; 105 len = cp ? cp - data : strlen(data); 106 107 if (ipcp && strncasecmp(data, "HISADDR", len) == 0) 108 *paddr = ipcp->peer_ip; 109 else if (ipcp && strncasecmp(data, "MYADDR", len) == 0) 110 *paddr = ipcp->my_ip; 111 else if (ipcp && strncasecmp(data, "DNS0", len) == 0) 112 *paddr = ipcp->ns.dns[0]; 113 else if (ipcp && strncasecmp(data, "DNS1", len) == 0) 114 *paddr = ipcp->ns.dns[1]; 115 else { 116 char *s; 117 118 s = (char *)alloca(len + 1); 119 strncpy(s, data, len); 120 s[len] = '\0'; 121 *paddr = GetIpAddr(s); 122 if (paddr->s_addr == INADDR_NONE) { 123 log_Printf(LogWARN, "ParseAddr: %s: Bad address\n", s); 124 return 0; 125 } 126 } 127 if (cp && *++cp) { 128 bits = strtol(cp, &wp, 0); 129 if (cp == wp || bits < 0 || bits > 32) { 130 log_Printf(LogWARN, "ParseAddr: bad mask width.\n"); 131 return 0; 132 } 133 } else if (paddr->s_addr == INADDR_ANY) 134 /* An IP of 0.0.0.0 without a width is anything */ 135 bits = 0; 136 else 137 /* If a valid IP is given without a width, assume 32 bits */ 138 bits = 32; 139 140 if (pwidth) 141 *pwidth = bits; 142 143 if (pmask) { 144 if (paddr->s_addr == INADDR_ANY) 145 pmask->s_addr = INADDR_ANY; 146 else 147 *pmask = bits2mask(bits); 148 } 149 150 return 1; 151} 152 | |
153static int | 76static int |
154ParsePort(const char *service, int proto) | 77ParsePort(const char *service, const char *proto) |
155{ | 78{ |
156 const char *protocol_name; 157 char *cp; | |
158 struct servent *servent; | 79 struct servent *servent; |
80 char *cp; |
|
159 int port; 160 | 81 int port; 82 |
161 switch (proto) { 162 case P_IPIP: 163 protocol_name = "ipip"; 164 break; 165 case P_UDP: 166 protocol_name = "udp"; 167 break; 168 case P_TCP: 169 protocol_name = "tcp"; 170 break; 171 default: 172 protocol_name = 0; 173 } 174 175 servent = getservbyname(service, protocol_name); | 83 servent = getservbyname(service, proto); |
176 if (servent != 0) 177 return ntohs(servent->s_port); 178 179 port = strtol(service, &cp, 0); 180 if (cp == service) { 181 log_Printf(LogWARN, "ParsePort: %s is not a port name or number.\n", 182 service); 183 return 0; 184 } 185 return port; 186} 187 188/* 189 * ICMP Syntax: src eq icmp_message_type 190 */ 191static int | 84 if (servent != 0) 85 return ntohs(servent->s_port); 86 87 port = strtol(service, &cp, 0); 88 if (cp == service) { 89 log_Printf(LogWARN, "ParsePort: %s is not a port name or number.\n", 90 service); 91 return 0; 92 } 93 return port; 94} 95 96/* 97 * ICMP Syntax: src eq icmp_message_type 98 */ 99static int |
192ParseIcmp(int argc, char const *const *argv, struct filterent *tgt) | 100ParseIcmp(int argc, char const *const *argv, const struct protoent *pe, 101 struct filterent *tgt) |
193{ 194 int type; 195 char *cp; 196 197 switch (argc) { 198 case 0: 199 /* permit/deny all ICMP types */ | 102{ 103 int type; 104 char *cp; 105 106 switch (argc) { 107 case 0: 108 /* permit/deny all ICMP types */ |
200 tgt->f_srcop = OP_NONE; | 109 tgt->f_srcop = tgt->f_dstop = OP_NONE; |
201 break; 202 203 case 3: 204 if (!strcmp(*argv, "src") && !strcmp(argv[1], "eq")) { 205 type = strtol(argv[2], &cp, 0); 206 if (cp == argv[2]) { 207 log_Printf(LogWARN, "ParseIcmp: type is expected.\n"); 208 return 0; 209 } 210 tgt->f_srcop = OP_EQ; 211 tgt->f_srcport = type; | 110 break; 111 112 case 3: 113 if (!strcmp(*argv, "src") && !strcmp(argv[1], "eq")) { 114 type = strtol(argv[2], &cp, 0); 115 if (cp == argv[2]) { 116 log_Printf(LogWARN, "ParseIcmp: type is expected.\n"); 117 return 0; 118 } 119 tgt->f_srcop = OP_EQ; 120 tgt->f_srcport = type; |
121 tgt->f_dstop = OP_NONE; |
|
212 } 213 break; 214 215 default: 216 log_Printf(LogWARN, "ParseIcmp: bad icmp syntax.\n"); 217 return 0; 218 } 219 return 1; 220} 221 222/* 223 * UDP Syntax: [src op port] [dst op port] 224 */ 225static int | 122 } 123 break; 124 125 default: 126 log_Printf(LogWARN, "ParseIcmp: bad icmp syntax.\n"); 127 return 0; 128 } 129 return 1; 130} 131 132/* 133 * UDP Syntax: [src op port] [dst op port] 134 */ 135static int |
226ParseUdpOrTcp(int argc, char const *const *argv, int proto, | 136ParseUdpOrTcp(int argc, char const *const *argv, const struct protoent *pe, |
227 struct filterent *tgt) 228{ 229 tgt->f_srcop = tgt->f_dstop = OP_NONE; 230 tgt->f_estab = tgt->f_syn = tgt->f_finrst = 0; 231 232 if (argc >= 3 && !strcmp(*argv, "src")) { 233 tgt->f_srcop = filter_Nam2Op(argv[1]); 234 if (tgt->f_srcop == OP_NONE) { | 137 struct filterent *tgt) 138{ 139 tgt->f_srcop = tgt->f_dstop = OP_NONE; 140 tgt->f_estab = tgt->f_syn = tgt->f_finrst = 0; 141 142 if (argc >= 3 && !strcmp(*argv, "src")) { 143 tgt->f_srcop = filter_Nam2Op(argv[1]); 144 if (tgt->f_srcop == OP_NONE) { |
235 log_Printf(LogWARN, "ParseUdpOrTcp: bad operation\n"); | 145 log_Printf(LogWARN, "ParseUdpOrTcp: bad operator\n"); |
236 return 0; 237 } | 146 return 0; 147 } |
238 tgt->f_srcport = ParsePort(argv[2], proto); | 148 if (pe == NULL) 149 return 0; 150 tgt->f_srcport = ParsePort(argv[2], pe->p_name); |
239 if (tgt->f_srcport == 0) 240 return 0; 241 argc -= 3; 242 argv += 3; 243 } 244 245 if (argc >= 3 && !strcmp(argv[0], "dst")) { 246 tgt->f_dstop = filter_Nam2Op(argv[1]); 247 if (tgt->f_dstop == OP_NONE) { | 151 if (tgt->f_srcport == 0) 152 return 0; 153 argc -= 3; 154 argv += 3; 155 } 156 157 if (argc >= 3 && !strcmp(argv[0], "dst")) { 158 tgt->f_dstop = filter_Nam2Op(argv[1]); 159 if (tgt->f_dstop == OP_NONE) { |
248 log_Printf(LogWARN, "ParseUdpOrTcp: bad operation\n"); | 160 log_Printf(LogWARN, "ParseUdpOrTcp: bad operator\n"); |
249 return 0; 250 } | 161 return 0; 162 } |
251 tgt->f_dstport = ParsePort(argv[2], proto); | 163 if (pe == NULL) 164 return 0; 165 tgt->f_dstport = ParsePort(argv[2], pe->p_name); |
252 if (tgt->f_dstport == 0) 253 return 0; 254 argc -= 3; 255 argv += 3; 256 } 257 | 166 if (tgt->f_dstport == 0) 167 return 0; 168 argc -= 3; 169 argv += 3; 170 } 171 |
258 if (proto == P_TCP) { | 172 if (pe && pe->p_proto == IPPROTO_TCP) { |
259 for (; argc > 0; argc--, argv++) 260 if (!strcmp(*argv, "estab")) 261 tgt->f_estab = 1; 262 else if (!strcmp(*argv, "syn")) 263 tgt->f_syn = 1; 264 else if (!strcmp(*argv, "finrst")) 265 tgt->f_finrst = 1; 266 else --- 4 unchanged lines hidden (view full) --- 271 log_Printf(LogWARN, "ParseUdpOrTcp: bad src/dst port syntax: %s\n", *argv); 272 return 0; 273 } 274 275 return 1; 276} 277 278static int | 173 for (; argc > 0; argc--, argv++) 174 if (!strcmp(*argv, "estab")) 175 tgt->f_estab = 1; 176 else if (!strcmp(*argv, "syn")) 177 tgt->f_syn = 1; 178 else if (!strcmp(*argv, "finrst")) 179 tgt->f_finrst = 1; 180 else --- 4 unchanged lines hidden (view full) --- 185 log_Printf(LogWARN, "ParseUdpOrTcp: bad src/dst port syntax: %s\n", *argv); 186 return 0; 187 } 188 189 return 1; 190} 191 192static int |
279ParseIgmp(int argc, char const * const *argv, struct filterent *tgt) | 193ParseGeneric(int argc, char const * const *argv, const struct protoent *pe, 194 struct filterent *tgt) |
280{ 281 /* 282 * Filter currently is a catch-all. Requests are either permitted or 283 * dropped. 284 */ 285 if (argc != 0) { | 195{ 196 /* 197 * Filter currently is a catch-all. Requests are either permitted or 198 * dropped. 199 */ 200 if (argc != 0) { |
286 log_Printf(LogWARN, "ParseIgmp: Too many parameters\n"); | 201 log_Printf(LogWARN, "ParseGeneric: Too many parameters\n"); |
287 return 0; 288 } else | 202 return 0; 203 } else |
289 tgt->f_srcop = OP_NONE; | 204 tgt->f_srcop = tgt->f_dstop = OP_NONE; |
290 291 return 1; 292} 293 | 205 206 return 1; 207} 208 |
294#ifdef P_GRE 295static int 296ParseGRE(int argc, char const * const *argv, struct filterent *tgt) 297{ 298 /* 299 * Filter currently is a catch-all. Requests are either permitted or 300 * dropped. 301 */ 302 if (argc != 0) { 303 log_Printf(LogWARN, "ParseGRE: Too many parameters\n"); 304 return 0; 305 } else 306 tgt->f_srcop = OP_NONE; 307 308 return 1; 309} 310#endif 311 312#ifdef P_OSPF 313static int 314ParseOspf(int argc, char const * const *argv, struct filterent *tgt) 315{ 316 /* 317 * Filter currently is a catch-all. Requests are either permitted or 318 * dropped. 319 */ 320 if (argc != 0) { 321 log_Printf(LogWARN, "ParseOspf: Too many parameters\n"); 322 return 0; 323 } else 324 tgt->f_srcop = OP_NONE; 325 326 return 1; 327} 328#endif 329 | |
330static unsigned 331addrtype(const char *addr) 332{ 333 if (!strncasecmp(addr, "MYADDR", 6) && (addr[6] == '\0' || addr[6] == '/')) 334 return T_MYADDR; | 209static unsigned 210addrtype(const char *addr) 211{ 212 if (!strncasecmp(addr, "MYADDR", 6) && (addr[6] == '\0' || addr[6] == '/')) 213 return T_MYADDR; |
214 if (!strncasecmp(addr, "MYADDR6", 7) && (addr[7] == '\0' || addr[7] == '/')) 215 return T_MYADDR6; |
|
335 if (!strncasecmp(addr, "HISADDR", 7) && (addr[7] == '\0' || addr[7] == '/')) 336 return T_HISADDR; | 216 if (!strncasecmp(addr, "HISADDR", 7) && (addr[7] == '\0' || addr[7] == '/')) 217 return T_HISADDR; |
218 if (!strncasecmp(addr, "HISADDR6", 8) && (addr[8] == '\0' || addr[8] == '/')) 219 return T_HISADDR6; |
|
337 if (!strncasecmp(addr, "DNS0", 4) && (addr[4] == '\0' || addr[4] == '/')) 338 return T_DNS0; 339 if (!strncasecmp(addr, "DNS1", 4) && (addr[4] == '\0' || addr[4] == '/')) 340 return T_DNS1; 341 342 return T_ADDR; 343} 344 345static const char * | 220 if (!strncasecmp(addr, "DNS0", 4) && (addr[4] == '\0' || addr[4] == '/')) 221 return T_DNS0; 222 if (!strncasecmp(addr, "DNS1", 4) && (addr[4] == '\0' || addr[4] == '/')) 223 return T_DNS1; 224 225 return T_ADDR; 226} 227 228static const char * |
346addrstr(struct in_addr addr, unsigned type) | 229addrstr(struct ncprange *addr, unsigned type) |
347{ 348 switch (type) { 349 case T_MYADDR: 350 return "MYADDR"; 351 case T_HISADDR: 352 return "HISADDR"; 353 case T_DNS0: 354 return "DNS0"; 355 case T_DNS1: 356 return "DNS1"; 357 } | 230{ 231 switch (type) { 232 case T_MYADDR: 233 return "MYADDR"; 234 case T_HISADDR: 235 return "HISADDR"; 236 case T_DNS0: 237 return "DNS0"; 238 case T_DNS1: 239 return "DNS1"; 240 } |
358 return inet_ntoa(addr); | 241 return ncprange_ntoa(addr); |
359} 360 | 242} 243 |
361static const char * 362maskstr(int bits) 363{ 364 static char str[4]; 365 366 if (bits == 32) 367 *str = '\0'; 368 else 369 snprintf(str, sizeof str, "/%d", bits); 370 371 return str; 372} 373 | |
374static int | 244static int |
375Parse(struct ipcp *ipcp, int argc, char const *const *argv, 376 struct filterent *ofp) | 245filter_Parse(struct ncp *ncp, int argc, char const *const *argv, 246 struct filterent *ofp) |
377{ | 247{ |
378 int action, proto; 379 int val, ruleno; | 248 struct filterent fe; 249 struct protoent *pe; |
380 char *wp; | 250 char *wp; |
381 struct filterent filterdata; | 251 int action, family, ruleno, val, width; |
382 383 ruleno = strtol(*argv, &wp, 0); 384 if (*argv == wp || ruleno >= MAXFILTERS) { 385 log_Printf(LogWARN, "Parse: invalid filter number.\n"); 386 return 0; 387 } 388 if (ruleno < 0) { 389 for (ruleno = 0; ruleno < MAXFILTERS; ruleno++) { --- 6 unchanged lines hidden (view full) --- 396 ofp += ruleno; 397 398 if (--argc == 0) { 399 log_Printf(LogWARN, "Parse: missing action.\n"); 400 return 0; 401 } 402 argv++; 403 | 252 253 ruleno = strtol(*argv, &wp, 0); 254 if (*argv == wp || ruleno >= MAXFILTERS) { 255 log_Printf(LogWARN, "Parse: invalid filter number.\n"); 256 return 0; 257 } 258 if (ruleno < 0) { 259 for (ruleno = 0; ruleno < MAXFILTERS; ruleno++) { --- 6 unchanged lines hidden (view full) --- 266 ofp += ruleno; 267 268 if (--argc == 0) { 269 log_Printf(LogWARN, "Parse: missing action.\n"); 270 return 0; 271 } 272 argv++; 273 |
404 proto = P_NONE; 405 memset(&filterdata, '\0', sizeof filterdata); | 274 memset(&fe, '\0', sizeof fe); |
406 407 val = strtol(*argv, &wp, 0); 408 if (!*wp && val >= 0 && val < MAXFILTERS) { 409 if (val <= ruleno) { 410 log_Printf(LogWARN, "Parse: Can only jump forward from rule %d\n", 411 ruleno); 412 return 0; 413 } 414 action = val; 415 } else if (!strcmp(*argv, "permit")) { 416 action = A_PERMIT; 417 } else if (!strcmp(*argv, "deny")) { 418 action = A_DENY; 419 } else if (!strcmp(*argv, "clear")) { 420 ofp->f_action = A_NONE; 421 return 1; 422 } else { | 275 276 val = strtol(*argv, &wp, 0); 277 if (!*wp && val >= 0 && val < MAXFILTERS) { 278 if (val <= ruleno) { 279 log_Printf(LogWARN, "Parse: Can only jump forward from rule %d\n", 280 ruleno); 281 return 0; 282 } 283 action = val; 284 } else if (!strcmp(*argv, "permit")) { 285 action = A_PERMIT; 286 } else if (!strcmp(*argv, "deny")) { 287 action = A_DENY; 288 } else if (!strcmp(*argv, "clear")) { 289 ofp->f_action = A_NONE; 290 return 1; 291 } else { |
423 log_Printf(LogWARN, "Parse: bad action: %s\n", *argv); | 292 log_Printf(LogWARN, "Parse: %s: bad action\n", *argv); |
424 return 0; 425 } | 293 return 0; 294 } |
426 filterdata.f_action = action; | 295 fe.f_action = action; |
427 428 argc--; 429 argv++; 430 431 if (argc && argv[0][0] == '!' && !argv[0][1]) { | 296 297 argc--; 298 argv++; 299 300 if (argc && argv[0][0] == '!' && !argv[0][1]) { |
432 filterdata.f_invert = 1; | 301 fe.f_invert = 1; |
433 argc--; 434 argv++; 435 } 436 | 302 argc--; 303 argv++; 304 } 305 |
437 proto = filter_Nam2Proto(argc, argv); 438 if (proto == P_NONE) { 439 if (!argc) 440 log_Printf(LogWARN, "Parse: address/mask is expected.\n"); 441 else if (ParseAddr(ipcp, *argv, &filterdata.f_src.ipaddr, 442 &filterdata.f_src.mask, &filterdata.f_src.width)) { 443 filterdata.f_srctype = addrtype(*argv); | 306 ncprange_init(&fe.f_src); 307 ncprange_init(&fe.f_dst); 308 309 if (argc == 0) 310 pe = NULL; 311 else if ((pe = getprotobyname(*argv)) == NULL && strcmp(*argv, "all") != 0) { 312 if (argc < 2) { 313 log_Printf(LogWARN, "Parse: Protocol or address pair expected\n"); 314 return 0; 315 } else if (strcasecmp(*argv, "any") == 0 || 316 ncprange_aton(&fe.f_src, ncp, *argv)) { 317 family = ncprange_family(&fe.f_src); 318 if (!ncprange_getwidth(&fe.f_src, &width)) 319 width = 0; 320 if (width == 0) 321 ncprange_init(&fe.f_src); 322 fe.f_srctype = addrtype(*argv); |
444 argc--; 445 argv++; | 323 argc--; 324 argv++; |
446 proto = filter_Nam2Proto(argc, argv); 447 if (!argc) 448 log_Printf(LogWARN, "Parse: address/mask is expected.\n"); 449 else if (proto == P_NONE) { 450 if (ParseAddr(ipcp, *argv, &filterdata.f_dst.ipaddr, 451 &filterdata.f_dst.mask, &filterdata.f_dst.width)) { 452 filterdata.f_dsttype = addrtype(*argv); 453 argc--; 454 argv++; 455 } else 456 filterdata.f_dsttype = T_ADDR; 457 if (argc) { 458 proto = filter_Nam2Proto(argc, argv); 459 if (proto == P_NONE) { 460 log_Printf(LogWARN, "Parse: %s: Invalid protocol\n", *argv); 461 return 0; 462 } else { 463 argc--; 464 argv++; 465 } 466 } | 325 326 if (strcasecmp(*argv, "any") == 0 || 327 ncprange_aton(&fe.f_dst, ncp, *argv)) { 328 if (ncprange_family(&fe.f_dst) != AF_UNSPEC && 329 ncprange_family(&fe.f_src) != AF_UNSPEC && 330 family != ncprange_family(&fe.f_dst)) { 331 log_Printf(LogWARN, "Parse: src and dst address families differ\n"); 332 return 0; 333 } 334 if (!ncprange_getwidth(&fe.f_dst, &width)) 335 width = 0; 336 if (width == 0) 337 ncprange_init(&fe.f_dst); 338 fe.f_dsttype = addrtype(*argv); 339 argc--; 340 argv++; |
467 } else { | 341 } else { |
468 argc--; 469 argv++; | 342 log_Printf(LogWARN, "Parse: Protocol or address pair expected\n"); 343 return 0; |
470 } | 344 } |
345 346 if (argc) { 347 if ((pe = getprotobyname(*argv)) == NULL && strcmp(*argv, "all") != 0) { 348 log_Printf(LogWARN, "Parse: %s: Protocol expected\n", *argv); 349 return 0; 350 } else { 351 argc--; 352 argv++; 353 } 354 } |
|
471 } else { | 355 } else { |
472 log_Printf(LogWARN, "Parse: Address/protocol expected.\n"); | 356 log_Printf(LogWARN, "Parse: Protocol or address pair expected\n"); |
473 return 0; 474 } 475 } else { 476 argc--; 477 argv++; 478 } 479 | 357 return 0; 358 } 359 } else { 360 argc--; 361 argv++; 362 } 363 |
480 if (argc >= 2 && strcmp(argv[argc - 2], "timeout") == 0) { 481 filterdata.timeout = strtoul(argv[argc - 1], NULL, 10); | 364 if (argc >= 2 && strcmp(*argv, "timeout") == 0) { 365 fe.timeout = strtoul(argv[1], NULL, 10); |
482 argc -= 2; | 366 argc -= 2; |
367 argv += 2; |
|
483 } 484 485 val = 1; | 368 } 369 370 val = 1; |
486 filterdata.f_proto = proto; | 371 fe.f_proto = (pe == NULL) ? 0 : pe->p_proto; |
487 | 372 |
488 switch (proto) { 489 case P_TCP: 490 val = ParseUdpOrTcp(argc, argv, P_TCP, &filterdata); 491 break; 492 case P_UDP: 493 val = ParseUdpOrTcp(argc, argv, P_UDP, &filterdata); 494 break; 495 case P_IPIP: 496 val = ParseUdpOrTcp(argc, argv, P_IPIP, &filterdata); 497 break; 498 case P_ICMP: 499 val = ParseIcmp(argc, argv, &filterdata); 500 break; 501 case P_IGMP: 502 val = ParseIgmp(argc, argv, &filterdata); 503 break; 504#ifdef P_OSPF 505 case P_OSPF: 506 val = ParseOspf(argc, argv, &filterdata); 507 break; | 373 switch (fe.f_proto) { 374 case IPPROTO_TCP: 375 case IPPROTO_UDP: 376 case IPPROTO_IPIP: 377#ifndef NOINET6 378 case IPPROTO_IPV6: |
508#endif | 379#endif |
509#ifdef P_GRE 510 case P_GRE: 511 val = ParseGRE(argc, argv, &filterdata); | 380 val = ParseUdpOrTcp(argc, argv, pe, &fe); |
512 break; | 381 break; |
382 case IPPROTO_ICMP: 383#ifndef NOINET6 384 case IPPROTO_ICMPV6: |
|
513#endif | 385#endif |
386 val = ParseIcmp(argc, argv, pe, &fe); 387 break; 388 default: 389 val = ParseGeneric(argc, argv, pe, &fe); 390 break; |
|
514 } 515 | 391 } 392 |
516 log_Printf(LogDEBUG, "Parse: Src: %s\n", inet_ntoa(filterdata.f_src.ipaddr)); 517 log_Printf(LogDEBUG, "Parse: Src mask: %s\n", 518 inet_ntoa(filterdata.f_src.mask)); 519 log_Printf(LogDEBUG, "Parse: Dst: %s\n", inet_ntoa(filterdata.f_dst.ipaddr)); 520 log_Printf(LogDEBUG, "Parse: Dst mask: %s\n", 521 inet_ntoa(filterdata.f_dst.mask)); 522 log_Printf(LogDEBUG, "Parse: Proto = %d\n", proto); | 393 log_Printf(LogDEBUG, "Parse: Src: %s\n", ncprange_ntoa(&fe.f_src)); 394 log_Printf(LogDEBUG, "Parse: Dst: %s\n", ncprange_ntoa(&fe.f_dst)); 395 log_Printf(LogDEBUG, "Parse: Proto: %d\n", fe.f_proto); |
523 524 log_Printf(LogDEBUG, "Parse: src: %s (%d)\n", | 396 397 log_Printf(LogDEBUG, "Parse: src: %s (%d)\n", |
525 filter_Op2Nam(filterdata.f_srcop), filterdata.f_srcport); | 398 filter_Op2Nam(fe.f_srcop), fe.f_srcport); |
526 log_Printf(LogDEBUG, "Parse: dst: %s (%d)\n", | 399 log_Printf(LogDEBUG, "Parse: dst: %s (%d)\n", |
527 filter_Op2Nam(filterdata.f_dstop), filterdata.f_dstport); 528 log_Printf(LogDEBUG, "Parse: estab: %u\n", filterdata.f_estab); 529 log_Printf(LogDEBUG, "Parse: syn: %u\n", filterdata.f_syn); 530 log_Printf(LogDEBUG, "Parse: finrst: %u\n", filterdata.f_finrst); | 400 filter_Op2Nam(fe.f_dstop), fe.f_dstport); 401 log_Printf(LogDEBUG, "Parse: estab: %u\n", fe.f_estab); 402 log_Printf(LogDEBUG, "Parse: syn: %u\n", fe.f_syn); 403 log_Printf(LogDEBUG, "Parse: finrst: %u\n", fe.f_finrst); |
531 532 if (val) | 404 405 if (val) |
533 *ofp = filterdata; | 406 *ofp = fe; |
534 535 return val; 536} 537 538int 539filter_Set(struct cmdargs const *arg) 540{ 541 struct filter *filter; --- 10 unchanged lines hidden (view full) --- 552 else if (!strcmp(arg->argv[arg->argn], "alive")) 553 filter = &arg->bundle->filter.alive; 554 else { 555 log_Printf(LogWARN, "filter_Set: %s: Invalid filter name.\n", 556 arg->argv[arg->argn]); 557 return -1; 558 } 559 | 407 408 return val; 409} 410 411int 412filter_Set(struct cmdargs const *arg) 413{ 414 struct filter *filter; --- 10 unchanged lines hidden (view full) --- 425 else if (!strcmp(arg->argv[arg->argn], "alive")) 426 filter = &arg->bundle->filter.alive; 427 else { 428 log_Printf(LogWARN, "filter_Set: %s: Invalid filter name.\n", 429 arg->argv[arg->argn]); 430 return -1; 431 } 432 |
560 Parse(&arg->bundle->ncp.ipcp, arg->argc - arg->argn - 1, | 433 filter_Parse(&arg->bundle->ncp, arg->argc - arg->argn - 1, |
561 arg->argv + arg->argn + 1, filter->rule); 562 return 0; 563} 564 565const char * 566filter_Action2Nam(int act) 567{ 568 static const char * const actname[] = { " none ", "permit ", " deny " }; --- 6 unchanged lines hidden (view full) --- 575 return actname[act - A_NONE]; 576 else 577 return "?????? "; 578} 579 580static void 581doShowFilter(struct filterent *fp, struct prompt *prompt) 582{ | 434 arg->argv + arg->argn + 1, filter->rule); 435 return 0; 436} 437 438const char * 439filter_Action2Nam(int act) 440{ 441 static const char * const actname[] = { " none ", "permit ", " deny " }; --- 6 unchanged lines hidden (view full) --- 448 return actname[act - A_NONE]; 449 else 450 return "?????? "; 451} 452 453static void 454doShowFilter(struct filterent *fp, struct prompt *prompt) 455{ |
456 struct protoent *pe; |
|
583 int n; 584 585 for (n = 0; n < MAXFILTERS; n++, fp++) { 586 if (fp->f_action != A_NONE) { 587 prompt_Printf(prompt, " %2d %s", n, filter_Action2Nam(fp->f_action)); 588 prompt_Printf(prompt, "%c ", fp->f_invert ? '!' : ' '); | 457 int n; 458 459 for (n = 0; n < MAXFILTERS; n++, fp++) { 460 if (fp->f_action != A_NONE) { 461 prompt_Printf(prompt, " %2d %s", n, filter_Action2Nam(fp->f_action)); 462 prompt_Printf(prompt, "%c ", fp->f_invert ? '!' : ' '); |
589 prompt_Printf(prompt, "%s%s ", addrstr(fp->f_src.ipaddr, fp->f_srctype), 590 maskstr(fp->f_src.width)); 591 prompt_Printf(prompt, "%s%s ", addrstr(fp->f_dst.ipaddr, fp->f_dsttype), 592 maskstr(fp->f_dst.width)); | 463 464 if (ncprange_isset(&fp->f_src)) 465 prompt_Printf(prompt, "%s ", addrstr(&fp->f_src, fp->f_srctype)); 466 else 467 prompt_Printf(prompt, "any "); 468 469 if (ncprange_isset(&fp->f_dst)) 470 prompt_Printf(prompt, "%s ", addrstr(&fp->f_dst, fp->f_dsttype)); 471 else 472 prompt_Printf(prompt, "any "); 473 |
593 if (fp->f_proto) { | 474 if (fp->f_proto) { |
594 prompt_Printf(prompt, "%s", filter_Proto2Nam(fp->f_proto)); | 475 if ((pe = getprotobynumber(fp->f_proto)) == NULL) 476 prompt_Printf(prompt, "P:%d", fp->f_proto); 477 else 478 prompt_Printf(prompt, "%s", pe->p_name); |
595 596 if (fp->f_srcop) 597 prompt_Printf(prompt, " src %s %d", filter_Op2Nam(fp->f_srcop), 598 fp->f_srcport); 599 if (fp->f_dstop) 600 prompt_Printf(prompt, " dst %s %d", filter_Op2Nam(fp->f_dstop), 601 fp->f_dstport); 602 if (fp->f_estab) 603 prompt_Printf(prompt, " estab"); 604 if (fp->f_syn) 605 prompt_Printf(prompt, " syn"); 606 if (fp->f_finrst) 607 prompt_Printf(prompt, " finrst"); | 479 480 if (fp->f_srcop) 481 prompt_Printf(prompt, " src %s %d", filter_Op2Nam(fp->f_srcop), 482 fp->f_srcport); 483 if (fp->f_dstop) 484 prompt_Printf(prompt, " dst %s %d", filter_Op2Nam(fp->f_dstop), 485 fp->f_dstport); 486 if (fp->f_estab) 487 prompt_Printf(prompt, " estab"); 488 if (fp->f_syn) 489 prompt_Printf(prompt, " syn"); 490 if (fp->f_finrst) 491 prompt_Printf(prompt, " finrst"); |
608 } | 492 } else 493 prompt_Printf(prompt, "all"); |
609 if (fp->timeout != 0) 610 prompt_Printf(prompt, " timeout %u", fp->timeout); 611 prompt_Printf(prompt, "\n"); 612 } 613 } 614} 615 616int --- 30 unchanged lines hidden (view full) --- 647 prompt_Printf(arg->prompt, "%s:\n", filter[f]->name); 648 doShowFilter(filter[f]->rule, arg->prompt); 649 } 650 } 651 652 return 0; 653} 654 | 494 if (fp->timeout != 0) 495 prompt_Printf(prompt, " timeout %u", fp->timeout); 496 prompt_Printf(prompt, "\n"); 497 } 498 } 499} 500 501int --- 30 unchanged lines hidden (view full) --- 532 prompt_Printf(arg->prompt, "%s:\n", filter[f]->name); 533 doShowFilter(filter[f]->rule, arg->prompt); 534 } 535 } 536 537 return 0; 538} 539 |
655static const char * const protoname[] = { 656 "none", "tcp", "udp", "icmp", "ospf", "igmp", "gre", "ipip" 657}; 658 659const char * 660filter_Proto2Nam(int proto) 661{ 662 if (proto >= sizeof protoname / sizeof protoname[0]) 663 return "unknown"; 664 return protoname[proto]; 665} 666 667static int 668filter_Nam2Proto(int argc, char const *const *argv) 669{ 670 int proto; 671 672 if (argc == 0) 673 proto = 0; 674 else 675 for (proto = sizeof protoname / sizeof protoname[0] - 1; proto; proto--) 676 if (!strcasecmp(*argv, protoname[proto])) 677 break; 678 679 return proto; 680} 681 | |
682static const char * const opname[] = {"none", "eq", "gt", "lt"}; 683 684const char * 685filter_Op2Nam(int op) 686{ 687 if (op >= sizeof opname / sizeof opname[0]) 688 return "unknown"; 689 return opname[op]; --- 8 unchanged lines hidden (view full) --- 698 for (op = sizeof opname / sizeof opname[0] - 1; op; op--) 699 if (!strcasecmp(cp, opname[op])) 700 break; 701 702 return op; 703} 704 705void | 540static const char * const opname[] = {"none", "eq", "gt", "lt"}; 541 542const char * 543filter_Op2Nam(int op) 544{ 545 if (op >= sizeof opname / sizeof opname[0]) 546 return "unknown"; 547 return opname[op]; --- 8 unchanged lines hidden (view full) --- 556 for (op = sizeof opname / sizeof opname[0] - 1; op; op--) 557 if (!strcasecmp(cp, opname[op])) 558 break; 559 560 return op; 561} 562 563void |
706filter_AdjustAddr(struct filter *filter, struct in_addr *my_ip, 707 struct in_addr *peer_ip, struct in_addr dns[2]) | 564filter_AdjustAddr(struct filter *filter, struct ncpaddr *local, 565 struct ncpaddr *remote, struct in_addr *dns) |
708{ 709 struct filterent *fp; 710 int n; 711 712 for (fp = filter->rule, n = 0; n < MAXFILTERS; fp++, n++) 713 if (fp->f_action != A_NONE) { | 566{ 567 struct filterent *fp; 568 int n; 569 570 for (fp = filter->rule, n = 0; n < MAXFILTERS; fp++, n++) 571 if (fp->f_action != A_NONE) { |
714 if (my_ip) { 715 if (fp->f_srctype == T_MYADDR) 716 fp->f_src.ipaddr = *my_ip; 717 if (fp->f_dsttype == T_MYADDR) 718 fp->f_dst.ipaddr = *my_ip; | 572 if (local) { 573 if (fp->f_srctype == T_MYADDR && ncpaddr_family(local) == AF_INET) 574 ncprange_sethost(&fp->f_src, local); 575 if (fp->f_dsttype == T_MYADDR && ncpaddr_family(local) == AF_INET) 576 ncprange_sethost(&fp->f_dst, local); 577#ifndef NOINET6 578 if (fp->f_srctype == T_MYADDR6 && ncpaddr_family(local) == AF_INET6) 579 ncprange_sethost(&fp->f_src, local); 580 if (fp->f_dsttype == T_MYADDR6 && ncpaddr_family(local) == AF_INET6) 581 ncprange_sethost(&fp->f_dst, local); 582#endif |
719 } | 583 } |
720 if (peer_ip) { 721 if (fp->f_srctype == T_HISADDR) 722 fp->f_src.ipaddr = *peer_ip; 723 if (fp->f_dsttype == T_HISADDR) 724 fp->f_dst.ipaddr = *peer_ip; | 584 if (remote) { 585 if (fp->f_srctype == T_HISADDR && ncpaddr_family(remote) == AF_INET) 586 ncprange_sethost(&fp->f_src, remote); 587 if (fp->f_dsttype == T_HISADDR && ncpaddr_family(remote) == AF_INET) 588 ncprange_sethost(&fp->f_dst, remote); 589#ifndef NOINET6 590 if (fp->f_srctype == T_HISADDR6 && ncpaddr_family(remote) == AF_INET6) 591 ncprange_sethost(&fp->f_src, remote); 592 if (fp->f_dsttype == T_HISADDR6 && ncpaddr_family(remote) == AF_INET6) 593 ncprange_sethost(&fp->f_dst, remote); 594#endif |
725 } 726 if (dns) { 727 if (fp->f_srctype == T_DNS0) | 595 } 596 if (dns) { 597 if (fp->f_srctype == T_DNS0) |
728 fp->f_src.ipaddr = dns[0]; | 598 ncprange_setip4host(&fp->f_src, dns[0]); |
729 if (fp->f_dsttype == T_DNS0) | 599 if (fp->f_dsttype == T_DNS0) |
730 fp->f_dst.ipaddr = dns[0]; | 600 ncprange_setip4host(&fp->f_dst, dns[0]); |
731 if (fp->f_srctype == T_DNS1) | 601 if (fp->f_srctype == T_DNS1) |
732 fp->f_src.ipaddr = dns[1]; | 602 ncprange_setip4host(&fp->f_src, dns[1]); |
733 if (fp->f_dsttype == T_DNS1) | 603 if (fp->f_dsttype == T_DNS1) |
734 fp->f_dst.ipaddr = dns[1]; | 604 ncprange_setip4host(&fp->f_dst, dns[1]); |
735 } 736 } 737} | 605 } 606 } 607} |