FreeBSD/sys/netinet/sctp_asconf.c
/* FIX ME: need to verify return result for v6 address type if v6 disabled */
/*
 * checks to see if a specific address is in the initack address list returns
 * 1 if found, 0 if not
 */
FIX ME: need to verify return result for v6 address type if v6 disabled
checks to see if a specific address is in the initack address list returns
1 if found, 0 if not
FIX ME : need to verify return result for v6 address type if v6 disabled checks to see if a specific address is in the initack address list returns 1 if found 0 if not
static uint32_t
sctp_addr_in_initack(struct mbuf *m, uint32_t offset, uint32_t length, struct sockaddr *sa)
{
	struct sctp_paramhdr tmp_param, *ph;
	uint16_t plen, ptype;
#ifdef INET
	struct sockaddr_in *sin;
	struct sctp_ipv4addr_param *a4p;
	struct sctp_ipv6addr_param addr4_store;
#endif
#ifdef INET6
	struct sockaddr_in6 *sin6;
	struct sctp_ipv6addr_param *a6p;
	struct sctp_ipv6addr_param addr6_store;
	struct sockaddr_in6 sin6_tmp;
#endif
	switch (sa->sa_family) {
#ifdef INET
	case AF_INET:
		break;
#endif
#ifdef INET6
	case AF_INET6:
		break;
#endif
	default:
		return (0);
	}
	SCTPDBG(SCTP_DEBUG_ASCONF2, "find_initack_addr: starting search for ");
	SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, sa);
	length += offset;
	if ((offset + sizeof(struct sctp_paramhdr)) > length) {
		SCTPDBG(SCTP_DEBUG_ASCONF1,
		    "find_initack_addr: invalid offset?\n");
		return (0);
	}
	ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset,
	    sizeof(struct sctp_paramhdr), (uint8_t *) & tmp_param);
	while (ph != NULL) {
		ptype = ntohs(ph->param_type);
		plen = ntohs(ph->param_length);
		switch (ptype) {
#ifdef INET6
		case SCTP_IPV6_ADDRESS:
			if (sa->sa_family == AF_INET6) {
				if (plen != sizeof(struct sctp_ipv6addr_param)) {
					break;
				}
				a6p = (struct sctp_ipv6addr_param *)
				    sctp_m_getptr(m, offset,
				    sizeof(struct sctp_ipv6addr_param),
				    (uint8_t *) & addr6_store);
				if (a6p == NULL) {
					return (0);
				}
				sin6 = (struct sockaddr_in6 *)sa;
				if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr)) {
					memcpy(&sin6_tmp, sin6,
					    sizeof(struct sockaddr_in6));
					sin6 = &sin6_tmp;
					in6_clearscope(&sin6->sin6_addr);
				}
				if (memcmp(&sin6->sin6_addr, a6p->addr,
				    sizeof(struct in6_addr)) == 0) {
					return (1);
				}
			}
			break;
#endif				
#ifdef INET
		case SCTP_IPV4_ADDRESS:
			if (sa->sa_family == AF_INET) {
				if (plen != sizeof(struct sctp_ipv4addr_param)) {
					break;
				}
				a4p = (struct sctp_ipv4addr_param *)
				    sctp_m_getptr(m, offset,
				    sizeof(struct sctp_ipv4addr_param),
				    (uint8_t *) & addr4_store);
				if (a4p == NULL) {
					return (0);
				}
				sin = (struct sockaddr_in *)sa;
				if (sin->sin_addr.s_addr == a4p->addr) {
					return (1);
				}
			}
			break;
#endif
		default:
			break;
		}
		offset += SCTP_SIZE32(plen);
		if (offset + sizeof(struct sctp_paramhdr) > length) {
			return (0);
		}
		ph = (struct sctp_paramhdr *)
		    sctp_m_getptr(m, offset, sizeof(struct sctp_paramhdr),
		    (uint8_t *) & tmp_param);
	}			
	return (0);
}
static uint32_t sctp_addr_in_initack ( struct mbuf * m , uint32_t offset , uint32_t length , struct sockaddr * sa ) { struct sctp_paramhdr tmp_param , * ph ; uint16_t plen , ptype ; #ifdef INET struct sockaddr_in * sin ; struct sctp_ipv4addr_param * a4p ; struct sctp_ipv6addr_param addr4_store ; #endif #ifdef INET6 struct sockaddr_in6 * sin6 ; struct sctp_ipv6addr_param * a6p ; struct sctp_ipv6addr_param addr6_store ; struct sockaddr_in6 sin6_tmp ; #endif switch ( sa -> sa_family ) { #ifdef INET case AF_INET : break ; #endif #ifdef INET6 case AF_INET6 : break ; #endif default : return ( 0 ) ; } SCTPDBG ( SCTP_DEBUG_ASCONF2 , " " ) ; SCTPDBG_ADDR ( SCTP_DEBUG_ASCONF2 , sa ) ; length += offset ; if ( ( offset + sizeof ( struct sctp_paramhdr ) ) > length ) { SCTPDBG ( SCTP_DEBUG_ASCONF1 , " \n " ) ; return ( 0 ) ; } ph = ( struct sctp_paramhdr * ) sctp_m_getptr ( m , offset , sizeof ( struct sctp_paramhdr ) , ( uint8_t * ) & tmp_param ) ; while ( ph != NULL ) { ptype = ntohs ( ph -> param_type ) ; plen = ntohs ( ph -> param_length ) ; switch ( ptype ) { #ifdef INET6 case SCTP_IPV6_ADDRESS : if ( sa -> sa_family == AF_INET6 ) { if ( plen != sizeof ( struct sctp_ipv6addr_param ) ) { break ; } a6p = ( struct sctp_ipv6addr_param * ) sctp_m_getptr ( m , offset , sizeof ( struct sctp_ipv6addr_param ) , ( uint8_t * ) & addr6_store ) ; if ( a6p == NULL ) { return ( 0 ) ; } sin6 = ( struct sockaddr_in6 * ) sa ; if ( IN6_IS_SCOPE_LINKLOCAL ( & sin6 -> sin6_addr ) ) { memcpy ( & sin6_tmp , sin6 , sizeof ( struct sockaddr_in6 ) ) ; sin6 = & sin6_tmp ; in6_clearscope ( & sin6 -> sin6_addr ) ; } if ( memcmp ( & sin6 -> sin6_addr , a6p -> addr , sizeof ( struct in6_addr ) ) == 0 ) { return ( 1 ) ; } } break ; #endif #ifdef INET case SCTP_IPV4_ADDRESS : if ( sa -> sa_family == AF_INET ) { if ( plen != sizeof ( struct sctp_ipv4addr_param ) ) { break ; } a4p = ( struct sctp_ipv4addr_param * ) sctp_m_getptr ( m , offset , sizeof ( struct sctp_ipv4addr_param ) , ( uint8_t * ) & addr4_store ) ; if ( a4p == NULL ) { return ( 0 ) ; } sin = ( struct sockaddr_in * ) sa ; if ( sin -> sin_addr . s_addr == a4p -> addr ) { return ( 1 ) ; } } break ; #endif default : break ; } offset += SCTP_SIZE32 ( plen ) ; if ( offset + sizeof ( struct sctp_paramhdr ) > length ) { return ( 0 ) ; } ph = ( struct sctp_paramhdr * ) sctp_m_getptr ( m , offset , sizeof ( struct sctp_paramhdr ) , ( uint8_t * ) & tmp_param ) ; } return ( 0 ) ; }
FIX ME: need to verify return result for v6 address type if v6 disabled
 checks to see if a specific address is in the initack address list returns
 1 if found, 0 if not
FIX ME : need to verify return result for v6 address type if v6 disabled checks to see if a specific address is in the initack address list returns 1 if found 0 if not
/* convert to upper bound */ /* go through the addresses in the init-ack */ /* get the entire IPv6 address param */ /* get the entire IPv6 address param */ /* create a copy and clear scope */ /* found it */ /* INET6 */ /* get the entire IPv4 address param */ /* found it */ /* get next parameter */ /* while */ /* not found! */