📄 icmplib.c
字号:
if (pCookie == NULL) goto icmpMaskGetError; for (ix = 0; ix < ICMP_MAX_SEND; ix++) { if ((pMbuf = bcopy_to_mbufs ((u_char *) &icmpMsg, sizeof (icmpMsg), 0, pIf, NONE)) == NULL) goto icmpMaskGetError; if (dst == NULL) /* if broadcasting */ pMbuf->mBlkHdr.mFlags |= M_BCAST; /* send message */ level = splnet (); result = (* pIf->if_output) ( (struct ifnet *)&pDrvCtrl->idr, pMbuf, (struct sockaddr *)&dstAddr, NULL); splx (level); if (result) goto icmpMaskGetError; /* wait for reply */ tickCount = retransmitSecs * sysClkRateGet (); while (tickCount-- > 0) { if (maskReplyReceived) { *pSubnet = icmpMask; muxUnbind (pCookie, MUX_PROTO_SNARF, pBoundRtn); return (OK); } taskDelay (1); } } errno = S_icmpLib_TIMEOUT; icmpMaskGetError: if (pCookie != NULL && pBoundRtn != NULL) muxUnbind (pCookie, MUX_PROTO_SNARF, pBoundRtn); return (ERROR); /* no subnet */ }/******************************************************************************** icmpMaskEndInput - END version of input filter for ICMP Mask Reply** This routine filters out the ICMP Address Mask Reply message from* incoming link frame. It is bound to MUX by muxBind as a SNARF* protocol.** RETURNS:* TRUE indicating the packet was consumed by this routine and no further* processing needs to be done.* FALSE indicating the packet was not consumed by this routine and* further processing needs to be done.*/LOCAL BOOL icmpMaskEndInput ( void * pCookie, /* device identifier from driver */ long type, /* Protocol type. */ M_BLK_ID pMblk, /* The whole packet. */ LL_HDR_INFO * pLinkHdrInfo, /* pointer to link level header info */ void * pSpare /* pointer to IP_DRV_CTRL */ ) { IP_DRV_CTRL * pDrvCtrl = (IP_DRV_CTRL *) pSpare; struct ifnet * pIf = NULL; struct icmp * pIcmp; M_BLK_ID pMblkOrig; M_BLK tmpM; /* already got a reply, or unknown device */ if (maskReplyReceived || pDrvCtrl == NULL || pMblk == NULL || (pIf = (struct ifnet *)&pDrvCtrl->idr) == NULL) return (FALSE); if ((pIf->if_flags & IFF_UP) == 0) { pIf->if_ierrors++; return (FALSE); } /* Make sure the entire Link Hdr is in the first M_BLK */ pMblkOrig = pMblk; if (pMblk->mBlkHdr.mLen < pLinkHdrInfo->dataOffset && (pMblk = m_pullup (pMblk, pLinkHdrInfo->dataOffset)) == NULL) { pMblk = pMblkOrig; return (FALSE); } /* point to the ip header, and adjust the length */ bzero ((char *)&tmpM, sizeof (M_BLK)); bcopy ((char *)pMblk, (char *)&tmpM, sizeof (M_BLK)); tmpM.mBlkHdr.mData += pLinkHdrInfo->dataOffset; tmpM.mBlkHdr.mLen -= pLinkHdrInfo->dataOffset; tmpM.mBlkPktHdr.len -= pLinkHdrInfo->dataOffset; tmpM.mBlkPktHdr.rcvif = &pDrvCtrl->idr.ac_if; /* get and verify icmp */ pIcmp = (struct icmp *) ipHeaderVerify ((struct ip *) tmpM.mBlkHdr.mData, tmpM.mBlkHdr.mLen, IPPROTO_ICMP); if ((pIcmp == NULL) || (checksum ((u_short *) pIcmp, ICMP_MASKLEN) != 0) || (pIcmp->icmp_type != ICMP_MASKREPLY)) return (FALSE); pIf->if_ipackets++; /* bump statistic */ pIf->if_lastchange = tickGet(); pIf->if_ibytes += pMblk->mBlkPktHdr.len; maskReplyReceived = TRUE; icmpMask = ntohl (pIcmp->icmp_mask); netMblkClChainFree (pMblk); return (TRUE); }/******************************************************************************** icmpMaskNptInput - NPT version of input filter for ICMP Mask Reply** This routine filters out the ICMP Address Mask Reply message from* incoming link frame. It is bound to MUX by muxBind as a SNARF* protocol.** RETURNS:* TRUE indicating the packet was consumed by this routine and no further* processing needs to be done.* FALSE indicating the packet was not consumed by this routine and* further processing needs to be done.*/LOCAL BOOL icmpMaskNptInput ( void * ipCallbackId, /* Sent down in muxTkBind call. */ long type, /* Protocol type. */ M_BLK_ID pMblk, /* The whole packet. */ void * pSpareData /* out of band data */ ) { IP_DRV_CTRL * pDrvCtrl = (IP_DRV_CTRL *)ipCallbackId; struct ifnet * pIf = NULL; struct icmp * pIcmp; M_BLK_ID pMblkOrig; M_BLK tmpM; /* already got a reply, or unknown device */ if (maskReplyReceived || pDrvCtrl == NULL || pMblk == NULL || (pIf = (struct ifnet *)&pDrvCtrl->idr) == NULL) return (FALSE); if ((pIf->if_flags & IFF_UP) == 0) { pIf->if_ierrors++; return (FALSE); } /* Make sure the entire interface header is in the first M_BLK */ pMblkOrig = pMblk; if (pMblk->mBlkHdr.mLen < pIf->if_hdrlen && (pMblk = m_pullup (pMblk, pIf->if_hdrlen)) == NULL) { pMblk = pMblkOrig; return (FALSE); } /* point to the network service header, and adjust the length */ bzero ((char *)&tmpM, sizeof (M_BLK)); bcopy ((char *)pMblk, (char *)&tmpM, sizeof (M_BLK)); tmpM.mBlkHdr.mData += pIf->if_hdrlen; tmpM.mBlkHdr.mLen -= pIf->if_hdrlen; tmpM.mBlkPktHdr.len -= pIf->if_hdrlen; tmpM.mBlkPktHdr.rcvif = &pDrvCtrl->idr.ac_if; /* get and verify icmp */ pIcmp = (struct icmp *) ipHeaderVerify ((struct ip *) tmpM.mBlkHdr.mData, tmpM.mBlkHdr.mLen, IPPROTO_ICMP); if (pIcmp == NULL || (checksum ((u_short *) pIcmp, ICMP_MASKLEN) != 0) || (pIcmp->icmp_type != ICMP_MASKREPLY)) return (FALSE); pIf->if_ipackets++; /* bump statistic */ pIf->if_lastchange = tickGet(); pIf->if_ibytes += pMblk->mBlkPktHdr.len; maskReplyReceived = TRUE; icmpMask = ntohl (pIcmp->icmp_mask); netMblkClChainFree (pMblk); return (TRUE); }/******************************************************************************** ipHeaderCreate - create a simple IP header** This generates a simple IP header (with no options) and checksums it.* <proto> specifies the protocol type. <pSrcAddr> and <pDstAddr> define* the source and destination internet addresses, respectively. Both should* be specified in network byte order. <pih> is a pointer to an internet* datagram whose length is <length>.** RETURNS: N/A** NOMANUAL*/void ipHeaderCreate ( int proto, /* protocol number */ struct in_addr * pSrcAddr, /* source ip address */ struct in_addr * pDstAddr, /* dest ip address */ struct ip * pih, /* internet header */ int length /* datagram size */ ) { /* fill in the IP header */ pih->ip_v = IPVERSION; pih->ip_hl = (sizeof (struct ip) >> 2) & 0xf; pih->ip_len = htons ((u_short) length); pih->ip_id = (u_short) (tickGet () & 0xffff); pih->ip_ttl = MAXTTL; pih->ip_p = (u_char) proto; pih->ip_src.s_addr = pSrcAddr->s_addr; pih->ip_dst.s_addr = pDstAddr->s_addr; pih->ip_sum = 0; /* zero out the checksum while computing it */ pih->ip_sum = checksum ((u_short *) pih, (pih->ip_hl << 2)); }/********************************************************************************* ipHeaderVerify - simple IP header verification** ipHeaderVerify performs simple IP header verification. It does* sanity checks and verifies the checksum. <pih> points to an internet* datagram of length <length>. <proto> is the expected protocol.** RETURNS: a pointer to the IP data, or NULL if not a valid IP datagram.** NOMANUAL*/u_char * ipHeaderVerify ( struct ip * pih, /* internet header */ int length, /* length of datagram */ int proto /* protocol */ ) { FAST int options; /* options offset */ /* if not minimum size, or right protocol bail */ if ((length < sizeof (struct ip)) || (pih->ip_p != (u_char) proto)) return (NULL); /* verify checksum */ if (checksum ((u_short *) pih, (pih->ip_hl << 2)) != 0) return (NULL); if ((pih->ip_v != IPVERSION) || (ntohs ((u_short) pih->ip_off) & 0x3FFF)) return (NULL); /* ip_hl is in words */ options = (pih->ip_hl << 2) - sizeof (struct ip); return ((u_char *) pih + sizeof (struct ip) + options); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -