⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filters.c

📁 radius服务器
💻 C
📖 第 1 页 / 共 2 页
字号:
		 */		*ipaddr |= (ip[count] << (8 * (3 - count)));	}	/*	 *	We've hit the end of the IP address, and there's something	 *	else left over: die.	 */	if (*str) return -1;	/*	 *	Set the default netmask.	 */	if (!netmask) {		if (!*ipaddr) {			netmask = 0;		} else if ((*ipaddr & 0x80000000) == 0) {			netmask = 8;		} else if ((*ipaddr & 0xc0000000) == 0x80000000) {			netmask = 16;		} else if ((*ipaddr & 0xe0000000) == 0xc0000000) {			netmask = 24;		} else {			netmask = 32;		}	}	*ipaddr = htonl(*ipaddr);	return netmask;}/* *	ascend_parse_port:  Parse a comparator and port. * *	Returns -1 on error, or the comparator. */static int ascend_parse_port(uint16_t *port, char *compare, char *str){	int rcode, token = -1;	/*	 *	There MUST be a comparison string.	 */	rcode = lrad_str2int(filterCompare, compare, -1);	if (rcode < 0) return rcode;	if (strspn(str, "0123456789") == strlen(str)) {		token = atoi(str);	} else {		token = lrad_str2int(filterPortType, str, -1);	}	if ((token < 0) || (token > 65535)) return -1;	*port = token;	*port = htons(*port);	return rcode;}/* *	ascend_parse_ip: * *	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. * *	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 with tcp *			or udp. 'cmp' are in FilterPortType[]. 'value' can be *			a name or number. * *	srcport:	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. * */static int ascend_parse_ip(int argc, char **argv, ascend_ip_filter_t *filter){	int rcode;	int token;	int flags;	/*	 *	We may have nothing, in which case we simply return.	 */	if (argc == 0) return 0;	/*	 *	There may, or may not, be src & dst IP's in the string.	 */	flags = 0;	while ((argc > 0) && (flags != 7)) {		token = lrad_str2int(filterKeywords, argv[0], -1);		switch (token) {		case FILTER_IP_SRC:			if (flags & 0x01) return -1;			if (argc < 2) return -1;			rcode = ascend_parse_ipaddr(&filter->srcip, argv[1]);			if (rcode < 0) return rcode;			filter->srcmask = rcode;			flags |= 0x01;			argv += 2;			argc -= 2;			break;		case FILTER_IP_DST:			if (flags & 0x02) return -1;			if (argc < 2) return -1;			rcode = ascend_parse_ipaddr(&filter->dstip, argv[1]);			if (rcode < 0) return rcode;			filter->dstmask = rcode;			flags |= 0x02;			argv += 2;			argc -= 2;			break;			/*			 *	Should be protocol, ASCII or otherwise.			 */		default:			if (strspn(argv[0], "0123456789") == strlen(argv[0])) {				token = atoi(argv[0]);			} else {				token = lrad_str2int(filterProtoName, argv[0], -1);				if (token == -1) {					librad_log("Unknown IP protocol \"%s\" in IP data filter",						   argv[0]);					return -1;				}			}			filter->proto = token;			flags = 0x07; /* MUST have parsed everything. */			argv++;			argc--;			break;		}	} /* looking for src/dst IP, and proto */	/*	 *	Done looking for everything, return.	 */	if (argc == 0) return 0;	/*	 *	There may, or may not, be src & dst ports in the string.	 */	flags = 0;	while ((argc > 0) && (flags != 7)) {		token = lrad_str2int(filterKeywords, argv[0], -1);		switch (token) {		case FILTER_IP_SRC_PORT:			if (flags & 0x01) return -1;			if (argc < 3) return -1;			rcode = ascend_parse_port(&filter->srcport,						  argv[1], argv[2]);			if (rcode < 0) return rcode;			filter->srcPortComp = rcode;			flags |= 0x01;			argv += 3;			argc -= 3;			break;		case FILTER_IP_DST_PORT:			if (flags & 0x02) return -1;			if (argc < 3) return -1;			rcode = ascend_parse_port(&filter->dstport,						  argv[1], argv[2]);			if (rcode < 0) return rcode;			filter->dstPortComp = rcode;			flags |= 0x02;			argv += 3;			argc -= 3;			break;			/*			 *	Look for established connections.			 */		case FILTER_EST:			filter->established = 1;			argv++;			argc--;			flags = 0x07;			break;			/*			 *	Unknown thingy.			 */		default:			librad_log("Unknown string \"%s\" in IP data filter",				   argv[0]);			return -1;			break;		}	} /* looking for src/dst port */	/*	 *	We should have parsed everything by now.	 */	if (argc != 0) {		librad_log("Unknown extra string \"%s\" in IP data filter",			   argv[0]);		return -1;	}	return 0;}/* *	ascend_parse_generic * *	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. * *	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. */static int ascend_parse_generic(int argc, char **argv,				ascend_generic_filter_t *filter){	int rcode;	int token;	int flags;	/*	 *	We may have nothing, in which case we simply return.	 */	if (argc == 0) return 0;	/*	 *	We need at least "offset mask value"	 */	if (argc < 3) return -1;	/*	 *	No more than optional comparison and "more"	 */	if (argc > 5) return -1;	/*	 *	Offset is a uint16_t number.	 */	if (strspn(argv[0], "0123456789") != strlen(argv[0])) return -1;	rcode = atoi(argv[0]);	if (rcode > 65535) return -1;	filter->offset = rcode;	filter->offset = htons(filter->offset);	rcode = hex2bin(argv[1], filter->mask, sizeof(filter->mask));	if (rcode < 0) return -1;	token = hex2bin(argv[2], filter->value, sizeof(filter->value));	if (token < 0) return -1;	/*	 *	The mask and value MUST be the same length.	 */	if (rcode != token) return -1;	filter->len = rcode;	filter->len = htons(filter->len);	/*	 *	Nothing more.  Exit.	 */	if (argc == 3) return 0;	argc -= 3;	argv += 3;	flags = 0;	while (argc >= 1) {		token = lrad_str2int(filterKeywords, argv[0], -1);		switch (token) {		case FILTER_GENERIC_COMPNEQ:			if (flags & 0x01) return -1;			filter->compNeq = TRUE;			flags |= 0x01;			break;		case FILTER_GENERIC_COMPEQ:			if (flags & 0x01) return -1;			filter->compNeq = FALSE;			flags |= 0x01;			break;		case FILTER_MORE:			if (flags & 0x02) return -1;			filter->more = htons( 1 );			flags |= 0x02;			break;		default:			librad_log("Invalid string \"%s\" in generic data filter",				   argv[0]);			return -1;		}		argc--;		argv++;	}	return 0;}/* * 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. */intascend_parse_filter(VALUE_PAIR *pair){	int		token, type;	int	        rcode;	int		argc;	char		*argv[32];	ascend_filter_t filter;	rcode = -1;	/*	 *	Tokenize the input string in the VP.	 *	 *	Once the filter is *completelty* parsed, then we will	 *	over-write it with the final binary filter.	 */	argc = str2argv(pair->strvalue, argv, 32);	if (argc < 3) return -1;	/*	 *	Decide which filter type it is: ip, ipx, or generic	 */	type = lrad_str2int(filterType, argv[0], -1);	memset(&filter, 0, sizeof(filter));	/*	 *	Validate the filter type.	 */	switch (type) {	case RAD_FILTER_GENERIC:	case RAD_FILTER_IP:	case RAD_FILTER_IPX:		filter.type = type;		break;	default:		librad_log("Unknown Ascend filter type \"%s\"", argv[0]);		return -1;		break;	}	/*	 *	Parse direction	 */	token = lrad_str2int(filterKeywords, argv[1], -1);	switch (token) {	case FILTER_IN:		filter.direction = 1;		break;	case FILTER_OUT:		filter.direction = 0;		break;	default:		librad_log("Unknown Ascend filter direction \"%s\"", argv[1]);		return -1;		break;	}	/*	 *	Parse action	 */	token = lrad_str2int(filterKeywords, argv[2], -1);	switch (token) {	case FILTER_FORWARD:		filter.forward = 1;		break;	case FILTER_DROP:		filter.forward = 0;		break;	default:		librad_log("Unknown Ascend filter action \"%s\"", argv[2]);		return -1;		break;	}	switch (type) {	case RAD_FILTER_GENERIC:		rcode = ascend_parse_generic(argc - 3, &argv[3],					  &filter.u.generic);		break;	case RAD_FILTER_IP:		rcode = ascend_parse_ip(argc - 3, &argv[3], &filter.u.ip);		break;	case RAD_FILTER_IPX:		rcode = ascend_parse_ipx(argc - 3, &argv[3], &filter.u.ipx);		break;	default:		/* should never reach here. */		break;	}	/*	 *	Touch the VP only if everything was OK.	 */	if (rcode == 0) {		pair->length = SIZEOF_RADFILTER;		memcpy(pair->strvalue, &filter, sizeof(filter));	}	return rcode;#if 0    /*     * 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     * previous '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;	    librad_log("filterBinary:  'more' for previous entry doesn't match: %s.\n",		     valstr);	}    }    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->length );    }    return(rc);#endif}/* *	Print an Ascend binary filter attribute to a string, *	Grrr... Ascend makes the server do this work, instead *	of doing it on the NAS. * *	Note we don't bother checking 'len' after the snprintf's. *	This function should ONLY be called with a large (~1k) buffer. */void print_abinary(VALUE_PAIR *vp, u_char *buffer, int len){  int 			i;  char			*p;  ascend_filter_t	filter;  static const char *action[] = {"drop", "forward"};  static const char *direction[] = {"out", "in"};  p = (char *)buffer;  /*   *  Just for paranoia: wrong size filters get printed as octets   */  if (vp->length > SIZEOF_RADFILTER) {    strcpy(p, "0x");    p += 2;    for (i = 0; i < vp->length; i++) {      sprintf(p, " %02x", vp->strvalue[i]);      p += 3;    }    return;  }  memcpy(&filter, vp->strvalue, SIZEOF_RADFILTER); /* alignment issues */  *(p++) = '"';  len -= 3;			/* account for leading & trailing quotes */  i = snprintf(p, len, "%s %s %s",	       lrad_int2str(filterType, filter.type, "??"),	       direction[filter.direction & 0x01],	       action[filter.forward & 0x01]);  p += i;  len -= i;  /*   *	Handle IP filters   */  if (filter.type == RAD_FILTER_IP) {    if (filter.u.ip.srcip) {      i = snprintf(p, len, " srcip %d.%d.%d.%d/%d",		   ((u_char *) &filter.u.ip.srcip)[0],		   ((u_char *) &filter.u.ip.srcip)[1],		   ((u_char *) &filter.u.ip.srcip)[2],		   ((u_char *) &filter.u.ip.srcip)[3],		   filter.u.ip.srcmask);      p += i;      len -= i;    }    if (filter.u.ip.dstip) {      i = snprintf(p, len, " dstip %d.%d.%d.%d/%d",		   ((u_char *) &filter.u.ip.dstip)[0],		   ((u_char *) &filter.u.ip.dstip)[1],		   ((u_char *) &filter.u.ip.dstip)[2],		   ((u_char *) &filter.u.ip.dstip)[3],		   filter.u.ip.dstmask);      p += i;      len -= i;    }    i =  snprintf(p, len, " %s",		  lrad_int2str(filterProtoName, filter.u.ip.proto, "??"));    p += i;    len -= i;    if (filter.u.ip.srcPortComp > RAD_NO_COMPARE) {      i = snprintf(p, len, " srcport %s %d",		   lrad_int2str(filterCompare, filter.u.ip.srcPortComp, "??"),		   ntohs(filter.u.ip.srcport));      p += i;      len -= i;    }    if (filter.u.ip.dstPortComp > RAD_NO_COMPARE) {      i = snprintf(p, len, " dstport %s %d",		   lrad_int2str(filterCompare, filter.u.ip.dstPortComp, "??"),		   ntohs(filter.u.ip.dstport));      p += i;      len -= i;    }    if (filter.u.ip.established) {      i = snprintf(p, len, " est");      p += i;      len -= i;    }    /*     *	Handle IPX filters     */  } else if (filter.type == RAD_FILTER_IPX) {    /* print for source */    if (filter.u.ipx.src.net) {      i = snprintf(p, len, " srcipxnet 0x%04x srcipxnode 0x%02x%02x%02x%02x%02x%02x",		  (unsigned int)ntohl(filter.u.ipx.src.net),		  filter.u.ipx.src.node[0], filter.u.ipx.src.node[1],		  filter.u.ipx.src.node[2], filter.u.ipx.src.node[3],		  filter.u.ipx.src.node[4], filter.u.ipx.src.node[5]);      p += i;      len -= i;      if (filter.u.ipx.srcSocComp > RAD_NO_COMPARE) {	i = snprintf(p, len, " srcipxsock %s 0x%04x",		     lrad_int2str(filterCompare, filter.u.ipx.srcSocComp, "??"),		     ntohs(filter.u.ipx.src.socket));	p += i;	len -= i;      }    }    /* same for destination */    if (filter.u.ipx.dst.net) {      i = snprintf(p, len, " dstipxnet 0x%04x dstipxnode 0x%02x%02x%02x%02x%02x%02x",		  (unsigned int)ntohl(filter.u.ipx.dst.net),		  filter.u.ipx.dst.node[0], filter.u.ipx.dst.node[1],		  filter.u.ipx.dst.node[2], filter.u.ipx.dst.node[3],		  filter.u.ipx.dst.node[4], filter.u.ipx.dst.node[5]);      p += i;      len -= i;      if (filter.u.ipx.dstSocComp > RAD_NO_COMPARE) {	i = snprintf(p, len, " dstipxsock %s 0x%04x",		     lrad_int2str(filterCompare, filter.u.ipx.dstSocComp, "??"),		     ntohs(filter.u.ipx.dst.socket));	p += i;	len -= i;      }    }  } else if (filter.type == RAD_FILTER_GENERIC) {    int count;    i = snprintf(p, len, " %u ", (unsigned int) ntohs(filter.u.generic.offset));    p += i;    i -= len;    /* show the mask */    for (count = 0; count < ntohs(filter.u.generic.len); count++) {      i = snprintf(p, len, "%02x", filter.u.generic.mask[count]);      p += i;      len -= i;    }    strcpy(p, " ");    p++;    len--;    /* show the value */    for (count = 0; count < ntohs(filter.u.generic.len); count++) {      i = snprintf(p, len, "%02x", filter.u.generic.value[count]);      p += i;      len -= i;    }    i = snprintf(p, len, " %s", (filter.u.generic.compNeq) ? "!=" : "==");    p += i;    len -= i;    if (filter.u.generic.more != 0) {      i = snprintf(p, len, " more");      p += i;      len -= i;    }  }  *(p++) = '"';  *p = '\0';}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -