📄 iputil.c
字号:
/***********************************************************************//* *//* Module: tcp_ip/ip/iputil.c *//* Release: 2001.3 *//* Version: 2000.0 *//* Purpose: IP Utility Routines *//* *//*---------------------------------------------------------------------*//* *//* Copyright 2000, Blunk Microsystems *//* ALL RIGHTS RESERVED *//* *//* Licensees have the non-exclusive right to use, modify, or extract *//* this computer program for software development at a single site. *//* This program may be resold or disseminated in executable format *//* only. The source code may not be redistributed or resold. *//* *//***********************************************************************/#include "../tcp_ipp.h"#include "ip.h"/***********************************************************************//* Global Function Definitions *//***********************************************************************//***********************************************************************//* IpLocalIn: Process inbound IP packet pointed to by RxBuf *//* *//***********************************************************************/void IpLocalIn(void){ /*-------------------------------------------------------------------*/ /* Assign global IP pointer and assign IP data length. */ /*-------------------------------------------------------------------*/ Net.Ip = (Ip *)RxBuf->ip_pkt; RxBuf->length -= IP_HLEN(RxBuf->ip_pkt); /*-------------------------------------------------------------------*/ /* Convert IP header to host order (addresses kept in network order).*/ /*-------------------------------------------------------------------*/ Net.Ip->length = ntohs(Net.Ip->length); Net.Ip->ip_id = ntohs(Net.Ip->ip_id); Net.Ip->frag_off = ntohs(Net.Ip->frag_off); /*-------------------------------------------------------------------*/ /* If fragmented, try to reassemble packet. */ /*-------------------------------------------------------------------*/ if (Net.Ip->frag_off & (IP_FRAGOFF | IP_MF)) { ++Stats.IpReasmReqds; if (IpJoinFrag() == FALSE) { RxBuf = NULL; return; } } TcpAssert(RxBuf); /*-------------------------------------------------------------------*/ /* Pass to the appropriate upper layer protocol. */ /*-------------------------------------------------------------------*/ switch (Net.Ip->protocol) { case IPT_UDP: UdpIn(); break; case IPT_ICMP: IcmpIn(); break; case IPT_IGMP: ++Stats.IgmpInSegs; break; case IPT_TCP: TcpIn(); ++Stats.TcpInSegs; break; default: IcmpDestUR(ICC_PROTOUR, RxBuf, Net.Ip->src_ip, Net.Ip->dst_ip); break; }}/***********************************************************************//* IpChecksum: Return 16-bit ones complement of source data *//* *//* Inputs: src = pointer to source data *//* len = byte count of data *//* *//***********************************************************************/ui16 IpChecksum(void *src, uint len){ ui16 *wptr = src; ui32 sum; /*-------------------------------------------------------------------*/ /* Check for atypical IP header size. */ /*-------------------------------------------------------------------*/ if (len != 20) { ui16 *end = wptr + (len >> 1); /*-----------------------------------------------------------------*/ /* Sum data as 16-bit words. */ /*-----------------------------------------------------------------*/ for (sum = 0; wptr < end;) sum += *wptr++; /*-----------------------------------------------------------------*/ /* Add left-over byte, if any. */ /*-----------------------------------------------------------------*/ if (len & 1) sum += htons(*(ui8*)wptr << 8); } /*-------------------------------------------------------------------*/ /* Special case for normal IP header. */ /*-------------------------------------------------------------------*/ else { sum = wptr[0] + wptr[1] + wptr[2] + wptr[3] + wptr[4] + wptr[5] + wptr[6] + wptr[7] + wptr[8] + wptr[9]; } /*-------------------------------------------------------------------*/ /* Convert to 16-bit ones complement sum and return complement. */ /*-------------------------------------------------------------------*/ sum = (sum >> 16) + (sum & 0xFFFF); sum += (sum >> 16); return (ui16)~sum;}/***********************************************************************//* IpSubnetMask: Determine the given network's subnet mask *//* *//* Input: net = IP network address *//* *//* Returns: subnet mask *//* *//***********************************************************************/ui32 IpSubnetMask(ui32 net){ ui32 netpart; Ni *ni; /*-------------------------------------------------------------------*/ /* If address specifies default route, use subnet mask of all 0's. */ /*-------------------------------------------------------------------*/ if (net == INADDR_ANY) return INADDR_ANY; /*-------------------------------------------------------------------*/ /* Check every network interface, except the local interface. */ /*-------------------------------------------------------------------*/ netpart = IpNetMask(net) & net; for (ni = Net.Local.next; ni; ni = ni->next) { /*-----------------------------------------------------------------*/ /* Skip interfaces that are down. */ /*-----------------------------------------------------------------*/ if ((ni->flags & NIF_UP) == FALSE) continue; /*-----------------------------------------------------------------*/ /* Use NI's mask if network addresses match. */ /*-----------------------------------------------------------------*/ if ((IpNetMask(ni->ip_addr) & ni->ip_addr) == netpart) return ni->ip_mask; } /*-------------------------------------------------------------------*/ /* Else, set the subnet mask according to the IP address class. */ /*-------------------------------------------------------------------*/ return IpNetMask(net);}/***********************************************************************//* IpNetMask: Determine the given network's network mask *//* *//* Input: net = IP network address *//* *//* Returns: network mask *//* *//***********************************************************************/ui32 IpNetMask(ui32 net){ net = ntohl(net); if (IP_CLASSA(net)) return htonl(0xFF000000); else if (IP_CLASSB(net)) return htonl(0xFFFF0000); else if (IP_CLASSC(net)) return htonl(0xFFFFFF00); else return htonl(0xFFFFFFFF);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -