📄 filters.c
字号:
* dir: Filter direction. "IN" or "OUT" * * action: Filter action. "FORWARD" or "DROP" * * dstip: Keyword for destination IP address. * n.n.n.n = IP address. * /nn = netmask. * * srcip: Keyword for source IP address. * n.n.n.n = IP address. * /nn = netmask. * * proto: Optional protocol field. Either a name or number. * Known names are in filterprotoname[]. * * dstport: Keyword for destination port. * Only valid for TCP or UDP. * 'cmp' are in radfiltercomp enumeration type. * 'value' entries are in filterporttype[]. * 'value' may be a name or number. * * srcport: Keyword for source port. Only valid for TCP or UDP. * 'cmp' are in radfiltercomp enumeration type. * 'value' entries are in filterporttype[]. * 'value' may be a name or number. * * est: Keyword for TCP established. Valid only for TCP. * * Returns: -1 for error, or 0 otherwise. * *************************************************************************/static intparse_ip_filter (curentry)radfilter *curentry; /* Pointer to return the filter structure. */{ UINT4 elements = (UINT4) 0; int tok; char *token; radipfilter *ip; static char *func = "parse_ip_filter"; dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: entered", func)); token = (char *) strtok (NULL, " "); memset (curentry, '\0', sizeof (radfilter)); curentry->type = RAD_FILTER_IP; ip = &curentry->u.ip; ip->established = FALSE; while (token) { dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: token %s ", func, token)); tok = find_key (token, filterkeywords); dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: tok %d ", func, tok)); switch (tok) { case FILTER_IN: case FILTER_OUT: curentry->input = (tok == FILTER_IN) ? TRUE : FALSE; dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: got %s ", func, tok == FILTER_IN ? "FILTER_IN" : "FILTER_OUT")); elements |= (1 << FILTER_DIRECTION); break; case FILTER_FORWARD: case FILTER_DROP: dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: got %s ", func, tok == FILTER_DROP ? "FILTER_DROP" : "FILTER_FORWARD")); elements |= (1 << FILTER_DISPOSITION); if (tok == FILTER_FORWARD) { curentry->forward = TRUE; } else { curentry->forward = FALSE; } break; case FILTER_IP_DST: case FILTER_IP_SRC: dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: got %s ", func, tok == FILTER_IP_DST ? "FILTER_IP_DST" : "FILTER_IP_SRC")); token = (char *) strtok (NULL, " "); if (token) { if (tok == FILTER_IP_DST) { if (ipaddr_str2val ((char *) token, &ip->dstip, (char *) &ip->dstmask)) { dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: ip %lx netmask %lx", func, ip->dstip, ip->dstmask)); break; } } else { if (ipaddr_str2val ((char *) token, &ip->srcip, (char *) &ip->srcmask)) { dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: ip %lx netmask %lx", ip->srcip, ip->srcmask)); break; } } } dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: IP filter syntax error %s", func, (token == (char *) NULL) ? "?" : token )); logit (LOG_DAEMON, LOG_ERR, "%s: IP filter syntax error: do not recognize %s in %s", func, token, curstring); return (-1); case FILTER_IP_DST_PORT: case FILTER_IP_SRC_PORT: { radfiltercomp cmp; short port; dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: got %s", func, tok == FILTER_IP_DST_PORT ? "FILTER_IP_DST_PORT" : "FILTER_IP_SRC_PORT")); token = (char *) strtok (NULL, " "); if (token) { cmp = find_key (token, filtercompare); dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: cmp value = %d", func, cmp)); if (cmp != NO_TOKEN) { token = (char *) strtok (NULL, " "); if (token) { if (is_all_digit (token)) { port = atoi ((char *) token); } else { port = find_key (token, filterporttype); } if (port != (short) NO_TOKEN) { dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: port = %d", func, port)); if (tok == FILTER_IP_DST_PORT) { ip->dstportcomp = cmp; ip->dstport = htons(port); } else { ip->srcportcomp = cmp; ip->srcport = htons(port); } break; } } } } logit (LOG_DAEMON, LOG_ERR, "%s: IP filter syntax error: do not recognize %s in %s", func, token, curstring); dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: IP Filter syntax error %s", func, (token == (char *) NULL) ? "?" : token )); return (-1); break; } case FILTER_EST: dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: got est %s", func, (token == (char *) NULL) ? "?" : token )); ip->established = TRUE; break; default: /* no keyword match but may match a protocol list */ if (is_all_digit (token)) { tok = atoi ((char *) token); } else { tok = find_key (token, filterprotoname); if (tok == NO_TOKEN) { dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: IP protocol error %s", func, (token == (char *) NULL) ? "?" : token )); logit (LOG_DAEMON, LOG_ERR, "%s: IP filter syntax error: do not recognize %s in %s", func, token, curstring); return (-1); } } ip->proto = tok; dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: IP protocol cmd = %d", func, tok)); } /* end of switch */ token = (char *) strtok (NULL, " "); } if (elements == IP_FILTER_COMPLETE) { return (0); } logit (LOG_DAEMON, LOG_ERR, "%s: Non-Fatal internal error!", func); return (-1);} /* end of parse_ip_filter () *//************************************************************************* * * Function: parse_gen_filter: * * Purpose: Parses a Generic filter string from a RADIUS reply. * The format of the string is: * * GENERIC dir action offset mask value [== or != ] [more] * * Fields in [...] are optional. Where: * * generic: Keyword to indicate a generic filter. * * dir: Filter direction. "IN" or "OUT" * * action: Filter action. "FORWARD" or "DROP" * * offset: A Number. Specifies an offset into * a frame to start comparing. * * mask: A hexadecimal mask of bits to compare. * * value: A value to compare with the masked data. * * compneq: Defines type of comparison. ( "==" or "!=") * Default is "==". * * more: Optional keyword MORE, to represent the * attachment to the next entry. * * Returns: -1 for error, or 0 otherwise. * *************************************************************************/static intparse_gen_filter (curentry)radfilter *curentry; /* Pointer to return the filter structure. */{ short masklen; short vallen; int gstate = FILTER_GENERIC_OFFSET; int tok; UINT4 elements = (UINT4) 0; char *token; radgenfilter *gen; static char *func = "parse_gen_filter"; dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: entered", func)); token = (char *) strtok (NULL, " "); masklen = 0; memset ((char *) curentry, '\0', sizeof (radfilter)); curentry->type = RAD_FILTER_GENERIC; gen = &curentry->u.generic; gen->more = FALSE; gen->compneq = FALSE; while (token) { dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: token %s", func, token)); tok = find_key (token, filterkeywords); dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: tok %d ", func, tok)); switch (tok) { case FILTER_IN: case FILTER_OUT: curentry->input = (tok == FILTER_IN) ? TRUE : FALSE; elements |= (1 << FILTER_DIRECTION); dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: got %s", func, tok == FILTER_IN ? "FILTER_IN" : "FILTER_OUT")); break; case FILTER_FORWARD: case FILTER_DROP: elements |= (1 << FILTER_DISPOSITION); dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: got %s", func, tok == FILTER_DROP ? "FILTER_DROP" : "FILTER_FORWARD")); if (tok == FILTER_FORWARD) { curentry->forward = TRUE; } else { curentry->forward = FALSE; } break; case FILTER_GENERIC_COMPNEQ: gen->compneq = TRUE; dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: got comp != %s", func, token)); break; case FILTER_GENERIC_COMPEQ: gen->compneq = FALSE; dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: got comp = %s", func, token)); break; case FILTER_MORE: gen->more = htons(TRUE); dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: got more %s", func, token)); break; default: elements |= (1 << gstate); switch (gstate) { case FILTER_GENERIC_OFFSET: gstate = FILTER_GENERIC_MASK; gen->offset = htons(atoi ((char *) token)); break; case FILTER_GENERIC_MASK: gstate = FILTER_GENERIC_VALUE; masklen = a2octet (token, (char *) gen->mask); if (masklen == (short) -1) { logit (LOG_DAEMON, LOG_ERR, "%s: filter mask error: %s", func, curstring); return (-1); } dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: octet retlen = %d ", func, masklen)); for (tok = 0; tok < masklen; tok++) { dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%2x", gen->mask[tok])); } break; case FILTER_GENERIC_VALUE: gstate++; vallen = a2octet (token, (char *) gen->value); if (vallen != masklen) { logit (LOG_DAEMON, LOG_ERR, "%s: filter value size not same as filter mask: %s", func, curstring); return (-1); } gen->len = htons(vallen); dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: octet retlen = %d ", func, masklen)); for (tok = 0; tok < masklen; tok++) { dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%2x", gen->value[tok])); } break; default: logit (LOG_DAEMON, LOG_ERR, "%s: do not know %s in %s", func, token, curstring); dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: Filter syntax error %s", func, token)); return (-1); } /* end of switch */ } /* end of switch */ token = (char *) strtok (NULL, " "); } /* end of while */ if (elements == GENERIC_FILTER_COMPLETE) { return (0); } logit (LOG_DAEMON, LOG_ERR, "%s: Non-Fatal internal error!", func); return (-1);} /* end of parse_gen_filter () *//************************************************************************* * * Function: filter_binary * * Purpose: Parse entries from an ASCII format to a * binary format recognized by Ascend boxes. * * Returns: the binary filter length, * or -1 otherwise. * *************************************************************************/intfilter_binary (filter, valstr)char *filter; /* Pointer to place to return parsed filter. */char *valstr; /* The string to parse. */{ int rc = -1; int tok; char *token;/* radfilter *filt; See CODE REMOVED below. *//* radgenfilter *gen; See CODE REMOVED below. */ radfilter radfil; static char *func = "filter_binary"; dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: entered", func)); filter[0] = '\0'; if (valstr != (char *) NULL) { strcpy (curstring, valstr); } else { return (rc); } token = (char *) strtok ((char *) valstr, " "); tok = find_key (token, filterkeywords); switch (tok) { case FILTER_IP_TYPE: rc = parse_ip_filter (&radfil); break; case FILTER_GENERIC_TYPE: rc = parse_gen_filter (&radfil); break; } /*************code below moved to avpair_add_vend()******************* * * If "more" is set, then this new entry must exist, be of * FILTER_GENERIC_TYPE, the direction and disposition must * match for the previous "more" to be valid. If any should * fail, then TURN OFF previous more.VALUE_PAIR *prevradpair = 0; if (prevradpair) { filt = (radfilter *) prevradpair->strvalue; if ((tok != FILTER_GENERIC_TYPE) || (rc == -1) || (prevradpair->attribute != pair->attribute) || (filt->input != radfil.input) || (filt->forward != radfil.forward)) { gen = &filt->u.generic; gen->more = FALSE; logit (LOG_DAEMON, LOG_ERR, "%s: 'more' for previous entry doesn't match: %s", func, curstring); } } prevradpair = (VALUE_PAIR *) NULL; if (rc != -1 && tok == FILTER_GENERIC_TYPE) { if (radfil.u.generic.more) { prevradpair = pair; } } **************above code moved to avpair_add_vend()*************/ if (rc != -1) { memcpy (filter, (char *) &radfil, sizeof (radfilter)); rc = sizeof (radfilter); } return (rc);} /* end of filter_binary () */#endif /* BINARY_FILTERS */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -