FreeBSD/sys/netinet6/in6_ifattach.c
/*
 * compute NI group address, based on the current hostname setting.
 * see RFC 4620.
 *
 * when ifp == NULL, the caller is responsible for filling scopeid.
 *
 * If oldmcprefix == 1, FF02:0:0:0:0:2::/96 is used for NI group address
 * while it is FF02:0:0:0:0:2:FF00::/104 in RFC 4620. 
 */
compute NI group address, based on the current hostname setting.

when ifp == NULL, the caller is responsible for filling scopeid.


compute NI group address based on the current hostname setting . when ifp == NULL the caller is responsible for filling scopeid .
static int
in6_nigroup0(struct ifnet *ifp, const char *name, int namelen,
    struct in6_addr *in6, int oldmcprefix)
{
	struct prison *pr;
	const char *p;
	u_char *q;
	MD5_CTX ctxt;
	u_int8_t digest[16];
	char l;
	char n[64];	
	if (!name && namelen == -1) {
		pr = curthread->td_ucred->cr_prison;
		mtx_lock(&pr->pr_mtx);
		name = pr->pr_hostname;
		namelen = strlen(name);
	} else
		pr = NULL;
	if (!name || !namelen) {
		if (pr != NULL)
			mtx_unlock(&pr->pr_mtx);
		return -1;
	}
	p = name;
	while (p && *p && *p != '.' && p - name < namelen)
		p++;
	if (p == name || p - name > sizeof(n) - 1) {
		if (pr != NULL)
			mtx_unlock(&pr->pr_mtx);
		return -1;	
	}
	l = p - name;
	strncpy(n, name, l);
	if (pr != NULL)
		mtx_unlock(&pr->pr_mtx);
	n[(int)l] = '\0';
	for (q = n; *q; q++) {
		if ('A' <= *q && *q <= 'Z')
			*q = *q - 'A' + 'a';
	}
	bzero(&ctxt, sizeof(ctxt));
	MD5Init(&ctxt);
	MD5Update(&ctxt, &l, sizeof(l));
	MD5Update(&ctxt, n, l);
	MD5Final(digest, &ctxt);
	bzero(in6, sizeof(*in6));
	in6->s6_addr16[0] = IPV6_ADDR_INT16_MLL;
	in6->s6_addr8[11] = 2;
	if (oldmcprefix == 0) {
		in6->s6_addr8[12] = 0xff;
		bcopy(digest, &in6->s6_addr8[13], 3);
	} else {
		bcopy(digest, &in6->s6_addr32[3], sizeof(in6->s6_addr32[3]));
	}
	if (in6_setscope(in6, ifp, NULL))
		return (-1); 
	return 0;
}
static int in6_nigroup0 ( struct ifnet * ifp , const char * name , int namelen , struct in6_addr * in6 , int oldmcprefix ) { struct prison * pr ; const char * p ; u_char * q ; MD5_CTX ctxt ; u_int8_t digest [ 16 ] ; char l ; char n [ 64 ] ; if ( ! name && namelen == -1 ) { pr = curthread -> td_ucred -> cr_prison ; mtx_lock ( & pr -> pr_mtx ) ; name = pr -> pr_hostname ; namelen = strlen ( name ) ; } else pr = NULL ; if ( ! name || ! namelen ) { if ( pr != NULL ) mtx_unlock ( & pr -> pr_mtx ) ; return -1 ; } p = name ; while ( p && * p && * p != ' ' && p - name < namelen ) p ++ ; if ( p == name || p - name > sizeof ( n ) - 1 ) { if ( pr != NULL ) mtx_unlock ( & pr -> pr_mtx ) ; return -1 ; } l = p - name ; strncpy ( n , name , l ) ; if ( pr != NULL ) mtx_unlock ( & pr -> pr_mtx ) ; n [ ( int ) l ] = ' \0 ' ; for ( q = n ; * q ; q ++ ) { if ( ' ' <= * q && * q <= ' ' ) * q = * q - ' ' + ' ' ; } bzero ( & ctxt , sizeof ( ctxt ) ) ; MD5Init ( & ctxt ) ; MD5Update ( & ctxt , & l , sizeof ( l ) ) ; MD5Update ( & ctxt , n , l ) ; MD5Final ( digest , & ctxt ) ; bzero ( in6 , sizeof ( * in6 ) ) ; in6 -> s6_addr16 [ 0 ] = IPV6_ADDR_INT16_MLL ; in6 -> s6_addr8 [ 11 ] = 2 ; if ( oldmcprefix == 0 ) { in6 -> s6_addr8 [ 12 ] = 0xff ; bcopy ( digest , & in6 -> s6_addr8 [ 13 ] , 3 ) ; } else { bcopy ( digest , & in6 -> s6_addr32 [ 3 ] , sizeof ( in6 -> s6_addr32 [ 3 ] ) ) ; } if ( in6_setscope ( in6 , ifp , NULL ) ) return ( -1 ) ; return 0 ; }
compute NI group address, based on the current hostname setting.
compute NI group address based on the current hostname setting .
/* a single label must not exceed 63 chars */ /*
	 * If no name is given and namelen is -1,
	 * we try to do the hostname lookup ourselves.
	 */ /* label too long */ /* generate 16 bytes of pseudo-random value. */ /* Copy the first 24 bits of 128-bit hash into the address. */ /* Copy the first 32 bits of 128-bit hash into the address. */ /* XXX: should not fail */