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

📄 valuepair.c

📁 使用最广泛的radius的linux的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
		(*ptr)++;	if (**ptr != 0)		*(*ptr)++ = 0;	return res;}/* *	Turn printable string into time_t *	Returns -1 on error, 0 on OK. */static int gettime(const char *valstr, time_t *date){	int		i;	time_t		t;	struct tm	*tm, s_tm;	char		buf[64];	char		*p;	char		*f[4];	char            *tail = '\0';	/*	 * Test for unix timestamp date	 */	*date = strtoul(valstr, &tail, 10);	if (*tail == '\0') {		return 0;	}	tm = &s_tm;	memset(tm, 0, sizeof(*tm));	tm->tm_isdst = -1;	/* don't know, and don't care about DST */	strlcpy(buf, valstr, sizeof(buf));	p = buf;	f[0] = mystrtok(&p, " \t");	f[1] = mystrtok(&p, " \t");	f[2] = mystrtok(&p, " \t");	f[3] = mystrtok(&p, " \t"); /* may, or may not, be present */	if (!f[0] || !f[1] || !f[2]) return -1;	/*	 *	The time has a colon, where nothing else does.	 *	So if we find it, bubble it to the back of the list.	 */	if (f[3]) {		for (i = 0; i < 3; i++) {			if (strchr(f[i], ':')) {				p = f[3];				f[3] = f[i];				f[i] = p;				break;			}		}	}	/*	 *  The month is text, which allows us to find it easily.	 */	tm->tm_mon = 12;	for (i = 0; i < 3; i++) {		if (isalpha( (int) *f[i])) {			/*			 *  Bubble the month to the front of the list			 */			p = f[0];			f[0] = f[i];			f[i] = p;			for (i = 0; i < 12; i++) {				if (strncasecmp(months[i], f[0], 3) == 0) {					tm->tm_mon = i;					break;				}			}		}	}	/* month not found? */	if (tm->tm_mon == 12) return -1;	/*	 *  The year may be in f[1], or in f[2]	 */	tm->tm_year = atoi(f[1]);	tm->tm_mday = atoi(f[2]);	if (tm->tm_year >= 1900) {		tm->tm_year -= 1900;	} else {		/*		 *  We can't use 2-digit years any more, they make it		 *  impossible to tell what's the day, and what's the year.		 */		if (tm->tm_mday < 1900) return -1;		/*		 *  Swap the year and the day.		 */		i = tm->tm_year;		tm->tm_year = tm->tm_mday - 1900;		tm->tm_mday = i;	}	/*	 *  If the day is out of range, die.	 */	if ((tm->tm_mday < 1) || (tm->tm_mday > 31)) {		return -1;	}	/*	 *	There may be %H:%M:%S.  Parse it in a hacky way.	 */	if (f[3]) {		f[0] = f[3];	/* HH */		f[1] = strchr(f[0], ':'); /* find : separator */		if (!f[1]) return -1;		*(f[1]++) = '\0'; /* nuke it, and point to MM:SS */		f[2] = strchr(f[1], ':'); /* find : separator */		if (f[2]) {		  *(f[2]++) = '\0';	/* nuke it, and point to SS */		} else {		  strcpy(f[2], "0");	/* assignment would discard const */		}		tm->tm_hour = atoi(f[0]);		tm->tm_min = atoi(f[1]);		tm->tm_sec = atoi(f[2]);	}	/*	 *  Returns -1 on error.	 */	t = mktime(tm);	if (t == (time_t) -1) return -1;	*date = t;	return 0;}static const char *hextab = "0123456789abcdef";/* *  Parse a string value into a given VALUE_PAIR * *  FIXME: we probably want to fix this function to accept *  octets as values for any type of attribute.  We should then *  double-check the parsed value, to be sure it's legal for that *  type (length, etc.) */VALUE_PAIR *pairparsevalue(VALUE_PAIR *vp, const char *value){	char		*p, *s=0;	const char	*cp, *cs;	int		x;	size_t		length;	DICT_VALUE	*dval;	/*	 *	Even for integers, dates and ip addresses we	 *	keep the original string in vp->vp_strvalue.	 */	strlcpy(vp->vp_strvalue, value, sizeof(vp->vp_strvalue));	vp->length = strlen(vp->vp_strvalue);	switch(vp->type) {		case PW_TYPE_STRING:			/*			 *	Do escaping here			 */			p = vp->vp_strvalue;			cp = value;			length = 0;			while (*cp && (length < (sizeof(vp->vp_strvalue) - 1))) {				char c = *cp++;				if (c == '\\') {					switch (*cp) {					case 'r':						c = '\r';						cp++;						break;					case 'n':						c = '\n';						cp++;						break;					case 't':						c = '\t';						cp++;						break;					case '"':						c = '"';						cp++;						break;					case '\'':						c = '\'';						cp++;						break;					case '`':						c = '`';						cp++;						break;					case '\0':						c = '\\'; /* no cp++ */						break;					default:						if ((cp[0] >= '0') &&						    (cp[0] <= '9') &&						    (cp[1] >= '0') &&						    (cp[1] <= '9') &&						    (cp[2] >= '0') &&						    (cp[2] <= '9') &&						    (sscanf(cp, "%3o", &x) == 1)) {							c = x;							cp += 3;						} /* else just do '\\' */					}				}				*p++ = c;				length++;			}			vp->length = length;			break;		case PW_TYPE_IPADDR:			/*			 *	It's a comparison, not a real IP.			 */			if ((vp->operator == T_OP_REG_EQ) ||			    (vp->operator == T_OP_REG_NE)) {				break;			}			/*			 *	FIXME: complain if hostname			 *	cannot be resolved, or resolve later!			 */			s = NULL;			if ((p = strrchr(value, '+')) != NULL && !p[1]) {				cs = s = strdup(value);				if (!s) return NULL;				p = strrchr(s, '+');				*p = 0;				vp->flags.addport = 1;			} else {				p = NULL;				cs = value;			}			{				fr_ipaddr_t ipaddr;				if (ip_hton(cs, AF_INET, &ipaddr) < 0) {					free(s);					librad_log("Failed to find IP address for %s", cs);					return NULL;				}				vp->vp_ipaddr = ipaddr.ipaddr.ip4addr.s_addr;			}			free(s);			vp->length = 4;			break;		case PW_TYPE_BYTE:			if (value && (value[0] == '0') && (value[1] == 'x')) {				goto do_octets;			}			/*			 *	Note that ALL integers are unsigned!			 */			vp->vp_integer = (uint32_t) strtoul(value, &p, 10);			if (!*p) {				if (vp->vp_integer > 255) {					librad_log("Byte value \"%s\" is larger than 255", value);					return NULL;				}				vp->length = 1;				break;			}			/*			 *	Look for the named value for the given			 *	attribute.			 */			if ((dval = dict_valbyname(vp->attribute, value)) == NULL) {				librad_log("Unknown value %s for attribute %s",					   value, vp->name);				return NULL;			}			vp->vp_integer = dval->value;			vp->length = 1;			break;		case PW_TYPE_SHORT:			/*			 *	Note that ALL integers are unsigned!			 */			vp->vp_integer = (uint32_t) strtoul(value, &p, 10);			if (!*p) {				if (vp->vp_integer > 65535) {					librad_log("Byte value \"%s\" is larger than 65535", value);					return NULL;				}				vp->length = 2;				break;			}			/*			 *	Look for the named value for the given			 *	attribute.			 */			if ((dval = dict_valbyname(vp->attribute, value)) == NULL) {				librad_log("Unknown value %s for attribute %s",					   value, vp->name);				return NULL;			}			vp->vp_integer = dval->value;			vp->length = 2;			break;		case PW_TYPE_INTEGER:			/*			 *	Note that ALL integers are unsigned!			 */			vp->vp_integer = (uint32_t) strtoul(value, &p, 10);			if (!*p) {				vp->length = 4;				break;			}			/*			 *	Look for the named value for the given			 *	attribute.			 */			if ((dval = dict_valbyname(vp->attribute, value)) == NULL) {				librad_log("Unknown value %s for attribute %s",					   value, vp->name);				return NULL;			}			vp->vp_integer = dval->value;			vp->length = 4;			break;		case PW_TYPE_DATE:		  	{				/*				 *	time_t may be 64 bits, whule vp_date				 *	MUST be 32-bits.  We need an				 *	intermediary variable to handle				 *	the conversions.				 */				time_t date;				if (gettime(value, &date) < 0) {					librad_log("failed to parse time string "						   "\"%s\"", value);					return NULL;				}				vp->vp_date = date;			}			vp->length = 4;			break;		case PW_TYPE_ABINARY:#ifdef ASCEND_BINARY			if (strncasecmp(value, "0x", 2) == 0) {				vp->type = PW_TYPE_OCTETS;				goto do_octets;			}		  	if (ascend_parse_filter(vp) < 0 ) {				librad_log("failed to parse Ascend binary attribute: %s",					   librad_errstr);				return NULL;			}			break;			/*			 *	If Ascend binary is NOT defined,			 *	then fall through to raw octets, so that			 *	the user can at least make them by hand...			 */#endif	do_octets:			/* raw octets: 0x01020304... */		case PW_TYPE_OCTETS:			if (strncasecmp(value, "0x", 2) == 0) {				uint8_t *us;				cp = value + 2;				us = vp->vp_octets;				vp->length = 0;				/*				 *	There is only one character,				 *	die.				 */				if ((strlen(cp) & 0x01) != 0) {					librad_log("Hex string is not an even length string.");					return NULL;				}				while (*cp &&				       (vp->length < MAX_STRING_LEN)) {					unsigned int tmp;					if (sscanf(cp, "%02x", &tmp) != 1) {						librad_log("Non-hex characters at %c%c", cp[0], cp[1]);						return NULL;					}					cp += 2;					*(us++) = tmp;					vp->length++;				}			}			break;		case PW_TYPE_IFID:			if (ifid_aton(value, (void *) &vp->vp_ifid) == NULL) {				librad_log("failed to parse interface-id "					   "string \"%s\"", value);				return NULL;			}			vp->length = 8;			break;		case PW_TYPE_IPV6ADDR:			if (inet_pton(AF_INET6, value, &vp->vp_ipv6addr) <= 0) {				librad_log("failed to parse IPv6 address "					   "string \"%s\"", value);				return NULL;			}			vp->length = 16; /* length of IPv6 address */			break;		case PW_TYPE_IPV6PREFIX:			p = strchr(value, '/');			if (!p || ((p - value) >= 256)) {				librad_log("invalid IPv6 prefix "					   "string \"%s\"", value);				return NULL;			} else {				unsigned int prefix;				char buffer[256], *eptr;				memcpy(buffer, value, p - value);				buffer[p - value] = '\0';				if (inet_pton(AF_INET6, buffer, vp->vp_octets + 2) <= 0) {					librad_log("failed to parse IPv6 address "						   "string \"%s\"", value);					return NULL;				}				prefix = strtoul(p + 1, &eptr, 10);				if ((prefix > 128) || *eptr) {					librad_log("failed to parse IPv6 address "						   "string \"%s\"", value);					return NULL;				}				vp->vp_octets[1] = prefix;			}			vp->vp_octets[0] = '\0';			vp->length = 16 + 2;			break;		case PW_TYPE_ETHERNET:			{				const char *c1, *c2;				length = 0;				cp = value;				while (*cp) {					if (cp[1] == ':') {						c1 = hextab;						c2 = memchr(hextab, tolower((int) cp[0]), 16);						cp += 2;					} else if ((cp[1] != '\0') &&						   ((cp[2] == ':') ||						    (cp[2] == '\0'))) {						   c1 = memchr(hextab, tolower((int) cp[0]), 16);						   c2 = memchr(hextab, tolower((int) cp[1]), 16);						   cp += 2;						   if (*cp == ':') cp++;					} else {						c1 = c2 = NULL;					}					if (!c1 || !c2 || (length >= sizeof(vp->vp_ether))) {						librad_log("failed to parse Ethernet address \"%s\"", value);						return NULL;					}					vp->vp_ether[length] = ((c1-hextab)<<4) + (c2-hextab);					length++;				}			}			vp->length = 6;			break;			/*			 *  Anything else.			 */		default:			librad_log("unknown attribute type %d", vp->type);			return NULL;	}	return vp;}/* *	Create a VALUE_PAIR from an ASCII attribute and value, *	where the attribute name is in the form: * *	Attr-%d *	Vendor-%d-Attr-%d *	VendorName-Attr-%d */static VALUE_PAIR *pairmake_any(const char *attribute, const char *value,				int operator){	int		attr, vendor;	size_t		size;	const char	*p = attribute;	char		*q;	VALUE_PAIR	*vp;	/*	 *	Unknown attributes MUST be of type 'octets'	 */	if (value && (strncasecmp(value, "0x", 2) != 0)) {		librad_log("Invalid octet string \"%s\" for attribute name \"%s\"", value, attribute);		return NULL;	}	attr = vendor = 0;	/*	 *	Pull off vendor prefix first.	 */	if (strncasecmp(p, "Attr-", 5) != 0) {		if (strncasecmp(p, "Vendor-", 7) == 0) {			vendor = (int) strtol(p + 7, &q, 10);			if ((vendor == 0) || (vendor > 65535)) {				librad_log("Invalid vendor value in attribute name \"%s\"", attribute);				return NULL;			}			p = q;		} else {	/* must be vendor name */			char buffer[256];			q = strchr(p, '-');			if (!q) {				librad_log("Invalid vendor name in attribute name \"%s\"", attribute);				return NULL;			}			if ((size_t) (q - p) >= sizeof(buffer)) {				librad_log("Vendor name too long in attribute name \"%s\"", attribute);				return NULL;			}			memcpy(buffer, p, (q - p));			buffer[q - p] = '\0';			vendor = dict_vendorbyname(buffer);			if (!vendor) {				librad_log("Unknown vendor name in attribute name \"%s\"", attribute);				return NULL;			}			p = q;		}		if (*p != '-') {			librad_log("Invalid text following vendor definition in attribute name \"%s\"", attribute);			return NULL;		}		p++;	}	/*	 *	Attr-%d	 */	if (strncasecmp(p, "Attr-", 5) != 0) {		librad_log("Invalid format in attribute name \"%s\"", attribute);		return NULL;	}	attr = strtol(p + 5, &q, 10);	/*	 *	Invalid, or trailing text after number.	 */	if ((attr == 0) || *q) {		librad_log("Invalid value in attribute name \"%s\"", attribute);		return NULL;	}	/*	 *	Double-check the size of attr.	 */	if (vendor) {		DICT_VENDOR *dv = dict_vendorbyvalue(vendor);		if (!dv) {			if (attr > 255) {			attr_error:				librad_log("Invalid attribute number in attribute name \"%s\"", attribute);				return NULL;			}		} else switch (dv->type) {			case 1:				if (attr > 255) goto attr_error;				break;			case 2:				if (attr > 65535) goto attr_error;				break;			case 4:	/* Internal limitations! */				if (attr > 65535) goto attr_error;				break;			default:				librad_log("Internal sanity check failed");				return NULL;		}	}	attr |= vendor << 16;	/*	 *	We've now parsed the attribute properly, Let's create	 *	it.  This next stop also looks the attribute up in the	 *	dictionary, and creates the appropriate type for it.	 */	if ((vp = paircreate(attr, PW_TYPE_OCTETS)) == NULL) {		librad_log("out of memory");

⌨️ 快捷键说明

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