📄 ip_in.c
字号:
/***********************************************************************//* *//* Module: tcp_ip/ip/ip_in.c *//* Release: 2001.3 *//* Version: 2001.0 *//* Purpose: IP Entry and Utility Routines *//* *//*---------------------------------------------------------------------*//* *//* Copyright 2001, 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 <string.h>#include "ip.h"/***********************************************************************//* Configuration *//***********************************************************************/#define IP_TTL_DEF 64 /* default time-to-live value *//***********************************************************************//* Local Function Definitions *//***********************************************************************//***********************************************************************//* limited_bcst: Send copy to every interface (except local) *//* *//***********************************************************************/static void limited_bcst(NetBuf *src, Ip *ip){ Ni *ni; NetBuf *buf; Ip *bip; /*-------------------------------------------------------------------*/ /* Check every network interface, except the local interface. */ /*-------------------------------------------------------------------*/ for (ni = Net.Local.next; ni; ni = ni->next) { /*-----------------------------------------------------------------*/ /* Skip interfaces that are down. */ /*-----------------------------------------------------------------*/ if ((ni->flags & NIF_UP) == FALSE) continue; /*-----------------------------------------------------------------*/ /* Get a buffer to send to this interface. */ /*-----------------------------------------------------------------*/ buf = tcpGetBuf(NIMHLEN + ip->length); if (buf == NULL) return; /*-----------------------------------------------------------------*/ /* Copy packet and initialize buffer. */ /*-----------------------------------------------------------------*/ memcpy(buf->ip_pkt, src->ip_pkt, ip->length); buf->next_hop = 0; buf->type = src->type; buf->ni = ni; /*-----------------------------------------------------------------*/ /* Need to redo header if upper protocol is UDP. */ /*-----------------------------------------------------------------*/ bip = (Ip *)buf->ip_pkt; if (bip->protocol == IPT_UDP) { Udp *udp = buf->ip_data; /*---------------------------------------------------------------*/ /* Use this interface's address as the source address. */ /*---------------------------------------------------------------*/ bip->src_ip = ni->ip_addr; /*---------------------------------------------------------------*/ /* If present, update the UDP checksum. */ /*---------------------------------------------------------------*/ if (udp->checksum) { ui32 sum = udp->checksum; sum += (htonl(INADDR_LOOPBACK) & 0xFFFF) + (htonl(INADDR_LOOPBACK) >> 16); sum += (~ni->ip_addr & 0xFFFF) + (~ni->ip_addr >> 16); sum = (sum >> 16) + (sum & 0xFFFF); udp->checksum = (sum >> 16) + (sum & 0xFFFF); if (udp->checksum == 0) udp->checksum = ~0; } } /*-----------------------------------------------------------------*/ /* Post to TCP/IP processing queue. */ /*-----------------------------------------------------------------*/ if (NetPostMsg(IpOut, buf, ATTN_REQ)) { ++Stats.IpOutDiscards; tcpRetBuf(&buf); } }}/***********************************************************************//* Global Function Definitions *//***********************************************************************//***********************************************************************//* IpIn: Handle an IP datagram arriving from the network *//* *//* Note: IP header is left in network order in this routine *//* *//***********************************************************************/void IpIn(void){ Ip *ip; Route *route; ui8 *aligned; int length, hlen = IP_HLEN(RxBuf->ip_pkt); /*-------------------------------------------------------------------*/ /* Assign pointer to IP data before aligning IP header. */ /*-------------------------------------------------------------------*/ RxBuf->ip_data = RxBuf->ip_pkt + hlen; /*-------------------------------------------------------------------*/ /* Align IP header to four-byte boundary. */ /*-------------------------------------------------------------------*/ aligned = (ui8 *)((ui32)RxBuf->ip_pkt & ~3); if (aligned != RxBuf->ip_pkt) { memmove(aligned, RxBuf->ip_pkt, hlen); RxBuf->ip_pkt = aligned; }#if TCP_PROBE /*-------------------------------------------------------------------*/ /* Decode incoming network buffers on stdout. */ /*-------------------------------------------------------------------*/ NetProbe(RxBuf);#endif /*-------------------------------------------------------------------*/ /* Check IP version. */ /*-------------------------------------------------------------------*/ ip = (Ip *)RxBuf->ip_pkt; if ((ip->ver_len >> 4) != IP_VERSION) { ++Stats.IpInHdrErrors; return; } /*-------------------------------------------------------------------*/ /* Verify datagram does not contain class D or class E address. */ /*-------------------------------------------------------------------*/ if (IP_CLASSD(ntohl(ip->dst_ip)) || IP_CLASSE(ntohl(ip->dst_ip))) { ++Stats.IpInAddrErrors; return; } /*-------------------------------------------------------------------*/ /* Verify IP header checksum. */ /*-------------------------------------------------------------------*/ if (IpChecksum(ip, hlen)) { ++Stats.IpInHdrErrors; return; } /*-------------------------------------------------------------------*/ /* Ensure buffer length not less than datagram length and assign. */ /*-------------------------------------------------------------------*/ length = ntohs(ip->length); if (RxBuf->length < length) { ++Stats.IpPartialPkt; return; } RxBuf->length = length; /*-------------------------------------------------------------------*/ /* Route datagram. */ /*-------------------------------------------------------------------*/ route = RtSearch(ip->dst_ip); /*-------------------------------------------------------------------*/ /* Check if no route exists. */ /*-------------------------------------------------------------------*/ if (route == NULL) { /*-----------------------------------------------------------------*/ /* Pass to higher protocol if source is un-configured NI. */ /*-----------------------------------------------------------------*/ if (RxBuf->ni->ip_addr == 0) IpLocalIn(); /*-----------------------------------------------------------------*/ /* Else we received this packet in error. */ /*-----------------------------------------------------------------*/ else { /*---------------------------------------------------------------*/ /* Increment "no route" error count. */ /*---------------------------------------------------------------*/ ++Stats.IpOutNoRoutes; /*---------------------------------------------------------------*/ /* Send an "unreachable" message if we are a gateway. */ /*---------------------------------------------------------------*/ if (Net.IsGateway) IcmpDestUR(ICC_NETUR, RxBuf, ip->src_ip, ip->dst_ip); } } /*-------------------------------------------------------------------*/ /* Else check if packet is addressed to us. */ /*-------------------------------------------------------------------*/ else if (route->ni == &Net.Local) { /*-----------------------------------------------------------------*/ /* Pass to higher protocol layer. */ /*-----------------------------------------------------------------*/ IpLocalIn(); } /*-------------------------------------------------------------------*/ /* Else check if packet is IP broadcast. */ /*-------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -