📄 ipproto.c
字号:
pm2DrvCntr->ifInOctets = mib2Tbl.ifInOctets; pm2DrvCntr->ifInNUcastPkts = mib2Tbl.ifInNUcastPkts; pm2DrvCntr->ifInDiscards = mib2Tbl.ifInDiscards; pm2DrvCntr->ifInUnknownProtos = mib2Tbl.ifInUnknownProtos; pm2DrvCntr->ifOutOctets = mib2Tbl.ifOutOctets; pm2DrvCntr->ifOutNUcastPkts = mib2Tbl.ifOutNUcastPkts; pm2DrvCntr->ifOutDiscards = mib2Tbl.ifOutDiscards; break; case SIOCGMIB2233: error = muxIoctl (pDrvCtrl->pIpCookie, EIOCGMIB2233, data); if (error != OK) return (EINVAL); break; case SIOCSMIB2233: error = muxIoctl (pDrvCtrl->pIpCookie, EIOCSMIB2233, data); if (error != OK) return (EINVAL); break; case SIOCADDMULTI: /* Don't allow group membership on non-multicast interfaces. */ if ((ifp->ac_if.if_flags & IFF_MULTICAST) == 0) return EOPNOTSUPP; if (ifp->ac_if.if_resolve) { pDrvCtrl = (IP_DRV_CTRL*)ifp->ac_if.pCookie; ifr = (struct ifreq *)data; inetaddr = &ifr->ifr_addr; pMblk = KHEAP_ALLOC(sizeof(M_BLK)); if (pMblk == NULL) { error = ENOBUFS; break; } bzero ( (char *)pMblk, sizeof (M_BLK)); pMblk->mBlkHdr.mFlags |= M_MCAST; /* * call the registered address resolution function * to do the mapping */ if (ifp->ac_if.if_resolve (&ipMcastResume, pMblk, inetaddr, &ifp->ac_if, SIOCADDMULTI, &mapMCastBuff) == 0) { KHEAP_FREE( (char *)pMblk); break; /* not yet resolved */ } KHEAP_FREE( (char *)pMblk); /* register the mapped multicast MAC address */ error = muxMCastAddrAdd (pDrvCtrl->pIpCookie, (char *)&mapMCastBuff); } break; /* if no resolve function, return OK */ case SIOCDELMULTI: /* Don't allow group membership on non-multicast interfaces. */ if ((ifp->ac_if.if_flags & IFF_MULTICAST) == 0) return EOPNOTSUPP; if (ifp->ac_if.if_resolve) { pDrvCtrl = ifp->ac_if.pCookie; ifr = (struct ifreq *)data; inetaddr = (&ifr->ifr_addr); pMblk = KHEAP_ALLOC(sizeof (M_BLK)); if (pMblk == NULL) { error = ENOBUFS; break; } bzero ( (char *)pMblk, sizeof (M_BLK)); pMblk->mBlkHdr.mFlags |= M_MCAST; /* * call the registered address resolution function to do * the mapping */ if (ifp->ac_if.if_resolve (&ipMcastResume, pMblk, inetaddr, &ifp->ac_if, SIOCDELMULTI, &mapMCastBuff) == 0) { KHEAP_FREE( (char *)pMblk); break; /* not yet resolved */ } KHEAP_FREE( (char *)pMblk); /* delete the mapped multicast MAC address */ error = muxMCastAddrDel (pDrvCtrl->pIpCookie, (char *)&mapMCastBuff); } break; /* if no resolve routine, return OK */ case SIOCGETMULTI: break; case SIOCSIFFLAGS: ifr = (struct ifreq *) data; /* * Turn off all flags that are disabled in the request * correcting for the conversion from short to long */ flagsMask = (unsigned short) (~ ifr->ifr_flags); /* Two's complement used to disable flags by muxIoctl () */ flagsMask = -flagsMask - 1; error = muxIoctl (pDrvCtrl->pIpCookie, EIOCSFLAGS, (caddr_t) flagsMask); /* * Next set all flags that are set in request correcting for * the conversion from short to long. */ flagsMask = (unsigned short) ifr->ifr_flags; error |= muxIoctl (pDrvCtrl->pIpCookie, EIOCSFLAGS, (caddr_t) flagsMask); break; case SIOCGMCASTLIST: error = muxIoctl (pDrvCtrl->pIpCookie, EIOCGMCASTLIST, data); if (error != OK) return (EINVAL); break; default: error = muxIoctl (pDrvCtrl->pIpCookie, cmd, data); break; } return (error); }/******************************************************************************** ipOutput - transmit routine for IP packets using END or NPT devices.** This routine handles the final processing before transferring a* network packet (contained in the <m0> argument) to the transmit* device.** For END devices, it encapsulates a packet in the link-level frame* before transferring it to the driver. The output processing constructs* Ethernet frames unless the device provides a custom routine to form the* appropriate frame header.** For NPT devices, the routine just inserts the destination link-level* address at the front of the mBlk chain. Later processing hands that* address to the driver along with an mBlk chain containing the network* packet (with no link-level header).** NOTE: It assumes that ifp is actually a pointer to an arpcom structure.** NOMANUAL*/int ipOutput ( register struct ifnet *ifp, struct mbuf *m0, struct sockaddr *dst, struct rtentry *rt0 ) { u_short etype = 0; int s, error = 0; register struct mbuf *m = m0; register struct rtentry *rt; int off; struct arpcom *ac = (struct arpcom *)ifp; struct ether_header* eh; IP_DRV_CTRL* pDrvCtrl;#ifdef ROUTER_STACK struct ip* pIpHdr; END_OBJ* pEnd; struct sockaddr_in* pNetMask;#endif /* ROUTER_STACK */ pDrvCtrl = (IP_DRV_CTRL *)ifp->pCookie; if (pDrvCtrl->pIpCookie == NULL) senderr (EINVAL); if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET /* WV_NET_CRITICAL event */ WV_NET_EVENT_1 (NET_CORE_EVENT, WV_NET_CRITICAL, 2, 3, WV_NETEVENT_ETHEROUT_IFDOWN, WV_NET_SEND, ifp)#endif /* INCLUDE_WVNET */#endif senderr(ENETDOWN); } ifp->if_lastchange = tickGet(); if ((rt = rt0)) { if ((rt->rt_flags & RTF_UP) == 0) { if ((rt0 = rt = rtalloc1(dst, 1))) rt->rt_refcnt--; else {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET /* WV_NET_CRITICAL event */ WV_NET_EVENT_1 (NET_CORE_EVENT, WV_NET_CRITICAL, 4, 5, WV_NETEVENT_ETHEROUT_NOROUTE, WV_NET_SEND, ((struct sockaddr_in *)dst)->sin_addr.s_addr)#endif /* INCLUDE_WVNET */#endif senderr(EHOSTUNREACH); } } if (rt->rt_flags & RTF_GATEWAY) { if (rt->rt_gwroute == 0) goto lookup; if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) { rtfree(rt); rt = rt0; lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1); if ((rt = rt->rt_gwroute) == 0) {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET /* WV_NET_CRITICAL event */ WV_NET_EVENT_1 (NET_CORE_EVENT, WV_NET_CRITICAL, 4, 5, WV_NETEVENT_ETHEROUT_NOROUTE, WV_NET_SEND, ((struct sockaddr_in *)rt->rt_gateway)->sin_addr.s_addr)#endif /* INCLUDE_WVNET */#endif senderr(EHOSTUNREACH); } } } if (rt->rt_flags & RTF_REJECT) { if (rt->rt_rmx.rmx_expire == 0 || tickGet() < rt->rt_rmx.rmx_expire) {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET /* WV_NET_CRITICAL event */ WV_NET_EVENT_0 (NET_CORE_EVENT, WV_NET_CRITICAL, 5, 6, WV_NETEVENT_ETHEROUT_RTREJECT, WV_NET_SEND)#endif /* INCLUDE_WVNET */#endif senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH); } } } /* if (rt = rt0) */ switch (dst->sa_family) { case AF_INET: if (ifp->if_resolve != NULL) if (!ifp->if_resolve (&ipOutputResume, m, dst, ifp, rt, pDrvCtrl->pDstAddr)) return (0); /* if not yet resolved */#ifdef ROUTER_STACK if ((m->m_flags & M_FORWARD)) { /* * If we are forwarding this packet, and Fastpath is * enabled both at the module and interface level, * supply the Fastpath module with the additional * forwarding information (the MAC address etc.) */ if (SHOULD_MAKE_CALLS_TO_FF (GET_IPV4_FF_ID) && FF_MOD_ENABLED (GET_IPV4_FF_ID) && FF_INTF_ENABLED (GET_IPV4_FF_ID, ifp)) { pEnd = PCOOKIE_TO_ENDOBJ(pDrvCtrl->pIpCookie); pIpHdr= mtod(m, struct ip *); pNetMask=(struct sockaddr_in*)(rt_mask(rt0));#ifdef DEBUG logMsg ("ipOutput: dst IP addr %x\n", pIpHdr->ip_dst.s_addr, 0, 0, 0, 0, 0); logMsg ("ipOutput: rt0 is %x. rt is %x.\n", rt0, rt, 0, 0, 0, 0);#endif /* DEBUG */ /* * if indirect route pass the 'key' of the * routing entry as the destination IP address. * If not pass the host * IP address as the destination IP address. */ if (rt0->rt_flags & RTF_GATEWAY) { if (rt0->rt_flags & RTF_CLONED) rt0 = rt0->rt_parent; if (rt0) FFL_CALL (ffLibRouteMoreInfo, \ (GET_IPV4_FF_ID, rt_key(rt0), \ rt_mask(rt0), rt0->rt_gateway, \ pDrvCtrl->pDstAddr, ifp->if_addrlen, \ rt0->rt_flags, ifp->if_mtu, \ ifp->if_index, ifp)); } else { FFL_CALL (ffLibRouteMoreInfo, \ (GET_IPV4_FF_ID, dst, \ 0, dst, \ pDrvCtrl->pDstAddr, ifp->if_addrlen, \ rt0->rt_flags, ifp->if_mtu, \ ifp->if_index, ifp)); } } }#endif /* ROUTER_STACK */ /* If broadcasting on a simplex interface, loopback a copy */ if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX) && !(m->m_flags & M_PROXY)) ip_mloopback (ifp, m, (struct sockaddr_in *)dst, (struct rtentry*)rt); off = m->m_pkthdr.len - m->m_len; etype = ETHERTYPE_IP; break; case AF_UNSPEC: /* * WARNING: At the moment this code ONLY handles 14 byte * headers of the type like Ethernet. */ switch (ifp->if_type) { case M2_ifType_ethernet_csmacd: case M2_ifType_iso88023_csmacd: case M2_ifType_iso88024_tokenBus: case M2_ifType_iso88025_tokenRing: case M2_ifType_iso88026_man: case M2_ifType_fddi: eh = (struct ether_header *)dst->sa_data; bcopy((caddr_t)eh->ether_dhost, (caddr_t)pDrvCtrl->pDstAddr, ifp->if_addrlen); etype = eh->ether_type; break; default: error=ERROR; } if(!error) break; /* fall-through */ default: logMsg ("%s%d: can't handle af%d\n", (int)ifp->if_name, ifp->if_unit, dst->sa_family, 0, 0, 0);#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET /* WV_NET_ERROR event */ WV_NET_EVENT_1 (NET_CORE_EVENT, WV_NET_ERROR, 3, 7, WV_NETEVENT_ETHEROUT_AFNOTSUPP, WV_NET_SEND, dst->sa_family)#endif /* INCLUDE_WVNET */#endif senderr(EAFNOSUPPORT); } etype = htons(etype); if (pDrvCtrl->nptFlag) { /* * For NPT devices, insert the destination address (if any) and * network protocol type at the beginning of the network packet * for later use. */ if (ifp->if_addrlen) { M_PREPEND(m, ifp->if_addrlen, M_DONTWAIT); if (m == NULL) { senderr(ENOBUFS); } ((M_BLK_ID)m)->mBlkPktHdr.rcvif = 0; /* Store the destination address. */ bcopy (pDrvCtrl->pDstAddr, m->m_data, ifp->if_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -