- register struct enp_softc *es = &enp_softc[ifp->if_unit];
- register struct mbuf *m = m0;
- register struct ether_header *enp;
- register int off;
- struct mbuf *mcopy = (struct mbuf *)0;
- int type, s, error, usetrailers;
- u_char edst[6];
- struct in_addr idst;
-
- if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) {
- error = ENETDOWN;
- goto bad;
- }
- switch (dst->sa_family) {
-#ifdef INET
- case AF_INET:
- idst = ((struct sockaddr_in *)dst)->sin_addr;
- if (!arpresolve(&es->es_ac, m, &idst, edst, &usetrailers))
- return (0); /* if not yet resolved */
- if (!bcmp((caddr_t)edst, (caddr_t)etherbroadcastaddr,
- sizeof (edst)))
- mcopy = m_copy(m, 0, (int)M_COPYALL);
- off = ntohs((u_short)mtod(m, struct ip *)->ip_len) - m->m_len;
- if (usetrailers && off > 0 && (off & 0x1ff) == 0 &&
- m->m_off >= MMINOFF + 2 * sizeof (u_short)) {
- type = ETHERTYPE_TRAIL + (off>>9);
- m->m_off -= 2 * sizeof (u_short);
- m->m_len += 2 * sizeof (u_short);
- *mtod(m, u_short *) = htons((u_short)ETHERTYPE_IP);
- *(mtod(m, u_short *) + 1) = htons((u_short)m->m_len);
- goto gottrailertype;
- }
- type = ETHERTYPE_IP;
- off = 0;
- goto gottype;
-#endif
-#ifdef NS
- case AF_NS:
- bcopy((caddr_t)&(((struct sockaddr_ns *)dst)->sns_addr.x_host),
- (caddr_t)edst, sizeof (edst));
- if (!bcmp((caddr_t)edst, (caddr_t)&ns_broadhost, sizeof (edst)))
- mcopy = m_copy(m, 0, (int)M_COPYALL);
- else if (!bcmp((caddr_t)edst, (caddr_t)&ns_thishost,
- sizeof (edst)))
- return (looutput(&loif, m, dst));
- type = ETHERTYPE_NS;
- off = 0;
- goto gottype;
-#endif
- case AF_UNSPEC:
- enp = (struct ether_header *)dst->sa_data;
- bcopy((caddr_t)enp->ether_dhost, (caddr_t)edst, sizeof (edst));
- type = enp->ether_type;
- goto gottype;
-
- default:
- log(LOG_ERR, "enp%d: can't handle af%d\n",
- ifp->if_unit, dst->sa_family);
- error = EAFNOSUPPORT;
- goto bad;
- }