📄 net_common.c
字号:
bcopy(org_code_ether, (caddr_t)lh->llc_un.type_snap.org_code, 3); type = 0; } /* * Add MAC header. */ switch (ifp->if_type) { case IFT_ISO88023: case IFT_ETHER: /* * Add Ethernet dhost, shost, and type. type == 0 indicates * frame is in 802.3 format and type really contains length. */ if (!type) { struct mbuf *n = m0; while (n) { type += n->m_len; n = n->m_next; } } m->m_off -= sizeof (struct ether_header); m->m_len += sizeof (struct ether_header); type = htons((u_short)type); eh = mtod(m, struct ether_header *); bcopy((caddr_t)&type,(caddr_t)&eh->ether_type, sizeof(eh->ether_type)); bcopy((caddr_t)odst, (caddr_t)eh->ether_dhost, sizeof (odst)); bcopy((caddr_t)ac->ac_enaddr, (caddr_t)eh->ether_shost, sizeof(ac->ac_enaddr)); break; case IFT_FDDI: m->m_off -= sizeof (struct fddi_header); m->m_len += sizeof (struct fddi_header); /* * Add FDDI dhost, shost, PA, SD, and frame control */ fh = mtod(m, struct fddi_header *); bcopy((caddr_t)odst, (caddr_t)fh->fddi_dhost, sizeof (odst)); bcopy((caddr_t)ac->ac_enaddr, (caddr_t)fh->fddi_shost, sizeof(ac->ac_enaddr)); fh->fddi_ph[0] = FDDIPH0; fh->fddi_ph[1] = FDDIPH1; fh->fddi_ph[2] = FDDIPH2; fh->fddi_fc = (u_char)(FDDIFC_LLC_ASYNC | FDDIFC_LLC_PRI4); break; default: error = EAFNOSUPPORT; goto bad; }gotheader: s = splimp(); if (ifp->lk_softc) { smp_lock(ifp->lk_softc, LK_RETRY); } if (IF_QFULL(&ifp->if_snd)) { IF_DROP(&ifp->if_snd); if (ifp->lk_softc) { smp_unlock(ifp->lk_softc); } splx(s); error = ENOBUFS; goto bad; } IF_ENQUEUE(&ifp->if_snd, m); if (!(ifp->if_flags & IFF_OACTIVE)) (*ifp->if_start)(ifp->if_unit); if (ifp->lk_softc) { smp_unlock(ifp->lk_softc); } splx(s); return(0);bad: if (m) m_freem(m); return (error);}/* * Called from the "read" routine of a LAN driver to * dispatch a received packet. */net_read(edp, eptr, m, len, lenbogus, istrailer) struct ether_driver *edp; register struct ether_header *eptr; struct mbuf *m; int len, lenbogus, istrailer;{ struct ifqueue *inq; register struct ifnet *ifp = &edp->ess_if; struct protosw *pr; struct ether_header eh; u_short etype; int priority = 0; /* * Convert FDDI headers to ethernet header for upper levels. */ if (ifp->if_type == IFT_FDDI) { struct fddi_header *fh = (struct fddi_header *)eptr; eptr = &eh; bcopy ((caddr_t)fh->fddi_dhost, (caddr_t)eptr->ether_dhost, sizeof(eptr->ether_dhost)); bcopy ((caddr_t)fh->fddi_shost, (caddr_t)eptr->ether_shost, sizeof(eptr->ether_dhost)); eptr->ether_type = 0; priority = 0; } /* * Sanity check the 802.3 frames rcvd over an Ethernet interface. * If the length in the protocol field is not equal to the * length of the data and data length > Ethernet minimum data * size, drop the packet. If the data length equals the Ethernet * minimum, adjust off the extra data at the end of the mbuf. */ if (ifp->if_type == IFT_ETHER && eptr->ether_type <= ETHERMTU) { if (eptr->ether_type != len && len != ETHERMIN) { if (eptr->ether_type > len) { edp->ess_ctrblk.est_recvfail_bm |= (1 << 2); } else { edp->ess_ctrblk.est_recvfail_bm |= (1 << 1); } if (edp->ess_ctrblk.est_recvfail != 0xffff) edp->ess_ctrblk.est_recvfail++; goto dropanyway; } else if (eptr->ether_type < len && len == ETHERMIN) { m_adj(m, -(len - eptr->ether_type)); if (m->m_len <= 0 && ((m = m_free(m)) == 0)) return; len = eptr->ether_type; } eptr->ether_type = 0; } /* * Ethernet/802.3 has two-octet type field in ether_header for * Protocol ID (Ethernet VII) OR packet length (OSI 802.3). * FDDI has ZERO in type field. */ if (eptr->ether_type <= ETHERMTU) { struct llc *lh = mtod(m, struct llc *); if ((lh->llc_control == LLC_UI) && (lh->llc_dsap == LLC_SNAP_LSAP) && (lh->llc_ssap == LLC_SNAP_LSAP) && (!bcmp((caddr_t)lh->llc_org_code, (caddr_t)org_code_ether,3))) { /* * 802.2 LLC Encapsulated Ethernet type. Grab off * the encapsulated type and trim LLC hdr. */ eptr->ether_type = ntohs((u_short)lh->llc_ether_type); if (eptr->ether_type > ETHERMTU) { m->m_off += sizeof (struct llc); m->m_len -= sizeof (struct llc); if (m->m_len <= 0 && ((m = m_free(m)) == 0)) return; } else { eptr->ether_type = 0; } } } if (pfactive || (ifp->if_flags & IFF_PROMISC)) { m = (struct mbuf *) pfilt_filter(edp, m, eptr, istrailer); /* * If the packet filter consumed the mbuf it was not * destined for the local node, so just return. */ if (m == 0) return; }#ifdef INET switch (eptr->ether_type) { case ETHERTYPE_IP: if (nINET == 0 || ac->ac_ipaddr.s_addr == 0) goto dropanyway; /* * Need to lock ipintrq so we don't allow schednetisr * to process the packet prior to us calling IF_ENQUEUE * below. */ inq = &ipintrq; smp_lock(&inq->lk_ifqueue, LK_RETRY); schednetisr(NETISR_IP); break; case ETHERTYPE_ARP: if ((nETHER==0 && nFDDI==0) || ac->ac_ipaddr.s_addr==0) goto dropanyway; /* * Need to unlock before calling arpinput, since * it calls the driver output routine and we will * already have locked the driver's softc. */ if (ifp->lk_softc) { smp_unlock(ifp->lk_softc); arpinput(ac, m); smp_lock(ifp->lk_softc, LK_RETRY); } else arpinput(ac, m); return;#endif default: /* * see if other protocol families defined * and call protocol specific routines. * If no other protocols defined then dump message. */ if ((pr=iftype_to_proto(eptr->ether_type)) && pr->pr_ifinput) { if ((m = (struct mbuf *)(*pr->pr_ifinput)(m, ifp, &inq, eptr, priority)) == 0) { if (edp->ess_ctrblk.est_unrecog != 0xffff) edp->ess_ctrblk.est_unrecog++; return; } /* else break; */ /* goes to IF_ENQUEUEIF below */ } else { if (edp->ess_ctrblk.est_unrecog != 0xffff) edp->ess_ctrblk.est_unrecog++; goto dropanyway; } } /* end switch */ if (IF_QFULL(inq)) { IF_DROP(inq); smp_unlock(&inq->lk_ifqueue); goto dropanyway; } IF_ENQUEUEIF(inq, m, ifp); smp_unlock(&inq->lk_ifqueue); return;dropanyway: m_freem(m); return;}#if NPACKETFILTER > 0/* * Initialize the part of the ether_driver structure concerned with * the packet filter, and tell the packet filter driver about us */attachpfilter_ethernet(edp)struct ether_driver *edp;{ struct endevp enp; enp.end_dev_type = ENDT_10MB; enp.end_addr_len = sizeof(edp->ess_addr); enp.end_hdr_len = sizeof(struct ether_header); enp.end_MTU = ETHERMTU; bcopy((caddr_t)(edp->ess_addr), (caddr_t)(enp.end_addr), sizeof(edp->ess_addr)); bcopy((caddr_t)etherbroadcastaddr, (caddr_t)(enp.end_broadaddr), sizeof(edp->ess_addr)); edp->ess_enetunit = pfilt_attach(&(edp->ess_if), &enp); edp->ess_missed = 0;}/* compatibility with old driver code; remove this some day */attachpfilter(edp)struct ether_driver *edp;{ attachpfilter_ethernet(edp);}attachpfilter_fddi(edp)struct ether_driver *edp;{ struct endevp enp; enp.end_dev_type = ENDT_FDDI; enp.end_addr_len = sizeof(edp->ess_addr); enp.end_hdr_len = sizeof(struct fddi_header); enp.end_MTU = FDDIMTU; bcopy((caddr_t)(edp->ess_addr), (caddr_t)(enp.end_addr), sizeof(edp->ess_addr)); bcopy((caddr_t)etherbroadcastaddr, (caddr_t)(enp.end_broadaddr), sizeof(edp->ess_addr)); edp->ess_enetunit = pfilt_attach(&(edp->ess_if), &enp); edp->ess_missed = 0;}#endif NPACKETFILTER > 0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -