FreeBSD/tools/tools/cxgbetool/cxgbetool.c
/*
 * Parse an argument sub-vector as a { <parameter name> <addr>[/<mask>] }
 * ordered tuple.  If the parameter name in the argument sub-vector does not
 * match the passed in parameter name, then a zero is returned for the
 * function and no parsing is performed.  If there is a match, then the value
 * and optional mask are parsed and returned in the provided return value
 * pointers.  If no optional mask is specified, then a default mask of all 1s
 * will be returned.
 *
 * The value return parameter "afp" is used to specify the expected address
 * family -- IPv4 or IPv6 -- of the address[/mask] and return its actual
 * format.  A passed in value of AF_UNSPEC indicates that either IPv4 or IPv6
 * is acceptable; AF_INET means that only IPv4 addresses are acceptable; and
 * AF_INET6 means that only IPv6 are acceptable.  AF_INET is returned for IPv4
 * and AF_INET6 for IPv6 addresses, respectively.  IPv4 address/mask pairs are
 * returned in the first four bytes of the address and mask return values with
 * the address A.B.C.D returned with { A, B, C, D } returned in addresses { 0,
 * 1, 2, 3}, respectively.
 *
 * An error in parsing the value[:mask] will result in an error message and
 * program termination.
 */
Parse an argument sub-vector as a {  [/] }
ordered tuple.  If the parameter name in the argument sub-vector does not
match the passed in parameter name, then a zero is returned for the
function and no parsing is performed.  If there is a match, then the value
and optional mask are parsed and returned in the provided return value
pointers.  If no optional mask is specified, then a default mask of all 1s
will be returned.

The value return parameter "afp" is used to specify the expected address
family -- IPv4 or IPv6 -- of the address[/mask] and return its actual
format.  A passed in value of AF_UNSPEC indicates that either IPv4 or IPv6
is acceptable; AF_INET means that only IPv4 addresses are acceptable; and
AF_INET6 means that only IPv6 are acceptable.

An error in parsing the value[:mask] will result in an error message and
program termination.
Parse an argument sub - vector as a { [ / ] } ordered tuple . If the parameter name in the argument sub - vector does not match the passed in parameter name then a zero is returned for the function and no parsing is performed . If there is a match then the value and optional mask are parsed and returned in the provided return value pointers . If no optional mask is specified then a default mask of all 1s will be returned . The value return parameter " afp " is used to specify the expected address family -- IPv4 or IPv6 -- of the address [ / mask ] and return its actual format . A passed in value of AF_UNSPEC indicates that either IPv4 or IPv6 is acceptable ; AF_INET means that only IPv4 addresses are acceptable ; and AF_INET6 means that only IPv6 are acceptable . An error in parsing the value [ : mask ] will result in an error message and program termination .
static int
parse_ipaddr(const char *param, const char *args[], int *afp, uint8_t addr[],
    uint8_t mask[])
{
	const char *colon, *afn;
	char *slash;
	uint8_t *m;
	int af, ret;
	unsigned int masksize;
	if (strcmp(param, args[0]) != 0)
		return (EINVAL);
	colon = strchr(args[1], ':');
	if (!colon) {
		afn = "IPv4";
		af = AF_INET;
		masksize = 32;
	} else {
		afn = "IPv6";
		af = AF_INET6;
		masksize = 128;
	}
	if (*afp == AF_UNSPEC)
		*afp = af;
	else if (*afp != af) {
		warnx("address %s is not of expected family %s",
		    args[1], *afp == AF_INET ? "IP" : "IPv6");
		return (EINVAL);
	}
	slash = strchr(args[1], '/');
	if (slash)
		*slash = 0;
	ret = inet_pton(af, args[1], addr);
	if (slash)
		*slash = '/';
	if (ret <= 0) {
		warnx("Cannot parse %s %s address %s", param, afn, args[1]);
		return (EINVAL);
	}
	if (slash) {
		char *p;
		unsigned int prefix = strtoul(slash + 1, &p, 10);
		if (p == slash + 1) {
			warnx("missing address prefix for %s", param);
			return (EINVAL);
		}
		if (*p) {
			warnx("%s is not a valid address prefix", slash + 1);
			return (EINVAL);
		}
		if (prefix > masksize) {
			warnx("prefix %u is too long for an %s address",
			     prefix, afn);
			return (EINVAL);
		}
		memset(mask, 0, masksize / 8);
		masksize = prefix;
	}
	for (m = mask; masksize >= 8; m++, masksize -= 8)
		*m = ~0;
	if (masksize)
		*m = ~0 << (8 - masksize);
	return (0);
}
static int parse_ipaddr ( const char * param , const char * args [ ] , int * afp , uint8_t addr [ ] , uint8_t mask [ ] ) { const char * colon , * afn ; char * slash ; uint8_t * m ; int af , ret ; unsigned int masksize ; if ( strcmp ( param , args [ 0 ] ) != 0 ) return ( EINVAL ) ; colon = strchr ( args [ 1 ] , ' ' ) ; if ( ! colon ) { afn = " " ; af = AF_INET ; masksize = 32 ; } else { afn = " " ; af = AF_INET6 ; masksize = 128 ; } if ( * afp == AF_UNSPEC ) * afp = af ; else if ( * afp != af ) { warnx ( " " , args [ 1 ] , * afp == AF_INET ? " " : " " ) ; return ( EINVAL ) ; } slash = strchr ( args [ 1 ] , ' ' ) ; if ( slash ) * slash = 0 ; ret = inet_pton ( af , args [ 1 ] , addr ) ; if ( slash ) * slash = ' ' ; if ( ret <= 0 ) { warnx ( " " , param , afn , args [ 1 ] ) ; return ( EINVAL ) ; } if ( slash ) { char * p ; unsigned int prefix = strtoul ( slash + 1 , & p , 10 ) ; if ( p == slash + 1 ) { warnx ( " " , param ) ; return ( EINVAL ) ; } if ( * p ) { warnx ( " " , slash + 1 ) ; return ( EINVAL ) ; } if ( prefix > masksize ) { warnx ( " " , prefix , afn ) ; return ( EINVAL ) ; } memset ( mask , 0 , masksize / 8 ) ; masksize = prefix ; } for ( m = mask ; masksize >= 8 ; m ++ , masksize -= 8 ) * m = ~ 0 ; if ( masksize ) * m = ~ 0 << ( 8 - masksize ) ; return ( 0 ) ; }
Parse an argument sub-vector as a { <parameter name> <addr>[/<mask>] }
 ordered tuple.
Parse an argument sub - vector as a { <parameter name > <addr > [ / <mask > ] } ordered tuple .
/*
	 * Is this our parameter?
	 */ /*
	 * Fundamental IPv4 versus IPv6 selection.
	 */ /*
	 * Parse address (temporarily stripping off any "/mask"
	 * specification).
	 */ /*
	 * Parse optional mask specification.
	 */ /*
	 * Fill in mask.
	 */