📄 filters.c
字号:
unsigned long elements = 0l; int tok; char* token; RadIpxFilter* ipx; token = (char *) strtok( NULL, " " ); memset( curEntry, '\0', sizeof( RadFilter ) ); curEntry->type = RAD_FILTER_IPX; ipx = &curEntry->u.ipx; while( token ) { tok = _findKey( token, _filterKeywords ); switch( tok ) { case FILTER_IN: case FILTER_OUT: curEntry->indirection = tok == FILTER_IN ? TRUE: FALSE; debug(" got FILTER %s ", tok == FILTER_IN?"IN":"OUT"); elements |= (1 << FILTER_DIRECTION ); break; case FILTER_FORWARD: case FILTER_DROP: debug(" got FILTER %s ", tok == FILTER_DROP? "DROP":"FORWARD"); elements |= (1 << FILTER_DISPOSITION ); if( tok == FILTER_FORWARD ) { curEntry->forward = TRUE; } else { curEntry->forward = FALSE; } break; case FILTER_IPX_DST_IPXNET: case FILTER_IPX_SRC_IPXNET: debug(" got FILTER_IPX %s IPXNET ", tok == FILTER_IPX_DST_IPXNET ? "DST":"SRC"); token = (char *) strtok( NULL, " " ); if ( token ) { if( tok == FILTER_IPX_DST_IPXNET ) { ipx->dstIpxNet = ntohl( strtol( token, 0, 16 )); debug("D.Net: %08lX token: %s \n", htonl(ipx->dstIpxNet), token); } else { ipx->srcIpxNet = ntohl( strtol( token, 0, 16 )); debug("S Net: %08lX token: %s \n", htonl(ipx->srcIpxNet), token); } break; } goto doneErr; case FILTER_IPX_DST_IPXNODE: case FILTER_IPX_SRC_IPXNODE: debug(" got FILTER_IPX %s IPXNODE ", tok == FILTER_IPX_DST_IPXNODE ? "DST":"SRC"); token = (char *) strtok( NULL, " " ); if ( token ) { if ( tok == FILTER_IPX_DST_IPXNODE) { _stringToNode( (unsigned char *)ipx->dstIpxNode, (unsigned char*)token ); debug("D. Node: %08lX%04X \n", htonl((*(int *)(ipx->dstIpxNode))), htons((*(short *)(ipx->dstIpxNode+4)))); } else { _stringToNode( (unsigned char *)ipx->srcIpxNode, (unsigned char*)token ); debug("S. Node: %08lX%04X \n", htonl((*(int *)(ipx->srcIpxNode))), htons((*(short *)(ipx->srcIpxNode+4)))); } break; } goto doneErr; case FILTER_IPX_DST_IPXSOCK: case FILTER_IPX_SRC_IPXSOCK: { RadFilterComparison cmp; debug(" got FILTER_IPX %s IPXSOCK", tok == FILTER_IPX_DST_IPXSOCK ? "DST":"SRC"); token = (char *) strtok( NULL, " " ); if ( token ) { cmp = _findKey( token, _filterCompare ); debug(" cmp value = %d \n", cmp ); if( cmp != NO_TOKEN ) { token = (char *) strtok( NULL, " " ); if ( token ) { if ( tok == FILTER_IPX_DST_IPXSOCK ) { ipx->dstSocComp = cmp; ipx->dstIpxSoc = ntohs( (IpxSocket) strtol( token, NULL, 16 )); debug("%X \n", htons(ipx->dstIpxSoc)); } else { ipx->srcSocComp = cmp; ipx->srcIpxSoc = ntohs( (IpxSocket) strtol( token, NULL, 16 )); debug("%X \n", htons(ipx->srcIpxSoc)); } break; } } } goto doneErr; } default: /* no keyword match */ goto doneErr; } token = (char *) strtok( NULL, " " ); } if( elements == IPX_FILTER_COMPLETE ) { return( 0 ); }doneErr: debug( "RADIF: IPX Filter syntax error %s \n", token ); log_err( "ipx filter error: do not recognize %s in %s \n", token, _curString ); return( -1 );} /* * _parseIpFilter: * * This routine parses an IP filter string from a RADIUS * reply. The format of the string is: * * ip dir action [ dstip n.n.n.n/nn ] [ srcip n.n.n.n/nn ] * [ proto [ dstport cmp value ] [ srcport cmd value ] [ est ] ] * * Fields in [...] are optional. * where: * * ip: Keyword to designate an IP filter. Actually this * has been determined by _parseFilter. * * 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[]. * * dstpost: Keyword for destination port. Only valid with tcp * or udp. 'cmp' are in FilterPortType[]. 'value' can be * a name or number. * * srcpost: Keyword for source port. Only valid with tcp * or udp. 'cmp' are in FilterPortType[]. 'value' can be * a name or number. * * est: Keyword for TCP established. Valid only for tcp. * * expects: * * curEntry: Pointer to place the filter structure * * returns: -1 for error or 0 for OK * */static int _parseIpFilter(RadFilter *curEntry){ unsigned long elements = 0l; int tok; char* token; RadIpFilter* ip; token = (char *) strtok( NULL, " " ); debug(" in ip filter \n"); memset( curEntry, '\0', sizeof( RadFilter ) ); curEntry->type = RAD_FILTER_IP; ip = &curEntry->u.ip; ip->established = FALSE; while( token ) { debug(" token %s ", token ); tok = _findKey( token, _filterKeywords ); switch( tok ) { case FILTER_IN: case FILTER_OUT: curEntry->indirection = tok == FILTER_IN ? TRUE: FALSE; debug(" got %s ", tok == FILTER_IN?"FILTER_IN":"FILTER_OUT"); elements |= (1 << FILTER_DIRECTION ); break; case FILTER_FORWARD: case FILTER_DROP: debug(" got %s ", 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: debug(" got %s ", tok == FILTER_IP_DST? "FILTER_IP_DST":"FILTER_IP_SRC"); token = (char *) strtok( NULL, " " ); if ( token ) { if( tok == FILTER_IP_DST ) { if( _ipAddressStringToValue( (char*)token, &ip->dstip, (char *)&ip->dstmask ) ) { debug(" ip %lx netmask %lx \n", ip->dstip, ip->dstmask ); break; } } else { if( _ipAddressStringToValue( (char *)token, &ip->srcip, (char *)&ip->srcmask ) ) { debug(" ip %lx netmask %lx \n", ip->srcip, ip->srcmask ); break; } } } debug( "RADIF: IP Filter syntax error %s \n", token ); log_err( "ip filter error: do not recognize %s in %s \n", token, _curString ); goto doneErr ; case FILTER_IP_DST_PORT: case FILTER_IP_SRC_PORT: { RadFilterComparison cmp; short port; debug(" got %s ", tok == FILTER_IP_DST_PORT? "FILTER_IP_DST_PORT":"FILTER_IP_SRC_PORT"); token = (char *) strtok( NULL, " " ); if ( token ) { cmp = _findKey( token, _filterCompare ); debug(" cmp value = %d \n", cmp ); if( cmp != NO_TOKEN ) { token = (char *) strtok( NULL, " " ); if ( token ) { if( _isAllDigit( token ) ) { port = atoi( (char *) token ); } else { port = _findKey( token, _filterPortType ); } if( port != (short) NO_TOKEN ) { debug(" port = %d \n", port ); if( tok == FILTER_IP_DST_PORT ) { ip->dstPortComp = cmp; ip->dstport = htons( port ); } else { ip->srcPortComp = cmp; ip->srcport = htons( port ); } break; } } } } log_err( "ip filter error: do not recognize %s in %s \n", token, _curString ); debug( "RADIF: IP Filter syntax error %s \n", token ); goto doneErr; break; } case FILTER_EST: debug(" got est %s ", token ); ip->established = TRUE; break; default: /* no keyword match but may match a protocol list */ if( _isAllDigit( token ) ) { tok = atoi( (char *) token ); } else { tok = _findKey( token, _filterProtoName ); if( tok == NO_TOKEN ) { debug( "RADIF: IP proto error %s \n", token ); log_err( "ip filter error: do not recognize %s in %s \n", token, _curString ); goto doneErr; } } ip->proto = tok; debug("ip proto cmd = %d ", tok); } token = (char *) strtok( NULL, " " ); } if( elements == IP_FILTER_COMPLETE ) { return( 0 ); }doneErr: debug((" done err \n")); return( -1 );} /* * _parseGenericFilter: * * This routine 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. This * has been determined by _parseFilter. * * 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. * * expects: * * curEntry: Pointer to place the filter structure * * returns: -1 for error or 0 for OK * */static int_parseGenericFilter(RadFilter *curEntry){ unsigned long elements = 0l; int tok; int gstate = FILTER_GENERIC_OFFSET; char* token; short valLen, maskLen; RadGenericFilter* gen; token = (char *) strtok( NULL, " " ); debug(" in parse generic filter"); 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 ) { debug(" token %s ", token ); tok = _findKey( token, _filterKeywords ); debug("tok %d ", tok); switch( tok ) { case FILTER_IN: case FILTER_OUT: curEntry->indirection = tok == FILTER_IN ? TRUE: FALSE; elements |= (1 << FILTER_DIRECTION ); debug(" got %s ", tok == FILTER_IN?"FILTER_IN":"FILTER_OUT"); break; case FILTER_FORWARD: case FILTER_DROP: elements |= (1 << FILTER_DISPOSITION ); debug(" got %s ", 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; debug(" got compare %s ", token); break; case FILTER_GENERIC_COMPEQ: gen->compNeq = FALSE; debug(" got compare %s ", token); break; case FILTER_MORE: gen->more = htons( TRUE ); debug(" got more %s ", 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 ) { log_err( "filter mask error: %s", _curString ); goto doneErr; } debug(" octet retlen = %d ", maskLen ); for( tok = 0; tok < maskLen; tok++) { debug("%2x", gen->mask[tok]); } break; case FILTER_GENERIC_VALUE: gstate ++; valLen = _a2octet( token, (char *)gen->value ); if( valLen != maskLen ) { log_err( "filter value size is not the same size as the filter mask: %s", _curString ); goto doneErr; } gen->len = htons( valLen ); debug(" octet retlen = %d ", maskLen ); for( tok = 0; tok < maskLen; tok++) { debug("%2x", gen->value[tok]); } break; default: log_err( "filter: do not know %s in %s", token, _curString ); debug( "RADIF: Filter syntax error %s", token ); goto doneErr; } } token = (char *) strtok( NULL, " " ); } if( elements == GENERIC_FILTER_COMPLETE ) { return( 0 ); }doneErr: debug(" done err"); return( -1 );} /* * filterBinary: * * This routine will call routines to parse entries from an ASCII format * to a binary format recognized by the Ascend boxes. * * pair: Pointer to value_pair to place return. * * valstr: The string to parse * * return: -1 for error or 0. */int filterBinary(VALUE_PAIR *pair,char*valstr){ char* token; unsigned long tok; int rc; RadFilter radFil, *filt; RadGenericFilter* gen; rc = -1; strncpy( _curString, valstr,sizeof(_curString)-1 ); _curString[sizeof(_curString)-1]='\0'; token = (char *) strtok( (char *)valstr, " " ); tok = _findKey( token, _filterKeywords ); pair->lvalue = sizeof( RadFilter ); switch( tok ) { case FILTER_IP_TYPE: rc = _parseIpFilter( &radFil ); break; case FILTER_GENERIC_TYPE: rc = _parseGenericFilter( &radFil ); break; case FILTER_IPX_TYPE: rc = _parseIpxFilter( &radFil ); break; } /* * if more is set then this new entry must exist, be a * FILTER_GENERIC_TYPE, direction and disposition must match for * the previous more to be valid. If any should fail then TURN OFF * previos more */ if( prevRadPair ) { filt = ( RadFilter * )prevRadPair->strvalue; if(( tok != FILTER_GENERIC_TYPE ) || (rc == -1 ) || ( prevRadPair->attribute != pair->attribute ) || ( filt->indirection != radFil.indirection ) || ( filt->forward != radFil.forward ) ) { gen = &filt->u.generic; gen->more = FALSE; log_err( "filterBinary: 'more' for previous entry doesn't match: %s.\n",_curString ); } } prevRadPair = NULL; if( rc != -1 && tok == FILTER_GENERIC_TYPE ) { if( radFil.u.generic.more ) { prevRadPair = pair; } } if( rc != -1 ) { memcpy( pair->strvalue, (char *) &radFil, pair->lvalue ); } return(rc);}#endif /* ASCEND_BINARY */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -