( ntohs( to.sat_addr.s_net ) < ntohs( 0xff00 ) || ntohs( to.sat_addr.s_net ) > ntohs( 0xfffe ))) {
( ntohs( to.sat_addr.s_net ) < 0xff00 || ntohs( to.sat_addr.s_net ) > 0xfffe)) {
ddp_input( m, ifp, elh, phase )    struct mbuf		*m;    struct ifnet	*ifp;    struct elaphdr	*elh;    int			phase;{    struct sockaddr_at	from, to;    struct ddpshdr	*dsh, ddps;    struct at_ifaddr	*aa;    struct ddpehdr	*deh, ddpe;    struct ddpcb	*ddp;    int			dlen, mlen;    u_int16_t		cksum;    bzero( (caddr_t)&from, sizeof( struct sockaddr_at ));    if ( elh ) {	ddpstat.ddps_short++;	if ( m->m_len < sizeof( struct ddpshdr ) &&		(( m = m_pullup( m, sizeof( struct ddpshdr ))) == 0 )) {	    ddpstat.ddps_tooshort++;	    return;	}	dsh = mtod( m, struct ddpshdr *);	bcopy( (caddr_t)dsh, (caddr_t)&ddps, sizeof( struct ddpshdr ));	ddps.dsh_bytes = ntohl( ddps.dsh_bytes );	dlen = ddps.dsh_len;	to.sat_addr.s_net = 0;	to.sat_addr.s_node = elh->el_dnode;	to.sat_port = ddps.dsh_dport;	from.sat_addr.s_net = 0;	from.sat_addr.s_node = elh->el_snode;	from.sat_port = ddps.dsh_sport;	for ( aa = at_ifaddr; aa; aa = aa->aa_next ) {	    if ( aa->aa_ifp == ifp && ( aa->aa_flags & AFA_PHASE2 ) == 0 &&		    ( AA_SAT( aa )->sat_addr.s_node == to.sat_addr.s_node ||		    to.sat_addr.s_node == ATADDR_BCAST )) {		break;	    }	}	if ( aa == NULL ) {	    m_freem( m );	    return;	}    } else {	ddpstat.ddps_long++;	if ( m->m_len < sizeof( struct ddpehdr ) &&		(( m = m_pullup( m, sizeof( struct ddpehdr ))) == 0 )) {	    ddpstat.ddps_tooshort++;	    return;	}	deh = mtod( m, struct ddpehdr *);	bcopy( (caddr_t)deh, (caddr_t)&ddpe, sizeof( struct ddpehdr ));	ddpe.deh_bytes = ntohl( ddpe.deh_bytes );	dlen = ddpe.deh_len;	if (( cksum = ddpe.deh_sum ) == 0 ) {	    ddpstat.ddps_nosum++;	}	from.sat_addr.s_net = ddpe.deh_snet;	from.sat_addr.s_node = ddpe.deh_snode;	from.sat_port = ddpe.deh_sport;	to.sat_addr.s_net = ddpe.deh_dnet;	to.sat_addr.s_node = ddpe.deh_dnode;	to.sat_port = ddpe.deh_dport;	if ( to.sat_addr.s_net == 0 ) {	    for ( aa = at_ifaddr; aa; aa = aa->aa_next ) {		if ( phase == 1 && ( aa->aa_flags & AFA_PHASE2 )) {		    continue;		}		if ( phase == 2 && ( aa->aa_flags & AFA_PHASE2 ) == 0 ) {		    continue;		}		if ( aa->aa_ifp == ifp &&			( AA_SAT( aa )->sat_addr.s_node == to.sat_addr.s_node ||			to.sat_addr.s_node == ATADDR_BCAST ||			( ifp->if_flags & IFF_LOOPBACK ))) {		    break;		}	    }	} else {	    for ( aa = at_ifaddr; aa; aa = aa->aa_next ) {		if ( to.sat_addr.s_net == aa->aa_firstnet &&			to.sat_addr.s_node == 0 ) {		    break;		}		if (( ntohs( to.sat_addr.s_net ) < ntohs( aa->aa_firstnet ) ||			ntohs( to.sat_addr.s_net ) > ntohs( aa->aa_lastnet )) &&			( ntohs( to.sat_addr.s_net ) < ntohs( 0xff00 ) ||			ntohs( to.sat_addr.s_net ) > ntohs( 0xfffe ))) {		    continue;		}		if ( to.sat_addr.s_node != AA_SAT( aa )->sat_addr.s_node &&			to.sat_addr.s_node != ATADDR_BCAST ) {		    continue;		}		break;	    }	}    }    /*     * Adjust the length, removing any padding that may have been added     * at a link layer.  We do this before we attempt to forward a packet,     * possibly on a different media.     */    mlen = m->m_pkthdr.len;    if ( mlen < dlen ) {	ddpstat.ddps_toosmall++;	m_freem( m );	return;    }    if ( mlen > dlen ) {	m_adj( m, dlen - mlen );    }    /*     * XXX Should we deliver broadcasts locally, also, or rely on the     * link layer to give us a copy?  For the moment, the latter.     */    if ( aa == NULL || ( to.sat_addr.s_node == ATADDR_BCAST &&	    aa->aa_ifp != ifp && ( ifp->if_flags & IFF_LOOPBACK ) == 0 )) {	if ( ddp_forward == 0 ) {	    m_freem( m );	    return;	}	if ( forwro.ro_rt && ( satosat( &forwro.ro_dst )->sat_addr.s_net !=		to.sat_addr.s_net ||		satosat( &forwro.ro_dst )->sat_addr.s_node !=		to.sat_addr.s_node )) {	    RTFREE( forwro.ro_rt );	    forwro.ro_rt = (struct rtentry *)0;	}	if ( forwro.ro_rt == (struct rtentry *)0 ||	     forwro.ro_rt->rt_ifp == (struct ifnet *)0 ) {	    forwro.ro_dst.sa_len = sizeof( struct sockaddr_at );	    forwro.ro_dst.sa_family = AF_APPLETALK;	    satosat( &forwro.ro_dst )->sat_addr.s_net = to.sat_addr.s_net;	    satosat( &forwro.ro_dst )->sat_addr.s_node = to.sat_addr.s_node;	    rtalloc( &forwro );	}	if ( to.sat_addr.s_net != satosat( &forwro.ro_dst )->sat_addr.s_net &&		ddpe.deh_hops == DDP_MAXHOPS ) {	    m_freem( m );	    return;	}	/* XXX FreeBSD doesn't have this */	if ( ddp_firewall &&		( forwro.ro_rt == NULL || ( forwro.ro_rt->rt_ifp != ifp &&		forwro.ro_rt->rt_ifp != at_ifaddr->aa_ifp ))) {	    m_freem( m );	    return;	}	ddpe.deh_hops++;	ddpe.deh_bytes = htonl( ddpe.deh_bytes );	bcopy( (caddr_t)&ddpe, (caddr_t)deh, sizeof( u_int16_t ));	if ( ddp_route( m, &forwro )) {	    ddpstat.ddps_cantforward++;	} else {	    ddpstat.ddps_forward++;	}	return;    }    from.sat_len = sizeof( struct sockaddr_at );    from.sat_family = AF_APPLETALK;    if ( elh ) {	m_adj( m, sizeof( struct ddpshdr ));    } else {	/*	 * XXX I've always hated this about the TCP checksum, and here it	 * is again. ddp_cksum determines whether we compute checksums on	 * outgoing packets. Why is it used to disable checkumming on	 * incoming packets as well? If the remote node went to the	 * trouble of computing the checksum, shouldn't we check it?	 */	if ( ddp_cksum && cksum && cksum != at_cksum( m, sizeof( int ))) {	    ddpstat.ddps_badsum++;	    m_freem( m );	    return;	}	m_adj( m, sizeof( struct ddpehdr ));    }    if (( ddp = ddp_search( &from, &to, aa )) == NULL ) {	m_freem( m );	return;    }    if ( sbappendaddr( &ddp->ddp_socket->so_rcv, (struct sockaddr *)&from,	    m, (struct mbuf *)0 ) == 0 ) {	ddpstat.ddps_nosockspace++;	m_freem( m );	return;    }    sorwakeup( ddp->ddp_socket );}