+ int type, dest, s;
+ register struct mbuf *m = m0;
+ register struct en_header *en;
+ register int off;
+
+COUNT(ENOUTPUT);
+ switch (dst->sa_family) {
+
+#ifdef INET
+ case AF_INET:
+ dest = ((struct sockaddr_in *)dst)->sin_addr.s_addr >> 24;
+ off = ntohs((u_short)mtod(m, struct ip *)->ip_len) - m->m_len;
+ if (off > 0 && (off & 0x1ff) == 0 &&
+ m->m_off >= MMINOFF + sizeof (u_short)) {
+ type = ENPUP_TRAIL + (off>>9);
+ m->m_off -= sizeof (u_short);
+ m->m_len += sizeof (u_short);
+ *mtod(m, u_short *) = ENPUP_IPTYPE;
+ goto gottrailertype;
+ }
+ type = ENPUP_IPTYPE;
+ off = 0;
+ goto gottype;
+#endif
+#ifdef PUP
+ case AF_PUP:
+ dest = ((struct sockaddr_pup *)dst)->spup_addr.pp_host;
+ off = mtod(m, struct pup_header *)->pup_length - m->m_len;
+ if (off > 0 && (off & 0x1ff) == 0 &&
+ m->m_off >= MMINOFF + sizeof (u_short)) {
+ type = ENPUP_TRAIL + (off>>9);
+ m->m_off -= sizeof (u_short);
+ m->m_len += sizeof (u_short);
+ *mtod(m, u_short *) = ENPUP_PUPTYPE;
+ goto gottrailertype;
+ }
+ type = ENPUP_PUPTYPE;
+ off = 0;
+ goto gottype;
+#endif
+
+ default:
+ printf("en%d: can't handle af%d\n", ifp->if_unit,
+ dst->sa_family);
+ m_freem(m0);
+ return (0);
+ }
+
+gottrailertype:
+ /*
+ * Packet to be sent as trailer: move first packet
+ * (control information) to end of chain.
+ */
+ while (m->m_next)
+ m = m->m_next;
+ m->m_next = m0;
+ m = m0->m_next;
+ m0->m_next = 0;
+ m0 = m;
+
+gottype:
+ /*
+ * Add local net header. If no space in first mbuf,
+ * allocate another.
+ */
+ if (m->m_off > MMAXOFF ||
+ MMINOFF + sizeof (struct en_header) > m->m_off) {
+ m = m_get(M_DONTWAIT);
+ if (m == 0) {
+ m_freem(m0);
+ return (0);
+ }
+ m->m_next = m0;
+ m->m_off = MMINOFF;
+ m->m_len = sizeof (struct en_header);
+ } else {
+ m->m_off -= sizeof (struct en_header);
+ m->m_len += sizeof (struct en_header);
+ }
+ en = mtod(m, struct en_header *);
+ en->en_shost = ifp->if_host[0];
+ en->en_dhost = dest;
+ en->en_type = type;