📄 neticmp.c
字号:
/*****************************************************************************
* neticmp.c - Network Internet Control Message Protocol program file.
*
* Copyright (c) 1997 by Global Election Systems Inc. All rights reserved.
*
* The authors hereby grant permission to use, copy, modify, distribute,
* and license this software and its documentation for any purpose, provided
* that existing copyright notices are retained in all copies and that this
* notice and the following disclaimer are included verbatim in any
* distributions. No written agreement, license, or royalty fee is required
* for any of the authorized uses.
*
* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
* REVISION HISTORY
*
* 98-01-22 Guy Lancaster <lancasterg@acm.org>, Global Election Systems Inc.
* Extracted from BSD's ip_icmp.c and icmp_var.h.
*****************************************************************************/
/*
* Copyright (c) 1982, 1986, 1988, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)ip_icmp.c 8.2 (Berkeley) 1/4/94
*
* @(#)icmp_var.h 8.1 (Berkeley) 6/10/93
*/
/*
* ICMP routines: error generation, receive packet processing, and
* routines to turnaround packets back to the originator, and
* host table maintenance routines.
*/
#include "netconf.h"
#include <string.h>
#ifdef HAVE_ANSI_TIME
#include <time.h>
#endif
#include "net.h"
#include "netbuf.h"
#include "netip.h"
#include "netiphdr.h"
#include "neticmp.h"
#include <stdio.h>
#include "netdebug.h"
#pragma warning (push)
#pragma warning (disable: 4761) // integral size mismatch in argument; conversion supplied
//extern int ppp_close;
//int icmp_input = 0;
////////////////////////////////////////////////////////////////////////////////
/*************************/
/*** LOCAL DEFINITIONS ***/
/*************************/
/*
* Names for ICMP sysctl objects
*/
#define ICMPCTL_MASKREPL 1 /* allow replies to netmask requests */
#define ICMPCTL_MAXID 2
#define ICMPCTL_NAMES { \
{ 0, 0 }, \
{ "maskrepl", CTLTYPE_INT }, \
}
/************************/
/*** LOCAL DATA TYPES ***/
/************************/
/***********************************/
/*** LOCAL FUNCTION DECLARATIONS ***/
/***********************************/
static void icmpReflect(NBuf* nb);
static void icmpSend(register NBuf* nb, NBuf *opts);
static u_long iptime(void);
/******************************/
/*** PUBLIC DATA STRUCTURES ***/
/******************************/
IcmpStats icmpStats;
extern int gettime(struct tm * time);
/***********************************/
/*** PUBLIC FUNCTION DEFINITIONS ***/
/***********************************/
void icmpInit(void)
{
memset(&icmpStats, 0, sizeof(icmpStats));
}
/*
* Generate an error packet of type error
* in response to bad packet ip.
*/
void icmp_error(NBuf* nb, u_char type, u_char code, n_long dest)
{
register IPHdr* oip = nBUFTOPTR(nb, IPHdr*);
register IPHdr* nip;
register unsigned oiplen = oip->ip_hl << 2;
register IcmpHdr* icp;
register NBuf* n0;
unsigned icmplen;
ICMPDEBUG((LOG_INFO, "icmp_error(%x, %d, %d)\n", oip, type, code));
if (type != ICMP_REDIRECT)
icmpStats.icps_error++;
/*
* Don't send error if not the first fragment of message.
* Don't error if the old packet protocol was ICMP
* error message, only known informational types.
*/
if (oip->ip_off &~ (IP_MF|IP_DF))
goto freeit;
if (oip->ip_p == IPPROTO_ICMP && type != ICMP_REDIRECT &&
nb->len >= oiplen + ICMP_MINLEN &&
!ICMP_INFOTYPE(((IcmpHdr*)((caddr_t)oip + oiplen))->icmp_type)) {
icmpStats.icps_oldicmp++;
goto freeit;
}
/* Don't send error in response to a multicast or broadcast packet */
/* XXX */
/*
* First, formulate icmp message
*/
nGET(n0);
if (n0 == NULL)
goto freeit;
icmplen = oiplen + min(8, oip->ip_len);
n0->len = n0->chainLen = icmplen + ICMP_MINLEN;
nALIGN(n0, n0->len);
icp = nBUFTOPTR(n0, IcmpHdr*);
if ((u_int)type > ICMP_MAXTYPE)
netpanic("icmp_error");
icmpStats.icps_outhist[type]++;
icp->icmp_type = type;
if (type == ICMP_REDIRECT)
icp->icmp_gwaddr.s_addr = dest;
else {
icp->icmp_void = 0;
/*
* The following assignments assume an overlay with the
* zeroed icmp_void field.
*/
if (type == ICMP_PARAMPROB) {
icp->icmp_pptr = code;
code = 0;
}
}
icp->icmp_code = code;
bcopy((caddr_t)oip, (caddr_t)&icp->icmp_ip, icmplen);
nip = &icp->icmp_ip;
nip->ip_len = htons((u_short)(nip->ip_len + oiplen));
/*
* Now, copy old ip header (without options)
* in front of icmp message.
*/
nPREPEND(n0, oip, sizeof(IPHdr));
nip = nBUFTOPTR(n0, IPHdr*);
nip->ip_len = n0->len;
nip->ip_hl = sizeof(IPHdr) >> 2;
nip->ip_p = IPPROTO_ICMP;
nip->ip_tos = 0;
icmpReflect(n0);
freeit:
nFreeChain(nb);
}
static struct sockaddr_in icmpsrc = { sizeof (struct sockaddr_in), AF_INET };
struct sockaddr_in icmpmask = { 8, 0 };
/*
* Process a received ICMP message.
*/
void icmpInput(NBuf* inBuf, short ipHdrLen)
{
register IcmpHdr* icp;
register IPHdr* ip = nBUFTOPTR(inBuf, IPHdr*);
int icmplen = ip->ip_len - ipHdrLen;
// register int i;
u_int i;
int code;
//extern u_char ip_protox[];
ICMPDEBUG((LOG_INFO, "icmp_input from %s to %s, len %d\n",
ip_ntoa(ip->ip_src.s_addr),
ip_ntoa2(ip->ip_dst.s_addr),
icmplen));
//++icmp_input;
//if(icmp_input == 100)
//ppp_close = 1;
/*
* Locate icmp structure in nBuf, and check
* that not corrupted and of at least minimum length.
*/
if (icmplen < ICMP_MINLEN) {
icmpStats.icps_tooshort++;
goto freeit;
}
i = ipHdrLen + min(icmplen, ICMP_ADVLENMIN);
if (inBuf->len < i && (inBuf = nPullup(inBuf, i)) == NULL) {
icmpStats.icps_tooshort++;
return;
}
ip = nBUFTOPTR(inBuf, IPHdr*);
icp = (IcmpHdr*)(nBUFTOPTR(inBuf, char*) + ipHdrLen);
if (inChkSum(inBuf, icmplen, ipHdrLen)) {
icmpStats.icps_checksum++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -