M_COPY_HDR(m, m0); m_tag_init(m0); m0->m_flags &= ~M_PKTHDR;
x25_ifoutput(ifp, m0, dst, rt)	struct ifnet   *ifp;	struct mbuf    *m0;	struct sockaddr *dst;	register struct rtentry *rt;{	register struct mbuf *m = m0;	register struct llinfo_x25 *lx;	struct pklcd   *lcp;	int             error = 0;	int             plen;	for (plen = 0; m; m = m->m_next)		plen += m->m_len;	m = m0;	if ((ifp->if_flags & IFF_UP) == 0)		senderr(ENETDOWN);	while (rt == 0 || (rt->rt_flags & RTF_GATEWAY)) {		if (rt) {			if (rt->rt_llinfo) {				rt = (struct rtentry *) rt->rt_llinfo;				continue;			}			dst = rt->rt_gateway;		}		if ((rt = rtalloc1(dst, 1)) == 0)			senderr(EHOSTUNREACH);		rt->rt_refcnt--;	}	/*	 * Sanity checks.	 */	if ((rt->rt_ifp != ifp) ||	    (rt->rt_flags & (RTF_CLONING | RTF_GATEWAY)) ||	    ((lx = (struct llinfo_x25 *) rt->rt_llinfo) == 0)) {		senderr(ENETUNREACH);	}	if ((m->m_flags & M_PKTHDR) == 0) {		if_x25stats.ifx_nophdr++;		m = m_gethdr(M_NOWAIT, MT_HEADER);		if (m == 0)			senderr(ENOBUFS);		m->m_pkthdr.len = plen;		m->m_next = m0;	}	if (plen != m->m_pkthdr.len) {		if_x25stats.ifx_wrongplen++;		m->m_pkthdr.len = plen;	}next_circuit:	lcp = lx->lx_lcd;	if (lcp == 0) {		lx->lx_lcd = lcp = pk_attach((struct socket *) 0);		if (lcp == 0)			senderr(ENOBUFS);		lcp->lcd_upper = x25_connect_callback;		lcp->lcd_upnext = (caddr_t) lx;		lcp->lcd_packetsize = lx->lx_ia->ia_xc.xc_psize;		lcp->lcd_flags = X25_MBS_HOLD;	}	switch (lcp->lcd_state) {	case READY:		if (dst->sa_family == AF_INET &&		    ifp->if_type == IFT_X25DDN &&		    rt->rt_gateway->sa_family != AF_CCITT)			x25_ddnip_to_ccitt(dst, rt);		if (rt->rt_gateway->sa_family != AF_CCITT) {			if ((rt->rt_flags & RTF_XRESOLVE) == 0)				senderr(EHOSTUNREACH);		} else if (x25_autoconnect)			error = pk_connect(lcp,				    (struct sockaddr_x25 *) rt->rt_gateway);		if (error)			senderr(error);		/* FALLTHROUGH */	case SENT_CALL:	case DATA_TRANSFER:		if (sbspace(&lcp->lcd_sb) < 0) {			lx = lx->lx_list.le_next;			if (lx->lx_rt != rt)				senderr(ENOSPC);			goto next_circuit;		}		if (lx->lx_ia)			lcp->lcd_dg_timer =				lx->lx_ia->ia_xc.xc_dg_idletimo;		pk_send(m, lcp);		break;	default:		/*		 * We count on the timer routine to close idle		 * connections, if there are not enough circuits to go		 * around.		 *		 * So throw away data for now.		 * After we get it all working, we'll rewrite to handle		 * actively closing connections (other than by timers),		 * when circuits get tight.		 *		 * In the DDN case, the imp itself closes connections		 * under heavy load.		 */		error = ENOBUFS;bad:		if (m)			m_freem(m);	}	return (error);}