FreeBSD/usr.sbin/mtest/mtest.c
/*
 * Parse join/leave/allow/block arguments, given:
 *  str1: group (as AF_INET or AF_INET6 printable)
 *  str2: ifname
 *  str3: optional source address (may be NULL).
 *   This argument must have the same parsed address family as str1.
 * Return the ifindex of ifname, or 0 if any parse element failed.
 */
Parse join/leave/allow/block arguments, given:
str1: group (as AF_INET or AF_INET6 printable)
str2: ifname
str3: optional source address (may be NULL).
This argument must have the same parsed address family as str1.
Return the ifindex of ifname, or 0 if any parse element failed.
Parse join / leave / allow / block arguments given : str1 : group ( as AF_INET or AF_INET6 printable ) str2 : ifname str3 : optional source address ( may be NULL ) . This argument must have the same parsed address family as str1 . Return the ifindex of ifname or 0 if any parse element failed .
static uint32_t
parse_cmd_args(sockunion_t *psu, sockunion_t *psu2,
    const char *str1, const char *str2, const char *str3)
{
	struct addrinfo		 hints;
	struct addrinfo		*res;
	uint32_t		 ifindex;
	int			 af, error;
	assert(psu != NULL);
	assert(str1 != NULL);
	assert(str2 != NULL);
	af = AF_UNSPEC;
	ifindex = if_nametoindex(str2);
	if (ifindex == 0)
		return (0);
	memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_flags = AI_NUMERICHOST;
	hints.ai_family = PF_UNSPEC;
	hints.ai_socktype = SOCK_DGRAM;
	memset(psu, 0, sizeof(sockunion_t));
	psu->sa.sa_family = AF_UNSPEC;
	error = getaddrinfo(str1, "0", &hints, &res);
	if (error) {
		warnx("getaddrinfo: %s", gai_strerror(error));
		return (0);
	}
	assert(res != NULL);
	af = res->ai_family;
	memcpy(psu, res->ai_addr, res->ai_addrlen);
	freeaddrinfo(res);
	if (psu2 != NULL && str3 != NULL && *str3 != '\0') {
		memset(psu2, 0, sizeof(sockunion_t));
		psu2->sa.sa_family = AF_UNSPEC;
		hints.ai_family = af;
		error = getaddrinfo(str3, "0", &hints, &res);
		if (error) {
			warnx("getaddrinfo: %s", gai_strerror(error));
			ifindex = 0;
		} else {
			if (af != res->ai_family) {
				errno = EINVAL; 
				ifindex = 0;
			}
			memcpy(psu2, res->ai_addr, res->ai_addrlen);
			freeaddrinfo(res);
		}
	}
	return (ifindex);
}
static uint32_t parse_cmd_args ( sockunion_t * psu , sockunion_t * psu2 , const char * str1 , const char * str2 , const char * str3 ) { struct addrinfo hints ; struct addrinfo * res ; uint32_t ifindex ; int af , error ; assert ( psu != NULL ) ; assert ( str1 != NULL ) ; assert ( str2 != NULL ) ; af = AF_UNSPEC ; ifindex = if_nametoindex ( str2 ) ; if ( ifindex == 0 ) return ( 0 ) ; memset ( & hints , 0 , sizeof ( struct addrinfo ) ) ; hints . ai_flags = AI_NUMERICHOST ; hints . ai_family = PF_UNSPEC ; hints . ai_socktype = SOCK_DGRAM ; memset ( psu , 0 , sizeof ( sockunion_t ) ) ; psu -> sa . sa_family = AF_UNSPEC ; error = getaddrinfo ( str1 , " " , & hints , & res ) ; if ( error ) { warnx ( " " , gai_strerror ( error ) ) ; return ( 0 ) ; } assert ( res != NULL ) ; af = res -> ai_family ; memcpy ( psu , res -> ai_addr , res -> ai_addrlen ) ; freeaddrinfo ( res ) ; if ( psu2 != NULL && str3 != NULL && * str3 != ' \0 ' ) { memset ( psu2 , 0 , sizeof ( sockunion_t ) ) ; psu2 -> sa . sa_family = AF_UNSPEC ; hints . ai_family = af ; error = getaddrinfo ( str3 , " " , & hints , & res ) ; if ( error ) { warnx ( " " , gai_strerror ( error ) ) ; ifindex = 0 ; } else { if ( af != res -> ai_family ) { errno = EINVAL ; ifindex = 0 ; } memcpy ( psu2 , res -> ai_addr , res -> ai_addrlen ) ; freeaddrinfo ( res ) ; } } return ( ifindex ) ; }
Parse join/leave/allow/block arguments, given:
  str1: group (as AF_INET or AF_INET6 printable)
  str2: ifname
  str3: optional source address (may be NULL).
Parse join / leave / allow / block arguments given : str1 : group ( as AF_INET or AF_INET6 printable ) str2 : ifname str3 : optional source address ( may be NULL ) .
/* sscanf() may pass the empty string. */ /* look for following address family; str3 is *optional*. */ /* XXX */