178189Sbrian/*- 278189Sbrian * Copyright (c) 1996 - 2001 Brian Somers <brian@Awfulhak.org> 378189Sbrian * based on work by Toshiharu OHNO <tony-o@iij.ad.jp> 478189Sbrian * Internet Initiative Japan, Inc (IIJ) 578189Sbrian * All rights reserved. 66059Samurai * 778189Sbrian * Redistribution and use in source and binary forms, with or without 878189Sbrian * modification, are permitted provided that the following conditions 978189Sbrian * are met: 1078189Sbrian * 1. Redistributions of source code must retain the above copyright 1178189Sbrian * notice, this list of conditions and the following disclaimer. 1278189Sbrian * 2. Redistributions in binary form must reproduce the above copyright 1378189Sbrian * notice, this list of conditions and the following disclaimer in the 1478189Sbrian * documentation and/or other materials provided with the distribution. 156059Samurai * 1678189Sbrian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1778189Sbrian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1878189Sbrian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1978189Sbrian * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2078189Sbrian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2178189Sbrian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2278189Sbrian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2378189Sbrian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2478189Sbrian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2578189Sbrian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2678189Sbrian * SUCH DAMAGE. 276059Samurai * 2850479Speter * $FreeBSD$ 296059Samurai */ 306059Samurai 3143313Sbrian#include <sys/param.h> 326059Samurai#include <netinet/in.h> 3310858Samurai#include <netdb.h> 3436285Sbrian#include <netinet/in_systm.h> 3536285Sbrian#include <netinet/ip.h> 3681634Sbrian#include <sys/socket.h> 3736285Sbrian#include <sys/un.h> 3830715Sbrian 39102500Sbrian#include <stdarg.h> 406059Samurai#include <stdio.h> 416059Samurai#include <stdlib.h> 4296582Sbrian#include <string.h> 4336285Sbrian#include <termios.h> 4430715Sbrian 4546686Sbrian#include "layer.h" 4637009Sbrian#include "defs.h" 476059Samurai#include "command.h" 4826516Sbrian#include "mbuf.h" 4926516Sbrian#include "log.h" 5036285Sbrian#include "iplist.h" 5136285Sbrian#include "timer.h" 5236285Sbrian#include "throughput.h" 5336285Sbrian#include "lqr.h" 5436285Sbrian#include "hdlc.h" 5536285Sbrian#include "fsm.h" 5636285Sbrian#include "lcp.h" 5736285Sbrian#include "ccp.h" 5836285Sbrian#include "link.h" 5936285Sbrian#include "slcompress.h" 6081634Sbrian#include "ncpaddr.h" 6127011Sbrian#include "ipcp.h" 6230715Sbrian#include "filter.h" 6336285Sbrian#include "descriptor.h" 6436285Sbrian#include "prompt.h" 6536285Sbrian#include "mp.h" 6643313Sbrian#ifndef NORADIUS 6743313Sbrian#include "radius.h" 6843313Sbrian#endif 6981634Sbrian#include "ipv6cp.h" 7081634Sbrian#include "ncp.h" 7136285Sbrian#include "bundle.h" 726059Samurai 73134789Sbrianstatic unsigned filter_Nam2Op(const char *); 7430715Sbrian 756059Samuraistatic int 7681634SbrianParsePort(const char *service, const char *proto) 7710858Samurai{ 7881634Sbrian struct servent *servent; 7931343Sbrian char *cp; 8010858Samurai int port; 8110858Samurai 8281634Sbrian servent = getservbyname(service, proto); 8310858Samurai if (servent != 0) 8449140Sbrian return ntohs(servent->s_port); 8510858Samurai 8610858Samurai port = strtol(service, &cp, 0); 8710858Samurai if (cp == service) { 8836285Sbrian log_Printf(LogWARN, "ParsePort: %s is not a port name or number.\n", 8928679Sbrian service); 9049140Sbrian return 0; 9110858Samurai } 9249140Sbrian return port; 9310858Samurai} 9410858Samurai 956059Samurai/* 966059Samurai * ICMP Syntax: src eq icmp_message_type 976059Samurai */ 986059Samuraistatic int 99134789SbrianParseIcmp(int argc, char const *const *argv, struct filterent *tgt) 1006059Samurai{ 1016059Samurai int type; 1026059Samurai char *cp; 1036059Samurai 1046059Samurai switch (argc) { 1056059Samurai case 0: 1066059Samurai /* permit/deny all ICMP types */ 10781634Sbrian tgt->f_srcop = tgt->f_dstop = OP_NONE; 1086059Samurai break; 10936285Sbrian 1106059Samurai case 3: 11130715Sbrian if (!strcmp(*argv, "src") && !strcmp(argv[1], "eq")) { 1126059Samurai type = strtol(argv[2], &cp, 0); 1136059Samurai if (cp == argv[2]) { 11436285Sbrian log_Printf(LogWARN, "ParseIcmp: type is expected.\n"); 11549140Sbrian return 0; 1166059Samurai } 11749140Sbrian tgt->f_srcop = OP_EQ; 11849140Sbrian tgt->f_srcport = type; 11981634Sbrian tgt->f_dstop = OP_NONE; 1206059Samurai } 1216059Samurai break; 12236285Sbrian 12336285Sbrian default: 12436285Sbrian log_Printf(LogWARN, "ParseIcmp: bad icmp syntax.\n"); 12549140Sbrian return 0; 1266059Samurai } 12749140Sbrian return 1; 1286059Samurai} 1296059Samurai 1306059Samurai/* 1316059Samurai * UDP Syntax: [src op port] [dst op port] 1326059Samurai */ 1336059Samuraistatic int 13481634SbrianParseUdpOrTcp(int argc, char const *const *argv, const struct protoent *pe, 13536285Sbrian struct filterent *tgt) 1366059Samurai{ 13749140Sbrian tgt->f_srcop = tgt->f_dstop = OP_NONE; 13849140Sbrian tgt->f_estab = tgt->f_syn = tgt->f_finrst = 0; 13930669Sbrian 14030715Sbrian if (argc >= 3 && !strcmp(*argv, "src")) { 14149140Sbrian tgt->f_srcop = filter_Nam2Op(argv[1]); 14249140Sbrian if (tgt->f_srcop == OP_NONE) { 14381634Sbrian log_Printf(LogWARN, "ParseUdpOrTcp: bad operator\n"); 14449140Sbrian return 0; 1456059Samurai } 14681634Sbrian if (pe == NULL) 14781634Sbrian return 0; 14881634Sbrian tgt->f_srcport = ParsePort(argv[2], pe->p_name); 14949140Sbrian if (tgt->f_srcport == 0) 15049140Sbrian return 0; 15128679Sbrian argc -= 3; 15228679Sbrian argv += 3; 1536059Samurai } 15436285Sbrian 15530715Sbrian if (argc >= 3 && !strcmp(argv[0], "dst")) { 15649140Sbrian tgt->f_dstop = filter_Nam2Op(argv[1]); 15749140Sbrian if (tgt->f_dstop == OP_NONE) { 15881634Sbrian log_Printf(LogWARN, "ParseUdpOrTcp: bad operator\n"); 15949140Sbrian return 0; 1606059Samurai } 16181634Sbrian if (pe == NULL) 16281634Sbrian return 0; 16381634Sbrian tgt->f_dstport = ParsePort(argv[2], pe->p_name); 16449140Sbrian if (tgt->f_dstport == 0) 16549140Sbrian return 0; 16628679Sbrian argc -= 3; 16728679Sbrian argv += 3; 16810858Samurai } 16936285Sbrian 17081634Sbrian if (pe && pe->p_proto == IPPROTO_TCP) { 17136285Sbrian for (; argc > 0; argc--, argv++) 17236285Sbrian if (!strcmp(*argv, "estab")) 17349140Sbrian tgt->f_estab = 1; 17436285Sbrian else if (!strcmp(*argv, "syn")) 17549140Sbrian tgt->f_syn = 1; 17636285Sbrian else if (!strcmp(*argv, "finrst")) 17749140Sbrian tgt->f_finrst = 1; 17836285Sbrian else 17936285Sbrian break; 1806059Samurai } 18136285Sbrian 18236285Sbrian if (argc > 0) { 18336285Sbrian log_Printf(LogWARN, "ParseUdpOrTcp: bad src/dst port syntax: %s\n", *argv); 18436285Sbrian return 0; 18536285Sbrian } 18636285Sbrian 18736285Sbrian return 1; 1886059Samurai} 1896059Samurai 19049372Sbrianstatic int 191134789SbrianParseGeneric(int argc, struct filterent *tgt) 19249140Sbrian{ 19349372Sbrian /* 19449372Sbrian * Filter currently is a catch-all. Requests are either permitted or 19549372Sbrian * dropped. 19649372Sbrian */ 19748142Sbrian if (argc != 0) { 19881634Sbrian log_Printf(LogWARN, "ParseGeneric: Too many parameters\n"); 19948142Sbrian return 0; 20048142Sbrian } else 20181634Sbrian tgt->f_srcop = tgt->f_dstop = OP_NONE; 20248142Sbrian 20348142Sbrian return 1; 20448142Sbrian} 20548142Sbrian 20647648Sbrianstatic unsigned 20747648Sbrianaddrtype(const char *addr) 20847648Sbrian{ 20947648Sbrian if (!strncasecmp(addr, "MYADDR", 6) && (addr[6] == '\0' || addr[6] == '/')) 21047648Sbrian return T_MYADDR; 21181634Sbrian if (!strncasecmp(addr, "MYADDR6", 7) && (addr[7] == '\0' || addr[7] == '/')) 21281634Sbrian return T_MYADDR6; 21347648Sbrian if (!strncasecmp(addr, "HISADDR", 7) && (addr[7] == '\0' || addr[7] == '/')) 21447648Sbrian return T_HISADDR; 21581634Sbrian if (!strncasecmp(addr, "HISADDR6", 8) && (addr[8] == '\0' || addr[8] == '/')) 21681634Sbrian return T_HISADDR6; 21758044Sbrian if (!strncasecmp(addr, "DNS0", 4) && (addr[4] == '\0' || addr[4] == '/')) 21858044Sbrian return T_DNS0; 21958044Sbrian if (!strncasecmp(addr, "DNS1", 4) && (addr[4] == '\0' || addr[4] == '/')) 22058044Sbrian return T_DNS1; 22147648Sbrian 22247648Sbrian return T_ADDR; 22347648Sbrian} 22447648Sbrian 22547648Sbrianstatic const char * 22681634Sbrianaddrstr(struct ncprange *addr, unsigned type) 22747648Sbrian{ 22847648Sbrian switch (type) { 22947648Sbrian case T_MYADDR: 23047648Sbrian return "MYADDR"; 23147648Sbrian case T_HISADDR: 23247648Sbrian return "HISADDR"; 23358044Sbrian case T_DNS0: 23458044Sbrian return "DNS0"; 23558044Sbrian case T_DNS1: 23658044Sbrian return "DNS1"; 23747648Sbrian } 23881634Sbrian return ncprange_ntoa(addr); 23947648Sbrian} 24047648Sbrian 2416059Samuraistatic int 24281634Sbrianfilter_Parse(struct ncp *ncp, int argc, char const *const *argv, 24381634Sbrian struct filterent *ofp) 2446059Samurai{ 24581634Sbrian struct filterent fe; 24681634Sbrian struct protoent *pe; 2476059Samurai char *wp; 24881634Sbrian int action, family, ruleno, val, width; 2496059Samurai 25049140Sbrian ruleno = strtol(*argv, &wp, 0); 25149140Sbrian if (*argv == wp || ruleno >= MAXFILTERS) { 25236285Sbrian log_Printf(LogWARN, "Parse: invalid filter number.\n"); 25349140Sbrian return 0; 2546059Samurai } 25549140Sbrian if (ruleno < 0) { 25649140Sbrian for (ruleno = 0; ruleno < MAXFILTERS; ruleno++) { 25749140Sbrian ofp->f_action = A_NONE; 2586059Samurai ofp++; 2596059Samurai } 26036285Sbrian log_Printf(LogWARN, "Parse: filter cleared.\n"); 26149140Sbrian return 1; 2626059Samurai } 26349140Sbrian ofp += ruleno; 2646059Samurai 2656059Samurai if (--argc == 0) { 26636285Sbrian log_Printf(LogWARN, "Parse: missing action.\n"); 26749140Sbrian return 0; 2686059Samurai } 2696059Samurai argv++; 2706059Samurai 27181634Sbrian memset(&fe, '\0', sizeof fe); 2726059Samurai 27349140Sbrian val = strtol(*argv, &wp, 0); 27449140Sbrian if (!*wp && val >= 0 && val < MAXFILTERS) { 27549140Sbrian if (val <= ruleno) { 27649140Sbrian log_Printf(LogWARN, "Parse: Can only jump forward from rule %d\n", 27749140Sbrian ruleno); 27849140Sbrian return 0; 27949140Sbrian } 28049140Sbrian action = val; 28149140Sbrian } else if (!strcmp(*argv, "permit")) { 2826059Samurai action = A_PERMIT; 28330715Sbrian } else if (!strcmp(*argv, "deny")) { 2846059Samurai action = A_DENY; 28530715Sbrian } else if (!strcmp(*argv, "clear")) { 28649140Sbrian ofp->f_action = A_NONE; 28749140Sbrian return 1; 2886059Samurai } else { 28981634Sbrian log_Printf(LogWARN, "Parse: %s: bad action\n", *argv); 29049140Sbrian return 0; 2916059Samurai } 29281634Sbrian fe.f_action = action; 2936059Samurai 29428679Sbrian argc--; 29528679Sbrian argv++; 2966059Samurai 29749140Sbrian if (argc && argv[0][0] == '!' && !argv[0][1]) { 29881634Sbrian fe.f_invert = 1; 29949140Sbrian argc--; 30049140Sbrian argv++; 3016059Samurai } 30243313Sbrian 30381634Sbrian ncprange_init(&fe.f_src); 30481634Sbrian ncprange_init(&fe.f_dst); 30581634Sbrian 30681634Sbrian if (argc == 0) 30781634Sbrian pe = NULL; 30881634Sbrian else if ((pe = getprotobyname(*argv)) == NULL && strcmp(*argv, "all") != 0) { 30981634Sbrian if (argc < 2) { 31081634Sbrian log_Printf(LogWARN, "Parse: Protocol or address pair expected\n"); 31181634Sbrian return 0; 31281634Sbrian } else if (strcasecmp(*argv, "any") == 0 || 31381634Sbrian ncprange_aton(&fe.f_src, ncp, *argv)) { 31481634Sbrian family = ncprange_family(&fe.f_src); 31581634Sbrian if (!ncprange_getwidth(&fe.f_src, &width)) 31681634Sbrian width = 0; 31781634Sbrian if (width == 0) 31881634Sbrian ncprange_init(&fe.f_src); 31981634Sbrian fe.f_srctype = addrtype(*argv); 32028679Sbrian argc--; 32128679Sbrian argv++; 32281634Sbrian 32381634Sbrian if (strcasecmp(*argv, "any") == 0 || 32481634Sbrian ncprange_aton(&fe.f_dst, ncp, *argv)) { 32581634Sbrian if (ncprange_family(&fe.f_dst) != AF_UNSPEC && 32681634Sbrian ncprange_family(&fe.f_src) != AF_UNSPEC && 32781634Sbrian family != ncprange_family(&fe.f_dst)) { 32881634Sbrian log_Printf(LogWARN, "Parse: src and dst address families differ\n"); 32981634Sbrian return 0; 33081634Sbrian } 33181634Sbrian if (!ncprange_getwidth(&fe.f_dst, &width)) 33281634Sbrian width = 0; 33381634Sbrian if (width == 0) 33481634Sbrian ncprange_init(&fe.f_dst); 33581634Sbrian fe.f_dsttype = addrtype(*argv); 33681634Sbrian argc--; 33781634Sbrian argv++; 33827723Sbrian } else { 33981634Sbrian log_Printf(LogWARN, "Parse: Protocol or address pair expected\n"); 34081634Sbrian return 0; 3416059Samurai } 34281634Sbrian 34381634Sbrian if (argc) { 34481634Sbrian if ((pe = getprotobyname(*argv)) == NULL && strcmp(*argv, "all") != 0) { 34581634Sbrian log_Printf(LogWARN, "Parse: %s: Protocol expected\n", *argv); 34681634Sbrian return 0; 34781634Sbrian } else { 34881634Sbrian argc--; 34981634Sbrian argv++; 35081634Sbrian } 35181634Sbrian } 3526059Samurai } else { 35381634Sbrian log_Printf(LogWARN, "Parse: Protocol or address pair expected\n"); 35449140Sbrian return 0; 3556059Samurai } 3566059Samurai } else { 35728679Sbrian argc--; 35828679Sbrian argv++; 3596059Samurai } 3606059Samurai 36181634Sbrian if (argc >= 2 && strcmp(*argv, "timeout") == 0) { 36281634Sbrian fe.timeout = strtoul(argv[1], NULL, 10); 36362977Sbrian argc -= 2; 36481634Sbrian argv += 2; 36562977Sbrian } 36662977Sbrian 3676059Samurai val = 1; 36881634Sbrian fe.f_proto = (pe == NULL) ? 0 : pe->p_proto; 3696059Samurai 37081634Sbrian switch (fe.f_proto) { 37181634Sbrian case IPPROTO_TCP: 37281634Sbrian case IPPROTO_UDP: 37381634Sbrian case IPPROTO_IPIP: 37481634Sbrian#ifndef NOINET6 37581634Sbrian case IPPROTO_IPV6: 37681634Sbrian#endif 37781634Sbrian val = ParseUdpOrTcp(argc, argv, pe, &fe); 3786059Samurai break; 37981634Sbrian case IPPROTO_ICMP: 38081634Sbrian#ifndef NOINET6 38181634Sbrian case IPPROTO_ICMPV6: 38281634Sbrian#endif 383134789Sbrian val = ParseIcmp(argc, argv, &fe); 3846059Samurai break; 38581634Sbrian default: 386134789Sbrian val = ParseGeneric(argc, &fe); 38775894Sbrian break; 3886059Samurai } 3896059Samurai 39081634Sbrian log_Printf(LogDEBUG, "Parse: Src: %s\n", ncprange_ntoa(&fe.f_src)); 39181634Sbrian log_Printf(LogDEBUG, "Parse: Dst: %s\n", ncprange_ntoa(&fe.f_dst)); 39281634Sbrian log_Printf(LogDEBUG, "Parse: Proto: %d\n", fe.f_proto); 3936059Samurai 39436285Sbrian log_Printf(LogDEBUG, "Parse: src: %s (%d)\n", 39581634Sbrian filter_Op2Nam(fe.f_srcop), fe.f_srcport); 39636285Sbrian log_Printf(LogDEBUG, "Parse: dst: %s (%d)\n", 39781634Sbrian filter_Op2Nam(fe.f_dstop), fe.f_dstport); 39881634Sbrian log_Printf(LogDEBUG, "Parse: estab: %u\n", fe.f_estab); 39981634Sbrian log_Printf(LogDEBUG, "Parse: syn: %u\n", fe.f_syn); 40081634Sbrian log_Printf(LogDEBUG, "Parse: finrst: %u\n", fe.f_finrst); 4016059Samurai 4026059Samurai if (val) 40381634Sbrian *ofp = fe; 40449140Sbrian 40549140Sbrian return val; 4066059Samurai} 4076059Samurai 4086059Samuraiint 40936285Sbrianfilter_Set(struct cmdargs const *arg) 4106059Samurai{ 41136285Sbrian struct filter *filter; 4126059Samurai 41336285Sbrian if (arg->argc < arg->argn+2) 41436285Sbrian return -1; 41536285Sbrian 41636285Sbrian if (!strcmp(arg->argv[arg->argn], "in")) 41736285Sbrian filter = &arg->bundle->filter.in; 41836285Sbrian else if (!strcmp(arg->argv[arg->argn], "out")) 41936285Sbrian filter = &arg->bundle->filter.out; 42036285Sbrian else if (!strcmp(arg->argv[arg->argn], "dial")) 42136285Sbrian filter = &arg->bundle->filter.dial; 42236285Sbrian else if (!strcmp(arg->argv[arg->argn], "alive")) 42336285Sbrian filter = &arg->bundle->filter.alive; 42436285Sbrian else { 42536285Sbrian log_Printf(LogWARN, "filter_Set: %s: Invalid filter name.\n", 42636285Sbrian arg->argv[arg->argn]); 42736285Sbrian return -1; 42826516Sbrian } 4296059Samurai 43081634Sbrian filter_Parse(&arg->bundle->ncp, arg->argc - arg->argn - 1, 43136285Sbrian arg->argv + arg->argn + 1, filter->rule); 43236285Sbrian return 0; 4336059Samurai} 4346059Samurai 43536285Sbrianconst char * 436134789Sbrianfilter_Action2Nam(unsigned act) 4376735Samurai{ 43855146Sbrian static const char * const actname[] = { " none ", "permit ", " deny " }; 439134789Sbrian static char buf[8]; 44049140Sbrian 441134789Sbrian if (act < MAXFILTERS) { 44249144Sbrian snprintf(buf, sizeof buf, "%6d ", act); 44349140Sbrian return buf; 44449140Sbrian } else if (act >= A_NONE && act < A_NONE + sizeof(actname)/sizeof(char *)) 44549140Sbrian return actname[act - A_NONE]; 44649140Sbrian else 44749140Sbrian return "?????? "; 4486735Samurai} 4496735Samurai 4506059Samuraistatic void 45136285SbriandoShowFilter(struct filterent *fp, struct prompt *prompt) 4526059Samurai{ 45381634Sbrian struct protoent *pe; 4546059Samurai int n; 4556059Samurai 4566059Samurai for (n = 0; n < MAXFILTERS; n++, fp++) { 45749140Sbrian if (fp->f_action != A_NONE) { 45849140Sbrian prompt_Printf(prompt, " %2d %s", n, filter_Action2Nam(fp->f_action)); 45949140Sbrian prompt_Printf(prompt, "%c ", fp->f_invert ? '!' : ' '); 46081634Sbrian 46181634Sbrian if (ncprange_isset(&fp->f_src)) 46281634Sbrian prompt_Printf(prompt, "%s ", addrstr(&fp->f_src, fp->f_srctype)); 46381634Sbrian else 46481634Sbrian prompt_Printf(prompt, "any "); 46581634Sbrian 46681634Sbrian if (ncprange_isset(&fp->f_dst)) 46781634Sbrian prompt_Printf(prompt, "%s ", addrstr(&fp->f_dst, fp->f_dsttype)); 46881634Sbrian else 46981634Sbrian prompt_Printf(prompt, "any "); 47081634Sbrian 47149140Sbrian if (fp->f_proto) { 47281634Sbrian if ((pe = getprotobynumber(fp->f_proto)) == NULL) 47381634Sbrian prompt_Printf(prompt, "P:%d", fp->f_proto); 47481634Sbrian else 47581634Sbrian prompt_Printf(prompt, "%s", pe->p_name); 4766059Samurai 47749140Sbrian if (fp->f_srcop) 47849140Sbrian prompt_Printf(prompt, " src %s %d", filter_Op2Nam(fp->f_srcop), 47949140Sbrian fp->f_srcport); 48049140Sbrian if (fp->f_dstop) 48149140Sbrian prompt_Printf(prompt, " dst %s %d", filter_Op2Nam(fp->f_dstop), 48249140Sbrian fp->f_dstport); 48349140Sbrian if (fp->f_estab) 48436285Sbrian prompt_Printf(prompt, " estab"); 48549140Sbrian if (fp->f_syn) 48636285Sbrian prompt_Printf(prompt, " syn"); 48749140Sbrian if (fp->f_finrst) 48836285Sbrian prompt_Printf(prompt, " finrst"); 48981634Sbrian } else 49081634Sbrian prompt_Printf(prompt, "all"); 49162977Sbrian if (fp->timeout != 0) 49262977Sbrian prompt_Printf(prompt, " timeout %u", fp->timeout); 49336285Sbrian prompt_Printf(prompt, "\n"); 4946059Samurai } 4956059Samurai } 4966059Samurai} 4976059Samurai 4986059Samuraiint 49936285Sbrianfilter_Show(struct cmdargs const *arg) 5006059Samurai{ 50136285Sbrian if (arg->argc > arg->argn+1) 50236285Sbrian return -1; 50336285Sbrian 50436285Sbrian if (arg->argc == arg->argn+1) { 50536285Sbrian struct filter *filter; 50636285Sbrian 50736285Sbrian if (!strcmp(arg->argv[arg->argn], "in")) 50836285Sbrian filter = &arg->bundle->filter.in; 50936285Sbrian else if (!strcmp(arg->argv[arg->argn], "out")) 51036285Sbrian filter = &arg->bundle->filter.out; 51136285Sbrian else if (!strcmp(arg->argv[arg->argn], "dial")) 51236285Sbrian filter = &arg->bundle->filter.dial; 51336285Sbrian else if (!strcmp(arg->argv[arg->argn], "alive")) 51436285Sbrian filter = &arg->bundle->filter.alive; 51536285Sbrian else 51636285Sbrian return -1; 51736285Sbrian doShowFilter(filter->rule, arg->prompt); 51836285Sbrian } else { 51936285Sbrian struct filter *filter[4]; 52036285Sbrian int f; 52136285Sbrian 52236285Sbrian filter[0] = &arg->bundle->filter.in; 52336285Sbrian filter[1] = &arg->bundle->filter.out; 52436285Sbrian filter[2] = &arg->bundle->filter.dial; 52536285Sbrian filter[3] = &arg->bundle->filter.alive; 52636285Sbrian for (f = 0; f < 4; f++) { 52736285Sbrian if (f) 52836285Sbrian prompt_Printf(arg->prompt, "\n"); 52936285Sbrian prompt_Printf(arg->prompt, "%s:\n", filter[f]->name); 53036285Sbrian doShowFilter(filter[f]->rule, arg->prompt); 53136285Sbrian } 53236285Sbrian } 53336285Sbrian 53426516Sbrian return 0; 5356059Samurai} 5366059Samurai 53755146Sbrianstatic const char * const opname[] = {"none", "eq", "gt", "lt"}; 53836285Sbrian 53936285Sbrianconst char * 540134789Sbrianfilter_Op2Nam(unsigned op) 5416735Samurai{ 54236285Sbrian if (op >= sizeof opname / sizeof opname[0]) 54336285Sbrian return "unknown"; 54436285Sbrian return opname[op]; 54536285Sbrian 5466735Samurai} 54736285Sbrian 548134789Sbrianstatic unsigned 54936285Sbrianfilter_Nam2Op(const char *cp) 55036285Sbrian{ 551134789Sbrian unsigned op; 55236285Sbrian 55336285Sbrian for (op = sizeof opname / sizeof opname[0] - 1; op; op--) 55436285Sbrian if (!strcasecmp(cp, opname[op])) 55536285Sbrian break; 55636285Sbrian 55736285Sbrian return op; 55836285Sbrian} 55947648Sbrian 56047648Sbrianvoid 56181634Sbrianfilter_AdjustAddr(struct filter *filter, struct ncpaddr *local, 56281634Sbrian struct ncpaddr *remote, struct in_addr *dns) 56347648Sbrian{ 56447648Sbrian struct filterent *fp; 56547648Sbrian int n; 56647648Sbrian 56747648Sbrian for (fp = filter->rule, n = 0; n < MAXFILTERS; fp++, n++) 56849140Sbrian if (fp->f_action != A_NONE) { 56981634Sbrian if (local) { 57081634Sbrian if (fp->f_srctype == T_MYADDR && ncpaddr_family(local) == AF_INET) 57181634Sbrian ncprange_sethost(&fp->f_src, local); 57281634Sbrian if (fp->f_dsttype == T_MYADDR && ncpaddr_family(local) == AF_INET) 57381634Sbrian ncprange_sethost(&fp->f_dst, local); 57481634Sbrian#ifndef NOINET6 57581634Sbrian if (fp->f_srctype == T_MYADDR6 && ncpaddr_family(local) == AF_INET6) 57681634Sbrian ncprange_sethost(&fp->f_src, local); 57781634Sbrian if (fp->f_dsttype == T_MYADDR6 && ncpaddr_family(local) == AF_INET6) 57881634Sbrian ncprange_sethost(&fp->f_dst, local); 57981634Sbrian#endif 58047648Sbrian } 58181634Sbrian if (remote) { 58281634Sbrian if (fp->f_srctype == T_HISADDR && ncpaddr_family(remote) == AF_INET) 58381634Sbrian ncprange_sethost(&fp->f_src, remote); 58481634Sbrian if (fp->f_dsttype == T_HISADDR && ncpaddr_family(remote) == AF_INET) 58581634Sbrian ncprange_sethost(&fp->f_dst, remote); 58681634Sbrian#ifndef NOINET6 58781634Sbrian if (fp->f_srctype == T_HISADDR6 && ncpaddr_family(remote) == AF_INET6) 58881634Sbrian ncprange_sethost(&fp->f_src, remote); 58981634Sbrian if (fp->f_dsttype == T_HISADDR6 && ncpaddr_family(remote) == AF_INET6) 59081634Sbrian ncprange_sethost(&fp->f_dst, remote); 59181634Sbrian#endif 59247648Sbrian } 59358044Sbrian if (dns) { 59458044Sbrian if (fp->f_srctype == T_DNS0) 59581634Sbrian ncprange_setip4host(&fp->f_src, dns[0]); 59658044Sbrian if (fp->f_dsttype == T_DNS0) 59781634Sbrian ncprange_setip4host(&fp->f_dst, dns[0]); 59858044Sbrian if (fp->f_srctype == T_DNS1) 59981634Sbrian ncprange_setip4host(&fp->f_src, dns[1]); 60058044Sbrian if (fp->f_dsttype == T_DNS1) 60181634Sbrian ncprange_setip4host(&fp->f_dst, dns[1]); 60258044Sbrian } 60347648Sbrian } 60447648Sbrian} 605