From a65d61a8a539bec1471dd9c587268738d63026de Mon Sep 17 00:00:00 2001 From: Juan Lang Date: Thu, 17 Jul 2008 09:39:29 -0700 Subject: [PATCH] Move Icmp* functions from icmp to iphlpapi --- dlls/icmp/Makefile.in | 2 dlls/icmp/icmp.spec | 8 - dlls/icmp/icmp_main.c | 510 ------------------------------------------- dlls/icmp/ip.h | 180 --------------- dlls/icmp/ip_icmp.h | 186 ---------------- dlls/iphlpapi/Makefile.in | 1 dlls/iphlpapi/icmp.c | 510 +++++++++++++++++++++++++++++++++++++++++++ dlls/iphlpapi/ip.h | 180 +++++++++++++++ dlls/iphlpapi/ip_icmp.h | 186 ++++++++++++++++ dlls/iphlpapi/iphlpapi.spec | 5 10 files changed, 886 insertions(+), 882 deletions(-) diff --git a/dlls/icmp/Makefile.in b/dlls/icmp/Makefile.in index 5286e86..3154034 100644 --- a/dlls/icmp/Makefile.in +++ b/dlls/icmp/Makefile.in @@ -6,8 +6,6 @@ MODULE = icmp.dll IMPORTLIB = icmp IMPORTS = kernel32 -C_SRCS = icmp_main.c - @MAKE_DLL_RULES@ @DEPENDENCIES@ # everything below this line is overwritten by make depend diff --git a/dlls/icmp/icmp.spec b/dlls/icmp/icmp.spec index 93d5b27..866e44f 100644 --- a/dlls/icmp/icmp.spec +++ b/dlls/icmp/icmp.spec @@ -1,8 +1,8 @@ -@ stdcall IcmpCloseHandle(ptr) -@ stdcall IcmpCreateFile() +@ stdcall IcmpCloseHandle(ptr) iphlpapi.IcmpCloseHandle +@ stdcall IcmpCreateFile() iphlpapi.IcmpCreateFile @ stub IcmpParseReplies -@ stub IcmpSendEcho2 -@ stdcall IcmpSendEcho(ptr long ptr long ptr ptr long long) +@ stdcall IcmpSendEcho2(ptr ptr ptr ptr long ptr long ptr ptr long long) iphlpapi.IcmpSendEcho2 +@ stdcall IcmpSendEcho(ptr long ptr long ptr ptr long long) iphlpapi.IcmpSendEcho @ stub do_echo_rep @ stub do_echo_req @ stub register_icmp diff --git a/dlls/icmp/icmp_main.c b/dlls/icmp/icmp_main.c deleted file mode 100644 index 82243da..0000000 --- a/dlls/icmp/icmp_main.c +++ /dev/null @@ -1,510 +0,0 @@ -/* - * ICMP - * - * Francois Gouget, 1999, based on the work of - * RW Hall, 1999, based on public domain code PING.C by Mike Muus (1983) - * and later works (c) 1989 Regents of Univ. of California - see copyright - * notice at end of source-code. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -/* Future work: - * - Systems like FreeBSD don't seem to support the IP_TTL option and maybe others. - * But using IP_HDRINCL and building the IP header by hand might work. - * - Not all IP options are supported. - * - Are ICMP handles real handles, i.e. inheritable and all? There might be some - * more work to do here, including server side stuff with synchronization. - * - Is it correct to use malloc for the internal buffer, for allocating the - * handle's structure? - * - This API should probably be thread safe. Is it really? - * - Using the winsock functions has not been tested. - */ - -#include "config.h" - -#include -#ifdef HAVE_SYS_SOCKET_H -# include -#endif -#ifdef HAVE_NETDB_H -# include -#endif -#ifdef HAVE_NETINET_IN_SYSTM_H -# include -#endif -#ifdef HAVE_NETINET_IN_H -# include -#endif - -#ifdef HAVE_SYS_TIME_H -# include -#endif -#include -#include -#include -#ifdef HAVE_UNISTD_H -# include -#endif -#ifdef HAVE_ARPA_INET_H -# include -#endif -#ifdef HAVE_SYS_POLL_H -# include -#endif - -#include "windef.h" -#include "winbase.h" -#include "winerror.h" -#include "ipexport.h" -#include "icmpapi.h" -#include "wine/debug.h" - -/* Set up endianness macros for the ip and ip_icmp BSD headers */ -#ifndef BIG_ENDIAN -#define BIG_ENDIAN 4321 -#endif -#ifndef LITTLE_ENDIAN -#define LITTLE_ENDIAN 1234 -#endif -#ifndef BYTE_ORDER -#ifdef WORDS_BIGENDIAN -#define BYTE_ORDER BIG_ENDIAN -#else -#define BYTE_ORDER LITTLE_ENDIAN -#endif -#endif /* BYTE_ORDER */ - -#define u_int16_t WORD -#define u_int32_t DWORD - -/* These are BSD headers. We use these here because they are needed on - * libc5 Linux systems. On other platforms they are usually simply more - * complete than the native stuff, and cause less portability problems - * so we use them anyway. - */ -#include "ip.h" -#include "ip_icmp.h" - - -WINE_DEFAULT_DEBUG_CHANNEL(icmp); - - -typedef struct { - int sid; - IP_OPTION_INFORMATION default_opts; -} icmp_t; - -#define IP_OPTS_UNKNOWN 0 -#define IP_OPTS_DEFAULT 1 -#define IP_OPTS_CUSTOM 2 - -/* The sequence number is unique process wide, so that all threads - * have a distinct sequence number. - */ -static LONG icmp_sequence=0; - -static int in_cksum(u_short *addr, int len) -{ - int nleft=len; - u_short *w = addr; - int sum = 0; - u_short answer = 0; - - while (nleft > 1) { - sum += *w++; - nleft -= 2; - } - - if (nleft == 1) { - *(u_char *)(&answer) = *(u_char *)w; - sum += answer; - } - - sum = (sum >> 16) + (sum & 0xffff); - sum += (sum >> 16); - answer = ~sum; - return(answer); -} - - - -/* - * Exported Routines. - */ - -/*********************************************************************** - * IcmpCreateFile (ICMP.@) - */ -HANDLE WINAPI IcmpCreateFile(VOID) -{ - icmp_t* icp; - - int sid=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP); - if (sid < 0) { - MESSAGE("WARNING: Trying to use ICMP (network ping) will fail unless running as root\n"); - SetLastError(ERROR_ACCESS_DENIED); - return INVALID_HANDLE_VALUE; - } - - icp=HeapAlloc(GetProcessHeap(), 0, sizeof(*icp)); - if (icp==NULL) { - SetLastError(IP_NO_RESOURCES); - return INVALID_HANDLE_VALUE; - } - icp->sid=sid; - icp->default_opts.OptionsSize=IP_OPTS_UNKNOWN; - return (HANDLE)icp; -} - - -/*********************************************************************** - * IcmpCloseHandle (ICMP.@) - */ -BOOL WINAPI IcmpCloseHandle(HANDLE IcmpHandle) -{ - icmp_t* icp=(icmp_t*)IcmpHandle; - if (IcmpHandle==INVALID_HANDLE_VALUE) { - /* FIXME: in fact win98 seems to ignore the handle value !!! */ - SetLastError(ERROR_INVALID_HANDLE); - return FALSE; - } - - shutdown(icp->sid,2); - HeapFree(GetProcessHeap (), 0, icp); - return TRUE; -} - - -/*********************************************************************** - * IcmpSendEcho (ICMP.@) - */ -DWORD WINAPI IcmpSendEcho( - HANDLE IcmpHandle, - IPAddr DestinationAddress, - LPVOID RequestData, - WORD RequestSize, - PIP_OPTION_INFORMATION RequestOptions, - LPVOID ReplyBuffer, - DWORD ReplySize, - DWORD Timeout - ) -{ - icmp_t* icp=(icmp_t*)IcmpHandle; - unsigned char* reqbuf; - int reqsize; - - struct icmp_echo_reply* ier; - struct ip* ip_header; - struct icmp* icmp_header; - char* endbuf; - int ip_header_len; - int maxlen; - struct pollfd fdr; - DWORD send_time,recv_time; - struct sockaddr_in addr; - unsigned int addrlen; - unsigned short id,seq,cksum; - int res; - - if (IcmpHandle==INVALID_HANDLE_VALUE) { - /* FIXME: in fact win98 seems to ignore the handle value !!! */ - SetLastError(ERROR_INVALID_HANDLE); - return 0; - } - - if (ReplySizeicmp_type=ICMP_ECHO; - icmp_header->icmp_code=0; - icmp_header->icmp_cksum=0; - icmp_header->icmp_id=id; - icmp_header->icmp_seq=seq; - memcpy(reqbuf+ICMP_MINLEN, RequestData, RequestSize); - icmp_header->icmp_cksum=cksum=in_cksum((u_short*)reqbuf,reqsize); - - addr.sin_family=AF_INET; - addr.sin_addr.s_addr=DestinationAddress; - addr.sin_port=0; - - if (RequestOptions!=NULL) { - int val; - if (icp->default_opts.OptionsSize==IP_OPTS_UNKNOWN) { - unsigned int len; - /* Before we mess with the options, get the default values */ - len=sizeof(val); - getsockopt(icp->sid,IPPROTO_IP,IP_TTL,(char *)&val,&len); - icp->default_opts.Ttl=val; - - len=sizeof(val); - getsockopt(icp->sid,IPPROTO_IP,IP_TOS,(char *)&val,&len); - icp->default_opts.Tos=val; - /* FIXME: missing: handling of IP 'flags', and all the other options */ - } - - val=RequestOptions->Ttl; - setsockopt(icp->sid,IPPROTO_IP,IP_TTL,(char *)&val,sizeof(val)); - val=RequestOptions->Tos; - setsockopt(icp->sid,IPPROTO_IP,IP_TOS,(char *)&val,sizeof(val)); - /* FIXME: missing: handling of IP 'flags', and all the other options */ - - icp->default_opts.OptionsSize=IP_OPTS_CUSTOM; - } else if (icp->default_opts.OptionsSize==IP_OPTS_CUSTOM) { - int val; - - /* Restore the default options */ - val=icp->default_opts.Ttl; - setsockopt(icp->sid,IPPROTO_IP,IP_TTL,(char *)&val,sizeof(val)); - val=icp->default_opts.Tos; - setsockopt(icp->sid,IPPROTO_IP,IP_TOS,(char *)&val,sizeof(val)); - /* FIXME: missing: handling of IP 'flags', and all the other options */ - - icp->default_opts.OptionsSize=IP_OPTS_DEFAULT; - } - - /* Get ready for receiving the reply - * Do it before we send the request to minimize the risk of introducing delays - */ - fdr.fd = icp->sid; - fdr.events = POLLIN; - addrlen=sizeof(addr); - ier=ReplyBuffer; - ip_header=(struct ip *) ((char *) ReplyBuffer+sizeof(ICMP_ECHO_REPLY)); - endbuf=(char *) ReplyBuffer+ReplySize; - maxlen=ReplySize-sizeof(ICMP_ECHO_REPLY); - - /* Send the packet */ - TRACE("Sending %d bytes (RequestSize=%d) to %s\n", reqsize, RequestSize, inet_ntoa(addr.sin_addr)); -#if 0 - if (TRACE_ON(icmp)){ - unsigned char* buf=(unsigned char*)reqbuf; - int i; - printf("Output buffer:\n"); - for (i=0;isid, reqbuf, reqsize, 0, (struct sockaddr*)&addr, sizeof(addr)); - HeapFree(GetProcessHeap (), 0, reqbuf); - if (res<0) { - if (errno==EMSGSIZE) - SetLastError(IP_PACKET_TOO_BIG); - else { - switch (errno) { - case ENETUNREACH: - SetLastError(IP_DEST_NET_UNREACHABLE); - break; - case EHOSTUNREACH: - SetLastError(IP_DEST_HOST_UNREACHABLE); - break; - default: - TRACE("unknown error: errno=%d\n",errno); - SetLastError(IP_GENERAL_FAILURE); - } - } - return 0; - } - - /* Get the reply */ - ip_header_len=0; /* because gcc was complaining */ - while ((res=poll(&fdr,1,Timeout))>0) { - recv_time = GetTickCount(); - res=recvfrom(icp->sid, (char*)ip_header, maxlen, 0, (struct sockaddr*)&addr,&addrlen); - TRACE("received %d bytes from %s\n",res, inet_ntoa(addr.sin_addr)); - ier->Status=IP_REQ_TIMED_OUT; - - /* Check whether we should ignore this packet */ - if ((ip_header->ip_p==IPPROTO_ICMP) && (res>=sizeof(struct ip)+ICMP_MINLEN)) { - ip_header_len=ip_header->ip_hl << 2; - icmp_header=(struct icmp*)(((char*)ip_header)+ip_header_len); - TRACE("received an ICMP packet of type,code=%d,%d\n",icmp_header->icmp_type,icmp_header->icmp_code); - if (icmp_header->icmp_type==ICMP_ECHOREPLY) { - if ((icmp_header->icmp_id==id) && (icmp_header->icmp_seq==seq)) - ier->Status=IP_SUCCESS; - } else { - switch (icmp_header->icmp_type) { - case ICMP_UNREACH: - switch (icmp_header->icmp_code) { - case ICMP_UNREACH_HOST: -#ifdef ICMP_UNREACH_HOST_UNKNOWN - case ICMP_UNREACH_HOST_UNKNOWN: -#endif -#ifdef ICMP_UNREACH_ISOLATED - case ICMP_UNREACH_ISOLATED: -#endif -#ifdef ICMP_UNREACH_HOST_PROHIB - case ICMP_UNREACH_HOST_PROHIB: -#endif -#ifdef ICMP_UNREACH_TOSHOST - case ICMP_UNREACH_TOSHOST: -#endif - ier->Status=IP_DEST_HOST_UNREACHABLE; - break; - case ICMP_UNREACH_PORT: - ier->Status=IP_DEST_PORT_UNREACHABLE; - break; - case ICMP_UNREACH_PROTOCOL: - ier->Status=IP_DEST_PROT_UNREACHABLE; - break; - case ICMP_UNREACH_SRCFAIL: - ier->Status=IP_BAD_ROUTE; - break; - default: - ier->Status=IP_DEST_NET_UNREACHABLE; - } - break; - case ICMP_TIMXCEED: - if (icmp_header->icmp_code==ICMP_TIMXCEED_REASS) - ier->Status=IP_TTL_EXPIRED_REASSEM; - else - ier->Status=IP_TTL_EXPIRED_TRANSIT; - break; - case ICMP_PARAMPROB: - ier->Status=IP_PARAM_PROBLEM; - break; - case ICMP_SOURCEQUENCH: - ier->Status=IP_SOURCE_QUENCH; - break; - } - if (ier->Status!=IP_REQ_TIMED_OUT) { - struct ip* rep_ip_header; - struct icmp* rep_icmp_header; - /* The ICMP header size of all the packets we accept is the same */ - rep_ip_header=(struct ip*)(((char*)icmp_header)+ICMP_MINLEN); - rep_icmp_header=(struct icmp*)(((char*)rep_ip_header)+(rep_ip_header->ip_hl << 2)); - - /* Make sure that this is really a reply to our packet */ - if (ip_header_len+ICMP_MINLEN+(rep_ip_header->ip_hl << 2)+ICMP_MINLEN>ip_header->ip_len) { - ier->Status=IP_REQ_TIMED_OUT; - } else if ((rep_icmp_header->icmp_type!=ICMP_ECHO) || - (rep_icmp_header->icmp_code!=0) || - (rep_icmp_header->icmp_id!=id) || - /* windows doesn't check this checksum, else tracert */ - /* behind a Linux 2.2 masquerading firewall would fail*/ - /* (rep_icmp_header->icmp_cksum!=cksum) || */ - (rep_icmp_header->icmp_seq!=seq)) { - /* This was not a reply to one of our packets after all */ - TRACE("skipping type,code=%d,%d id,seq=%d,%d cksum=%d\n", - rep_icmp_header->icmp_type,rep_icmp_header->icmp_code, - rep_icmp_header->icmp_id,rep_icmp_header->icmp_seq, - rep_icmp_header->icmp_cksum); - TRACE("expected type,code=8,0 id,seq=%d,%d cksum=%d\n", - id,seq, - cksum); - ier->Status=IP_REQ_TIMED_OUT; - } - } - } - } - - if (ier->Status==IP_REQ_TIMED_OUT) { - /* This packet was not for us. - * Decrease the timeout so that we don't enter an endless loop even - * if we get flooded with ICMP packets that are not for us. - */ - DWORD t = (recv_time - send_time); - if (Timeout > t) Timeout -= t; - else Timeout = 0; - continue; - } else { - /* This is a reply to our packet */ - memcpy(&ier->Address,&ip_header->ip_src,sizeof(IPAddr)); - /* Status is already set */ - ier->RoundTripTime= recv_time - send_time; - ier->DataSize=res-ip_header_len-ICMP_MINLEN; - ier->Reserved=0; - ier->Data=endbuf-ier->DataSize; - memmove(ier->Data,((char*)ip_header)+ip_header_len+ICMP_MINLEN,ier->DataSize); - ier->Options.Ttl=ip_header->ip_ttl; - ier->Options.Tos=ip_header->ip_tos; - ier->Options.Flags=ip_header->ip_off >> 13; - ier->Options.OptionsSize=ip_header_len-sizeof(struct ip); - if (ier->Options.OptionsSize!=0) { - ier->Options.OptionsData=(unsigned char *) ier->Data-ier->Options.OptionsSize; - /* FIXME: We are supposed to rearrange the option's 'source route' data */ - memmove(ier->Options.OptionsData,((char*)ip_header)+ip_header_len,ier->Options.OptionsSize); - endbuf=(char*)ier->Options.OptionsData; - } else { - ier->Options.OptionsData=NULL; - endbuf=ier->Data; - } - - /* Prepare for the next packet */ - ier++; - ip_header=(struct ip*)(((char*)ip_header)+sizeof(ICMP_ECHO_REPLY)); - maxlen=endbuf-(char*)ip_header; - - /* Check out whether there is more but don't wait this time */ - Timeout=0; - } - } - res=ier-(ICMP_ECHO_REPLY*)ReplyBuffer; - if (res==0) - SetLastError(IP_REQ_TIMED_OUT); - TRACE("received %d replies\n",res); - return res; -} - -/* - * Copyright (c) 1989 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Mike Muuss. - * - * 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. 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. - * - */ diff --git a/dlls/icmp/ip.h b/dlls/icmp/ip.h deleted file mode 100644 index 9c669d9..0000000 --- a/dlls/icmp/ip.h +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 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. 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.h 8.2 (Berkeley) 6/1/94 - * $FreeBSD: src/sys/netinet/ip.h,v 1.16 1999/08/28 00:49:19 peter Exp $ - */ - -#ifndef _NETINET_IP_H_ -#define _NETINET_IP_H_ - -/* - * Definitions for internet protocol version 4. - * Per RFC 791, September 1981. - */ -#define IPVERSION 4 - -/* - * Structure of an internet header, naked of options. - */ -struct ip { -#ifdef _IP_VHL - u_char ip_vhl; /* version << 4 | header length >> 2 */ -#else -#if BYTE_ORDER == LITTLE_ENDIAN - u_int ip_hl:4, /* header length */ - ip_v:4; /* version */ -#endif -#if BYTE_ORDER == BIG_ENDIAN - u_int ip_v:4, /* version */ - ip_hl:4; /* header length */ -#endif -#endif /* not _IP_VHL */ - u_char ip_tos; /* type of service */ - u_short ip_len; /* total length */ - u_short ip_id; /* identification */ - u_short ip_off; /* fragment offset field */ -#define IP_RF 0x8000 /* reserved fragment flag */ -#define IP_DF 0x4000 /* don't fragment flag */ -#define IP_MF 0x2000 /* more fragments flag */ -#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ - u_char ip_ttl; /* time to live */ - u_char ip_p; /* protocol */ - u_short ip_sum; /* checksum */ - struct in_addr ip_src,ip_dst; /* source and dest address */ -}; - -#ifdef _IP_VHL -#define IP_MAKE_VHL(v, hl) ((v) << 4 | (hl)) -#define IP_VHL_HL(vhl) ((vhl) & 0x0f) -#define IP_VHL_V(vhl) ((vhl) >> 4) -#define IP_VHL_BORING 0x45 -#endif - -#define IP_MAXPACKET 65535 /* maximum packet size */ - -/* - * Definitions for IP type of service (ip_tos) - */ -#define IPTOS_LOWDELAY 0x10 -#define IPTOS_THROUGHPUT 0x08 -#define IPTOS_RELIABILITY 0x04 -#define IPTOS_MINCOST 0x02 - -/* - * Definitions for IP precedence (also in ip_tos) (hopefully unused) - */ -#define IPTOS_PREC_NETCONTROL 0xe0 -#define IPTOS_PREC_INTERNETCONTROL 0xc0 -#define IPTOS_PREC_CRITIC_ECP 0xa0 -#define IPTOS_PREC_FLASHOVERRIDE 0x80 -#define IPTOS_PREC_FLASH 0x60 -#define IPTOS_PREC_IMMEDIATE 0x40 -#define IPTOS_PREC_PRIORITY 0x20 -#define IPTOS_PREC_ROUTINE 0x00 - -/* - * Definitions for options. - */ -#define IPOPT_COPIED(o) ((o)&0x80) -#define IPOPT_CLASS(o) ((o)&0x60) -#define IPOPT_NUMBER(o) ((o)&0x1f) - -#define IPOPT_CONTROL 0x00 -#define IPOPT_RESERVED1 0x20 -#define IPOPT_DEBMEAS 0x40 -#define IPOPT_RESERVED2 0x60 - -#define IPOPT_EOL 0 /* end of option list */ -#define IPOPT_NOP 1 /* no operation */ - -#define IPOPT_RR 7 /* record packet route */ -#define IPOPT_TS 68 /* timestamp */ -#define IPOPT_SECURITY 130 /* provide s,c,h,tcc */ -#define IPOPT_LSRR 131 /* loose source route */ -#define IPOPT_SATID 136 /* satnet id */ -#define IPOPT_SSRR 137 /* strict source route */ -#define IPOPT_RA 148 /* router alert */ - -/* - * Offsets to fields in options other than EOL and NOP. - */ -#define IPOPT_OPTVAL 0 /* option ID */ -#define IPOPT_OLEN 1 /* option length */ -#define IPOPT_OFFSET 2 /* offset within option */ -#define IPOPT_MINOFF 4 /* min value of above */ - -/* - * Time stamp option structure. - */ -struct ip_timestamp { - u_char ipt_code; /* IPOPT_TS */ - u_char ipt_len; /* size of structure (variable) */ - u_char ipt_ptr; /* index of current entry */ -#if BYTE_ORDER == LITTLE_ENDIAN - u_int ipt_flg:4, /* flags, see below */ - ipt_oflw:4; /* overflow counter */ -#endif -#if BYTE_ORDER == BIG_ENDIAN - u_int ipt_oflw:4, /* overflow counter */ - ipt_flg:4; /* flags, see below */ -#endif - union ipt_timestamp { - n_long ipt_time[1]; - struct ipt_ta { - struct in_addr ipt_addr; - n_long ipt_time; - } ipt_ta[1]; - } ipt_timestamp; -}; - -/* flag bits for ipt_flg */ -#define IPOPT_TS_TSONLY 0 /* timestamps only */ -#define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */ -#define IPOPT_TS_PRESPEC 3 /* specified modules only */ - -/* bits for security (not byte swapped) */ -#define IPOPT_SECUR_UNCLASS 0x0000 -#define IPOPT_SECUR_CONFID 0xf135 -#define IPOPT_SECUR_EFTO 0x789a -#define IPOPT_SECUR_MMMM 0xbc4d -#define IPOPT_SECUR_RESTR 0xaf13 -#define IPOPT_SECUR_SECRET 0xd788 -#define IPOPT_SECUR_TOPSECRET 0x6bc5 - -/* - * Internet implementation parameters. - */ -#define MAXTTL 255 /* maximum time to live (seconds) */ -#define IPDEFTTL 64 /* default ttl, from RFC 1340 */ -#define IPFRAGTTL 60 /* time to live for frags, slowhz */ -#define IPTTLDEC 1 /* subtracted when forwarding */ - -#define IP_MSS 576 /* default maximum segment size */ - -#endif diff --git a/dlls/icmp/ip_icmp.h b/dlls/icmp/ip_icmp.h deleted file mode 100644 index ce54495..0000000 --- a/dlls/icmp/ip_icmp.h +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 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. 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.h 8.1 (Berkeley) 6/10/93 - * $FreeBSD: src/sys/netinet/ip_icmp.h,v 1.13 1999/08/28 00:49:24 peter Exp $ - */ - -#ifndef _NETINET_IP_ICMP_H_ -#define _NETINET_IP_ICMP_H_ - -/* - * Interface Control Message Protocol Definitions. - * Per RFC 792, September 1981. - */ - -/* - * Internal of an ICMP Router Advertisement - */ -struct icmp_ra_addr { - u_int32_t ira_addr; - u_int32_t ira_preference; -}; - -/* - * Structure of an icmp header. - */ -struct icmp { - u_char icmp_type; /* type of message, see below */ - u_char icmp_code; /* type sub code */ - u_short icmp_cksum; /* ones complement cksum of struct */ - union { - u_char ih_pptr; /* ICMP_PARAMPROB */ - struct in_addr ih_gwaddr; /* ICMP_REDIRECT */ - struct ih_idseq { - n_short icd_id; - n_short icd_seq; - } ih_idseq; - int ih_void; - - /* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */ - struct ih_pmtu { - n_short ipm_void; - n_short ipm_nextmtu; - } ih_pmtu; - - struct ih_rtradv { - u_char irt_num_addrs; - u_char irt_wpa; - u_int16_t irt_lifetime; - } ih_rtradv; - } icmp_hun; -#define icmp_pptr icmp_hun.ih_pptr -#define icmp_gwaddr icmp_hun.ih_gwaddr -#define icmp_id icmp_hun.ih_idseq.icd_id -#define icmp_seq icmp_hun.ih_idseq.icd_seq -#define icmp_void icmp_hun.ih_void -#define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void -#define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu -#define icmp_num_addrs icmp_hun.ih_rtradv.irt_num_addrs -#define icmp_wpa icmp_hun.ih_rtradv.irt_wpa -#define icmp_lifetime icmp_hun.ih_rtradv.irt_lifetime - union { - struct id_ts { - n_time its_otime; - n_time its_rtime; - n_time its_ttime; - } id_ts; - struct id_ip { - struct ip idi_ip; - /* options and then 64 bits of data */ - } id_ip; - struct icmp_ra_addr id_radv; - u_int32_t id_mask; - char id_data[1]; - } icmp_dun; -#define icmp_otime icmp_dun.id_ts.its_otime -#define icmp_rtime icmp_dun.id_ts.its_rtime -#define icmp_ttime icmp_dun.id_ts.its_ttime -#define icmp_ip icmp_dun.id_ip.idi_ip -#define icmp_radv icmp_dun.id_radv -#define icmp_mask icmp_dun.id_mask -#define icmp_data icmp_dun.id_data -}; - -/* - * Lower bounds on packet lengths for various types. - * For the error advice packets must first insure that the - * packet is large enough to contain the returned ip header. - * Only then can we do the check to see if 64 bits of packet - * data have been returned, since we need to check the returned - * ip header length. - */ -#define ICMP_MINLEN 8 /* abs minimum */ -#define ICMP_TSLEN (8 + 3 * sizeof (n_time)) /* timestamp */ -#define ICMP_MASKLEN 12 /* address mask */ -#define ICMP_ADVLENMIN (8 + sizeof (struct ip) + 8) /* min */ -#ifndef _IP_VHL -#define ICMP_ADVLEN(p) (8 + ((p)->icmp_ip.ip_hl << 2) + 8) - /* N.B.: must separately check that ip_hl >= 5 */ -#else -#define ICMP_ADVLEN(p) (8 + (IP_VHL_HL((p)->icmp_ip.ip_vhl) << 2) + 8) - /* N.B.: must separately check that header length >= 5 */ -#endif - -/* - * Definition of type and code field values. - */ -#define ICMP_ECHOREPLY 0 /* echo reply */ -#define ICMP_UNREACH 3 /* dest unreachable, codes: */ -#define ICMP_UNREACH_NET 0 /* bad net */ -#define ICMP_UNREACH_HOST 1 /* bad host */ -#define ICMP_UNREACH_PROTOCOL 2 /* bad protocol */ -#define ICMP_UNREACH_PORT 3 /* bad port */ -#define ICMP_UNREACH_NEEDFRAG 4 /* IP_DF caused drop */ -#define ICMP_UNREACH_SRCFAIL 5 /* src route failed */ -#define ICMP_UNREACH_NET_UNKNOWN 6 /* unknown net */ -#define ICMP_UNREACH_HOST_UNKNOWN 7 /* unknown host */ -#define ICMP_UNREACH_ISOLATED 8 /* src host isolated */ -#define ICMP_UNREACH_NET_PROHIB 9 /* prohibited access */ -#define ICMP_UNREACH_HOST_PROHIB 10 /* ditto */ -#define ICMP_UNREACH_TOSNET 11 /* bad tos for net */ -#define ICMP_UNREACH_TOSHOST 12 /* bad tos for host */ -#define ICMP_UNREACH_FILTER_PROHIB 13 /* admin prohib */ -#define ICMP_UNREACH_HOST_PRECEDENCE 14 /* host prec vio. */ -#define ICMP_UNREACH_PRECEDENCE_CUTOFF 15 /* prec cutoff */ -#define ICMP_SOURCEQUENCH 4 /* packet lost, slow down */ -#define ICMP_REDIRECT 5 /* shorter route, codes: */ -#define ICMP_REDIRECT_NET 0 /* for network */ -#define ICMP_REDIRECT_HOST 1 /* for host */ -#define ICMP_REDIRECT_TOSNET 2 /* for tos and net */ -#define ICMP_REDIRECT_TOSHOST 3 /* for tos and host */ -#define ICMP_ECHO 8 /* echo service */ -#define ICMP_ROUTERADVERT 9 /* router advertisement */ -#define ICMP_ROUTERSOLICIT 10 /* router solicitation */ -#define ICMP_TIMXCEED 11 /* time exceeded, code: */ -#define ICMP_TIMXCEED_INTRANS 0 /* ttl==0 in transit */ -#define ICMP_TIMXCEED_REASS 1 /* ttl==0 in reass */ -#define ICMP_PARAMPROB 12 /* ip header bad */ -#define ICMP_PARAMPROB_OPTABSENT 1 /* req. opt. absent */ -#define ICMP_TSTAMP 13 /* timestamp request */ -#define ICMP_TSTAMPREPLY 14 /* timestamp reply */ -#define ICMP_IREQ 15 /* information request */ -#define ICMP_IREQREPLY 16 /* information reply */ -#define ICMP_MASKREQ 17 /* address mask request */ -#define ICMP_MASKREPLY 18 /* address mask reply */ - -#define ICMP_MAXTYPE 18 - -#define ICMP_INFOTYPE(type) \ - ((type) == ICMP_ECHOREPLY || (type) == ICMP_ECHO || \ - (type) == ICMP_ROUTERADVERT || (type) == ICMP_ROUTERSOLICIT || \ - (type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY || \ - (type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \ - (type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY) - -#ifdef KERNEL -void icmp_error __P((struct mbuf *, int, int, n_long, struct ifnet *)); -void icmp_input __P((struct mbuf *, int)); -#endif - -#endif diff --git a/dlls/iphlpapi/Makefile.in b/dlls/iphlpapi/Makefile.in index b52a1c0..76315af 100644 --- a/dlls/iphlpapi/Makefile.in +++ b/dlls/iphlpapi/Makefile.in @@ -8,6 +8,7 @@ IMPORTS = advapi32 kernel32 EXTRALIBS = @RESOLVLIBS@ C_SRCS = \ + icmp.c \ ifenum.c \ iphlpapi_main.c \ ipstats.c diff --git a/dlls/iphlpapi/icmp.c b/dlls/iphlpapi/icmp.c new file mode 100644 index 0000000..dd28065 --- /dev/null +++ b/dlls/iphlpapi/icmp.c @@ -0,0 +1,510 @@ +/* + * ICMP + * + * Francois Gouget, 1999, based on the work of + * RW Hall, 1999, based on public domain code PING.C by Mike Muus (1983) + * and later works (c) 1989 Regents of Univ. of California - see copyright + * notice at end of source-code. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* Future work: + * - Systems like FreeBSD don't seem to support the IP_TTL option and maybe others. + * But using IP_HDRINCL and building the IP header by hand might work. + * - Not all IP options are supported. + * - Are ICMP handles real handles, i.e. inheritable and all? There might be some + * more work to do here, including server side stuff with synchronization. + * - Is it correct to use malloc for the internal buffer, for allocating the + * handle's structure? + * - This API should probably be thread safe. Is it really? + * - Using the winsock functions has not been tested. + */ + +#include "config.h" + +#include +#ifdef HAVE_SYS_SOCKET_H +# include +#endif +#ifdef HAVE_NETDB_H +# include +#endif +#ifdef HAVE_NETINET_IN_SYSTM_H +# include +#endif +#ifdef HAVE_NETINET_IN_H +# include +#endif + +#ifdef HAVE_SYS_TIME_H +# include +#endif +#include +#include +#include +#ifdef HAVE_UNISTD_H +# include +#endif +#ifdef HAVE_ARPA_INET_H +# include +#endif +#ifdef HAVE_SYS_POLL_H +# include +#endif + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "ipexport.h" +#include "icmpapi.h" +#include "wine/debug.h" + +/* Set up endianness macros for the ip and ip_icmp BSD headers */ +#ifndef BIG_ENDIAN +#define BIG_ENDIAN 4321 +#endif +#ifndef LITTLE_ENDIAN +#define LITTLE_ENDIAN 1234 +#endif +#ifndef BYTE_ORDER +#ifdef WORDS_BIGENDIAN +#define BYTE_ORDER BIG_ENDIAN +#else +#define BYTE_ORDER LITTLE_ENDIAN +#endif +#endif /* BYTE_ORDER */ + +#define u_int16_t WORD +#define u_int32_t DWORD + +/* These are BSD headers. We use these here because they are needed on + * libc5 Linux systems. On other platforms they are usually simply more + * complete than the native stuff, and cause less portability problems + * so we use them anyway. + */ +#include "ip.h" +#include "ip_icmp.h" + + +WINE_DEFAULT_DEBUG_CHANNEL(icmp); + + +typedef struct { + int sid; + IP_OPTION_INFORMATION default_opts; +} icmp_t; + +#define IP_OPTS_UNKNOWN 0 +#define IP_OPTS_DEFAULT 1 +#define IP_OPTS_CUSTOM 2 + +/* The sequence number is unique process wide, so that all threads + * have a distinct sequence number. + */ +static LONG icmp_sequence=0; + +static int in_cksum(u_short *addr, int len) +{ + int nleft=len; + u_short *w = addr; + int sum = 0; + u_short answer = 0; + + while (nleft > 1) { + sum += *w++; + nleft -= 2; + } + + if (nleft == 1) { + *(u_char *)(&answer) = *(u_char *)w; + sum += answer; + } + + sum = (sum >> 16) + (sum & 0xffff); + sum += (sum >> 16); + answer = ~sum; + return(answer); +} + + + +/* + * Exported Routines. + */ + +/*********************************************************************** + * IcmpCreateFile (IPHLPAPI.@) + */ +HANDLE WINAPI IcmpCreateFile(VOID) +{ + icmp_t* icp; + + int sid=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP); + if (sid < 0) { + MESSAGE("WARNING: Trying to use ICMP (network ping) will fail unless running as root\n"); + SetLastError(ERROR_ACCESS_DENIED); + return INVALID_HANDLE_VALUE; + } + + icp=HeapAlloc(GetProcessHeap(), 0, sizeof(*icp)); + if (icp==NULL) { + SetLastError(IP_NO_RESOURCES); + return INVALID_HANDLE_VALUE; + } + icp->sid=sid; + icp->default_opts.OptionsSize=IP_OPTS_UNKNOWN; + return (HANDLE)icp; +} + + +/*********************************************************************** + * IcmpCloseHandle (IPHLPAPI.@) + */ +BOOL WINAPI IcmpCloseHandle(HANDLE IcmpHandle) +{ + icmp_t* icp=(icmp_t*)IcmpHandle; + if (IcmpHandle==INVALID_HANDLE_VALUE) { + /* FIXME: in fact win98 seems to ignore the handle value !!! */ + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + + shutdown(icp->sid,2); + HeapFree(GetProcessHeap (), 0, icp); + return TRUE; +} + + +/*********************************************************************** + * IcmpSendEcho (IPHLPAPI.@) + */ +DWORD WINAPI IcmpSendEcho( + HANDLE IcmpHandle, + IPAddr DestinationAddress, + LPVOID RequestData, + WORD RequestSize, + PIP_OPTION_INFORMATION RequestOptions, + LPVOID ReplyBuffer, + DWORD ReplySize, + DWORD Timeout + ) +{ + icmp_t* icp=(icmp_t*)IcmpHandle; + unsigned char* reqbuf; + int reqsize; + + struct icmp_echo_reply* ier; + struct ip* ip_header; + struct icmp* icmp_header; + char* endbuf; + int ip_header_len; + int maxlen; + struct pollfd fdr; + DWORD send_time,recv_time; + struct sockaddr_in addr; + unsigned int addrlen; + unsigned short id,seq,cksum; + int res; + + if (IcmpHandle==INVALID_HANDLE_VALUE) { + /* FIXME: in fact win98 seems to ignore the handle value !!! */ + SetLastError(ERROR_INVALID_HANDLE); + return 0; + } + + if (ReplySizeicmp_type=ICMP_ECHO; + icmp_header->icmp_code=0; + icmp_header->icmp_cksum=0; + icmp_header->icmp_id=id; + icmp_header->icmp_seq=seq; + memcpy(reqbuf+ICMP_MINLEN, RequestData, RequestSize); + icmp_header->icmp_cksum=cksum=in_cksum((u_short*)reqbuf,reqsize); + + addr.sin_family=AF_INET; + addr.sin_addr.s_addr=DestinationAddress; + addr.sin_port=0; + + if (RequestOptions!=NULL) { + int val; + if (icp->default_opts.OptionsSize==IP_OPTS_UNKNOWN) { + unsigned int len; + /* Before we mess with the options, get the default values */ + len=sizeof(val); + getsockopt(icp->sid,IPPROTO_IP,IP_TTL,(char *)&val,&len); + icp->default_opts.Ttl=val; + + len=sizeof(val); + getsockopt(icp->sid,IPPROTO_IP,IP_TOS,(char *)&val,&len); + icp->default_opts.Tos=val; + /* FIXME: missing: handling of IP 'flags', and all the other options */ + } + + val=RequestOptions->Ttl; + setsockopt(icp->sid,IPPROTO_IP,IP_TTL,(char *)&val,sizeof(val)); + val=RequestOptions->Tos; + setsockopt(icp->sid,IPPROTO_IP,IP_TOS,(char *)&val,sizeof(val)); + /* FIXME: missing: handling of IP 'flags', and all the other options */ + + icp->default_opts.OptionsSize=IP_OPTS_CUSTOM; + } else if (icp->default_opts.OptionsSize==IP_OPTS_CUSTOM) { + int val; + + /* Restore the default options */ + val=icp->default_opts.Ttl; + setsockopt(icp->sid,IPPROTO_IP,IP_TTL,(char *)&val,sizeof(val)); + val=icp->default_opts.Tos; + setsockopt(icp->sid,IPPROTO_IP,IP_TOS,(char *)&val,sizeof(val)); + /* FIXME: missing: handling of IP 'flags', and all the other options */ + + icp->default_opts.OptionsSize=IP_OPTS_DEFAULT; + } + + /* Get ready for receiving the reply + * Do it before we send the request to minimize the risk of introducing delays + */ + fdr.fd = icp->sid; + fdr.events = POLLIN; + addrlen=sizeof(addr); + ier=ReplyBuffer; + ip_header=(struct ip *) ((char *) ReplyBuffer+sizeof(ICMP_ECHO_REPLY)); + endbuf=(char *) ReplyBuffer+ReplySize; + maxlen=ReplySize-sizeof(ICMP_ECHO_REPLY); + + /* Send the packet */ + TRACE("Sending %d bytes (RequestSize=%d) to %s\n", reqsize, RequestSize, inet_ntoa(addr.sin_addr)); +#if 0 + if (TRACE_ON(icmp)){ + unsigned char* buf=(unsigned char*)reqbuf; + int i; + printf("Output buffer:\n"); + for (i=0;isid, reqbuf, reqsize, 0, (struct sockaddr*)&addr, sizeof(addr)); + HeapFree(GetProcessHeap (), 0, reqbuf); + if (res<0) { + if (errno==EMSGSIZE) + SetLastError(IP_PACKET_TOO_BIG); + else { + switch (errno) { + case ENETUNREACH: + SetLastError(IP_DEST_NET_UNREACHABLE); + break; + case EHOSTUNREACH: + SetLastError(IP_DEST_HOST_UNREACHABLE); + break; + default: + TRACE("unknown error: errno=%d\n",errno); + SetLastError(IP_GENERAL_FAILURE); + } + } + return 0; + } + + /* Get the reply */ + ip_header_len=0; /* because gcc was complaining */ + while ((res=poll(&fdr,1,Timeout))>0) { + recv_time = GetTickCount(); + res=recvfrom(icp->sid, (char*)ip_header, maxlen, 0, (struct sockaddr*)&addr,&addrlen); + TRACE("received %d bytes from %s\n",res, inet_ntoa(addr.sin_addr)); + ier->Status=IP_REQ_TIMED_OUT; + + /* Check whether we should ignore this packet */ + if ((ip_header->ip_p==IPPROTO_ICMP) && (res>=sizeof(struct ip)+ICMP_MINLEN)) { + ip_header_len=ip_header->ip_hl << 2; + icmp_header=(struct icmp*)(((char*)ip_header)+ip_header_len); + TRACE("received an ICMP packet of type,code=%d,%d\n",icmp_header->icmp_type,icmp_header->icmp_code); + if (icmp_header->icmp_type==ICMP_ECHOREPLY) { + if ((icmp_header->icmp_id==id) && (icmp_header->icmp_seq==seq)) + ier->Status=IP_SUCCESS; + } else { + switch (icmp_header->icmp_type) { + case ICMP_UNREACH: + switch (icmp_header->icmp_code) { + case ICMP_UNREACH_HOST: +#ifdef ICMP_UNREACH_HOST_UNKNOWN + case ICMP_UNREACH_HOST_UNKNOWN: +#endif +#ifdef ICMP_UNREACH_ISOLATED + case ICMP_UNREACH_ISOLATED: +#endif +#ifdef ICMP_UNREACH_HOST_PROHIB + case ICMP_UNREACH_HOST_PROHIB: +#endif +#ifdef ICMP_UNREACH_TOSHOST + case ICMP_UNREACH_TOSHOST: +#endif + ier->Status=IP_DEST_HOST_UNREACHABLE; + break; + case ICMP_UNREACH_PORT: + ier->Status=IP_DEST_PORT_UNREACHABLE; + break; + case ICMP_UNREACH_PROTOCOL: + ier->Status=IP_DEST_PROT_UNREACHABLE; + break; + case ICMP_UNREACH_SRCFAIL: + ier->Status=IP_BAD_ROUTE; + break; + default: + ier->Status=IP_DEST_NET_UNREACHABLE; + } + break; + case ICMP_TIMXCEED: + if (icmp_header->icmp_code==ICMP_TIMXCEED_REASS) + ier->Status=IP_TTL_EXPIRED_REASSEM; + else + ier->Status=IP_TTL_EXPIRED_TRANSIT; + break; + case ICMP_PARAMPROB: + ier->Status=IP_PARAM_PROBLEM; + break; + case ICMP_SOURCEQUENCH: + ier->Status=IP_SOURCE_QUENCH; + break; + } + if (ier->Status!=IP_REQ_TIMED_OUT) { + struct ip* rep_ip_header; + struct icmp* rep_icmp_header; + /* The ICMP header size of all the packets we accept is the same */ + rep_ip_header=(struct ip*)(((char*)icmp_header)+ICMP_MINLEN); + rep_icmp_header=(struct icmp*)(((char*)rep_ip_header)+(rep_ip_header->ip_hl << 2)); + + /* Make sure that this is really a reply to our packet */ + if (ip_header_len+ICMP_MINLEN+(rep_ip_header->ip_hl << 2)+ICMP_MINLEN>ip_header->ip_len) { + ier->Status=IP_REQ_TIMED_OUT; + } else if ((rep_icmp_header->icmp_type!=ICMP_ECHO) || + (rep_icmp_header->icmp_code!=0) || + (rep_icmp_header->icmp_id!=id) || + /* windows doesn't check this checksum, else tracert */ + /* behind a Linux 2.2 masquerading firewall would fail*/ + /* (rep_icmp_header->icmp_cksum!=cksum) || */ + (rep_icmp_header->icmp_seq!=seq)) { + /* This was not a reply to one of our packets after all */ + TRACE("skipping type,code=%d,%d id,seq=%d,%d cksum=%d\n", + rep_icmp_header->icmp_type,rep_icmp_header->icmp_code, + rep_icmp_header->icmp_id,rep_icmp_header->icmp_seq, + rep_icmp_header->icmp_cksum); + TRACE("expected type,code=8,0 id,seq=%d,%d cksum=%d\n", + id,seq, + cksum); + ier->Status=IP_REQ_TIMED_OUT; + } + } + } + } + + if (ier->Status==IP_REQ_TIMED_OUT) { + /* This packet was not for us. + * Decrease the timeout so that we don't enter an endless loop even + * if we get flooded with ICMP packets that are not for us. + */ + DWORD t = (recv_time - send_time); + if (Timeout > t) Timeout -= t; + else Timeout = 0; + continue; + } else { + /* This is a reply to our packet */ + memcpy(&ier->Address,&ip_header->ip_src,sizeof(IPAddr)); + /* Status is already set */ + ier->RoundTripTime= recv_time - send_time; + ier->DataSize=res-ip_header_len-ICMP_MINLEN; + ier->Reserved=0; + ier->Data=endbuf-ier->DataSize; + memmove(ier->Data,((char*)ip_header)+ip_header_len+ICMP_MINLEN,ier->DataSize); + ier->Options.Ttl=ip_header->ip_ttl; + ier->Options.Tos=ip_header->ip_tos; + ier->Options.Flags=ip_header->ip_off >> 13; + ier->Options.OptionsSize=ip_header_len-sizeof(struct ip); + if (ier->Options.OptionsSize!=0) { + ier->Options.OptionsData=(unsigned char *) ier->Data-ier->Options.OptionsSize; + /* FIXME: We are supposed to rearrange the option's 'source route' data */ + memmove(ier->Options.OptionsData,((char*)ip_header)+ip_header_len,ier->Options.OptionsSize); + endbuf=(char*)ier->Options.OptionsData; + } else { + ier->Options.OptionsData=NULL; + endbuf=ier->Data; + } + + /* Prepare for the next packet */ + ier++; + ip_header=(struct ip*)(((char*)ip_header)+sizeof(ICMP_ECHO_REPLY)); + maxlen=endbuf-(char*)ip_header; + + /* Check out whether there is more but don't wait this time */ + Timeout=0; + } + } + res=ier-(ICMP_ECHO_REPLY*)ReplyBuffer; + if (res==0) + SetLastError(IP_REQ_TIMED_OUT); + TRACE("received %d replies\n",res); + return res; +} + +/* + * Copyright (c) 1989 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Mike Muuss. + * + * 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. 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. + * + */ diff --git a/dlls/iphlpapi/ip.h b/dlls/iphlpapi/ip.h new file mode 100644 index 0000000..9c669d9 --- /dev/null +++ b/dlls/iphlpapi/ip.h @@ -0,0 +1,180 @@ +/* + * Copyright (c) 1982, 1986, 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. 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.h 8.2 (Berkeley) 6/1/94 + * $FreeBSD: src/sys/netinet/ip.h,v 1.16 1999/08/28 00:49:19 peter Exp $ + */ + +#ifndef _NETINET_IP_H_ +#define _NETINET_IP_H_ + +/* + * Definitions for internet protocol version 4. + * Per RFC 791, September 1981. + */ +#define IPVERSION 4 + +/* + * Structure of an internet header, naked of options. + */ +struct ip { +#ifdef _IP_VHL + u_char ip_vhl; /* version << 4 | header length >> 2 */ +#else +#if BYTE_ORDER == LITTLE_ENDIAN + u_int ip_hl:4, /* header length */ + ip_v:4; /* version */ +#endif +#if BYTE_ORDER == BIG_ENDIAN + u_int ip_v:4, /* version */ + ip_hl:4; /* header length */ +#endif +#endif /* not _IP_VHL */ + u_char ip_tos; /* type of service */ + u_short ip_len; /* total length */ + u_short ip_id; /* identification */ + u_short ip_off; /* fragment offset field */ +#define IP_RF 0x8000 /* reserved fragment flag */ +#define IP_DF 0x4000 /* don't fragment flag */ +#define IP_MF 0x2000 /* more fragments flag */ +#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ + u_char ip_ttl; /* time to live */ + u_char ip_p; /* protocol */ + u_short ip_sum; /* checksum */ + struct in_addr ip_src,ip_dst; /* source and dest address */ +}; + +#ifdef _IP_VHL +#define IP_MAKE_VHL(v, hl) ((v) << 4 | (hl)) +#define IP_VHL_HL(vhl) ((vhl) & 0x0f) +#define IP_VHL_V(vhl) ((vhl) >> 4) +#define IP_VHL_BORING 0x45 +#endif + +#define IP_MAXPACKET 65535 /* maximum packet size */ + +/* + * Definitions for IP type of service (ip_tos) + */ +#define IPTOS_LOWDELAY 0x10 +#define IPTOS_THROUGHPUT 0x08 +#define IPTOS_RELIABILITY 0x04 +#define IPTOS_MINCOST 0x02 + +/* + * Definitions for IP precedence (also in ip_tos) (hopefully unused) + */ +#define IPTOS_PREC_NETCONTROL 0xe0 +#define IPTOS_PREC_INTERNETCONTROL 0xc0 +#define IPTOS_PREC_CRITIC_ECP 0xa0 +#define IPTOS_PREC_FLASHOVERRIDE 0x80 +#define IPTOS_PREC_FLASH 0x60 +#define IPTOS_PREC_IMMEDIATE 0x40 +#define IPTOS_PREC_PRIORITY 0x20 +#define IPTOS_PREC_ROUTINE 0x00 + +/* + * Definitions for options. + */ +#define IPOPT_COPIED(o) ((o)&0x80) +#define IPOPT_CLASS(o) ((o)&0x60) +#define IPOPT_NUMBER(o) ((o)&0x1f) + +#define IPOPT_CONTROL 0x00 +#define IPOPT_RESERVED1 0x20 +#define IPOPT_DEBMEAS 0x40 +#define IPOPT_RESERVED2 0x60 + +#define IPOPT_EOL 0 /* end of option list */ +#define IPOPT_NOP 1 /* no operation */ + +#define IPOPT_RR 7 /* record packet route */ +#define IPOPT_TS 68 /* timestamp */ +#define IPOPT_SECURITY 130 /* provide s,c,h,tcc */ +#define IPOPT_LSRR 131 /* loose source route */ +#define IPOPT_SATID 136 /* satnet id */ +#define IPOPT_SSRR 137 /* strict source route */ +#define IPOPT_RA 148 /* router alert */ + +/* + * Offsets to fields in options other than EOL and NOP. + */ +#define IPOPT_OPTVAL 0 /* option ID */ +#define IPOPT_OLEN 1 /* option length */ +#define IPOPT_OFFSET 2 /* offset within option */ +#define IPOPT_MINOFF 4 /* min value of above */ + +/* + * Time stamp option structure. + */ +struct ip_timestamp { + u_char ipt_code; /* IPOPT_TS */ + u_char ipt_len; /* size of structure (variable) */ + u_char ipt_ptr; /* index of current entry */ +#if BYTE_ORDER == LITTLE_ENDIAN + u_int ipt_flg:4, /* flags, see below */ + ipt_oflw:4; /* overflow counter */ +#endif +#if BYTE_ORDER == BIG_ENDIAN + u_int ipt_oflw:4, /* overflow counter */ + ipt_flg:4; /* flags, see below */ +#endif + union ipt_timestamp { + n_long ipt_time[1]; + struct ipt_ta { + struct in_addr ipt_addr; + n_long ipt_time; + } ipt_ta[1]; + } ipt_timestamp; +}; + +/* flag bits for ipt_flg */ +#define IPOPT_TS_TSONLY 0 /* timestamps only */ +#define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */ +#define IPOPT_TS_PRESPEC 3 /* specified modules only */ + +/* bits for security (not byte swapped) */ +#define IPOPT_SECUR_UNCLASS 0x0000 +#define IPOPT_SECUR_CONFID 0xf135 +#define IPOPT_SECUR_EFTO 0x789a +#define IPOPT_SECUR_MMMM 0xbc4d +#define IPOPT_SECUR_RESTR 0xaf13 +#define IPOPT_SECUR_SECRET 0xd788 +#define IPOPT_SECUR_TOPSECRET 0x6bc5 + +/* + * Internet implementation parameters. + */ +#define MAXTTL 255 /* maximum time to live (seconds) */ +#define IPDEFTTL 64 /* default ttl, from RFC 1340 */ +#define IPFRAGTTL 60 /* time to live for frags, slowhz */ +#define IPTTLDEC 1 /* subtracted when forwarding */ + +#define IP_MSS 576 /* default maximum segment size */ + +#endif diff --git a/dlls/iphlpapi/ip_icmp.h b/dlls/iphlpapi/ip_icmp.h new file mode 100644 index 0000000..ce54495 --- /dev/null +++ b/dlls/iphlpapi/ip_icmp.h @@ -0,0 +1,186 @@ +/* + * Copyright (c) 1982, 1986, 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. 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.h 8.1 (Berkeley) 6/10/93 + * $FreeBSD: src/sys/netinet/ip_icmp.h,v 1.13 1999/08/28 00:49:24 peter Exp $ + */ + +#ifndef _NETINET_IP_ICMP_H_ +#define _NETINET_IP_ICMP_H_ + +/* + * Interface Control Message Protocol Definitions. + * Per RFC 792, September 1981. + */ + +/* + * Internal of an ICMP Router Advertisement + */ +struct icmp_ra_addr { + u_int32_t ira_addr; + u_int32_t ira_preference; +}; + +/* + * Structure of an icmp header. + */ +struct icmp { + u_char icmp_type; /* type of message, see below */ + u_char icmp_code; /* type sub code */ + u_short icmp_cksum; /* ones complement cksum of struct */ + union { + u_char ih_pptr; /* ICMP_PARAMPROB */ + struct in_addr ih_gwaddr; /* ICMP_REDIRECT */ + struct ih_idseq { + n_short icd_id; + n_short icd_seq; + } ih_idseq; + int ih_void; + + /* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */ + struct ih_pmtu { + n_short ipm_void; + n_short ipm_nextmtu; + } ih_pmtu; + + struct ih_rtradv { + u_char irt_num_addrs; + u_char irt_wpa; + u_int16_t irt_lifetime; + } ih_rtradv; + } icmp_hun; +#define icmp_pptr icmp_hun.ih_pptr +#define icmp_gwaddr icmp_hun.ih_gwaddr +#define icmp_id icmp_hun.ih_idseq.icd_id +#define icmp_seq icmp_hun.ih_idseq.icd_seq +#define icmp_void icmp_hun.ih_void +#define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void +#define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu +#define icmp_num_addrs icmp_hun.ih_rtradv.irt_num_addrs +#define icmp_wpa icmp_hun.ih_rtradv.irt_wpa +#define icmp_lifetime icmp_hun.ih_rtradv.irt_lifetime + union { + struct id_ts { + n_time its_otime; + n_time its_rtime; + n_time its_ttime; + } id_ts; + struct id_ip { + struct ip idi_ip; + /* options and then 64 bits of data */ + } id_ip; + struct icmp_ra_addr id_radv; + u_int32_t id_mask; + char id_data[1]; + } icmp_dun; +#define icmp_otime icmp_dun.id_ts.its_otime +#define icmp_rtime icmp_dun.id_ts.its_rtime +#define icmp_ttime icmp_dun.id_ts.its_ttime +#define icmp_ip icmp_dun.id_ip.idi_ip +#define icmp_radv icmp_dun.id_radv +#define icmp_mask icmp_dun.id_mask +#define icmp_data icmp_dun.id_data +}; + +/* + * Lower bounds on packet lengths for various types. + * For the error advice packets must first insure that the + * packet is large enough to contain the returned ip header. + * Only then can we do the check to see if 64 bits of packet + * data have been returned, since we need to check the returned + * ip header length. + */ +#define ICMP_MINLEN 8 /* abs minimum */ +#define ICMP_TSLEN (8 + 3 * sizeof (n_time)) /* timestamp */ +#define ICMP_MASKLEN 12 /* address mask */ +#define ICMP_ADVLENMIN (8 + sizeof (struct ip) + 8) /* min */ +#ifndef _IP_VHL +#define ICMP_ADVLEN(p) (8 + ((p)->icmp_ip.ip_hl << 2) + 8) + /* N.B.: must separately check that ip_hl >= 5 */ +#else +#define ICMP_ADVLEN(p) (8 + (IP_VHL_HL((p)->icmp_ip.ip_vhl) << 2) + 8) + /* N.B.: must separately check that header length >= 5 */ +#endif + +/* + * Definition of type and code field values. + */ +#define ICMP_ECHOREPLY 0 /* echo reply */ +#define ICMP_UNREACH 3 /* dest unreachable, codes: */ +#define ICMP_UNREACH_NET 0 /* bad net */ +#define ICMP_UNREACH_HOST 1 /* bad host */ +#define ICMP_UNREACH_PROTOCOL 2 /* bad protocol */ +#define ICMP_UNREACH_PORT 3 /* bad port */ +#define ICMP_UNREACH_NEEDFRAG 4 /* IP_DF caused drop */ +#define ICMP_UNREACH_SRCFAIL 5 /* src route failed */ +#define ICMP_UNREACH_NET_UNKNOWN 6 /* unknown net */ +#define ICMP_UNREACH_HOST_UNKNOWN 7 /* unknown host */ +#define ICMP_UNREACH_ISOLATED 8 /* src host isolated */ +#define ICMP_UNREACH_NET_PROHIB 9 /* prohibited access */ +#define ICMP_UNREACH_HOST_PROHIB 10 /* ditto */ +#define ICMP_UNREACH_TOSNET 11 /* bad tos for net */ +#define ICMP_UNREACH_TOSHOST 12 /* bad tos for host */ +#define ICMP_UNREACH_FILTER_PROHIB 13 /* admin prohib */ +#define ICMP_UNREACH_HOST_PRECEDENCE 14 /* host prec vio. */ +#define ICMP_UNREACH_PRECEDENCE_CUTOFF 15 /* prec cutoff */ +#define ICMP_SOURCEQUENCH 4 /* packet lost, slow down */ +#define ICMP_REDIRECT 5 /* shorter route, codes: */ +#define ICMP_REDIRECT_NET 0 /* for network */ +#define ICMP_REDIRECT_HOST 1 /* for host */ +#define ICMP_REDIRECT_TOSNET 2 /* for tos and net */ +#define ICMP_REDIRECT_TOSHOST 3 /* for tos and host */ +#define ICMP_ECHO 8 /* echo service */ +#define ICMP_ROUTERADVERT 9 /* router advertisement */ +#define ICMP_ROUTERSOLICIT 10 /* router solicitation */ +#define ICMP_TIMXCEED 11 /* time exceeded, code: */ +#define ICMP_TIMXCEED_INTRANS 0 /* ttl==0 in transit */ +#define ICMP_TIMXCEED_REASS 1 /* ttl==0 in reass */ +#define ICMP_PARAMPROB 12 /* ip header bad */ +#define ICMP_PARAMPROB_OPTABSENT 1 /* req. opt. absent */ +#define ICMP_TSTAMP 13 /* timestamp request */ +#define ICMP_TSTAMPREPLY 14 /* timestamp reply */ +#define ICMP_IREQ 15 /* information request */ +#define ICMP_IREQREPLY 16 /* information reply */ +#define ICMP_MASKREQ 17 /* address mask request */ +#define ICMP_MASKREPLY 18 /* address mask reply */ + +#define ICMP_MAXTYPE 18 + +#define ICMP_INFOTYPE(type) \ + ((type) == ICMP_ECHOREPLY || (type) == ICMP_ECHO || \ + (type) == ICMP_ROUTERADVERT || (type) == ICMP_ROUTERSOLICIT || \ + (type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY || \ + (type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \ + (type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY) + +#ifdef KERNEL +void icmp_error __P((struct mbuf *, int, int, n_long, struct ifnet *)); +void icmp_input __P((struct mbuf *, int)); +#endif + +#endif diff --git a/dlls/iphlpapi/iphlpapi.spec b/dlls/iphlpapi/iphlpapi.spec index 5ea43c5..c31dc49 100644 --- a/dlls/iphlpapi/iphlpapi.spec +++ b/dlls/iphlpapi/iphlpapi.spec @@ -54,6 +54,11 @@ @ stdcall GetUdpTable( ptr ptr long ) @ stub GetUdpTableFromStack @ stdcall GetUniDirectionalAdapterInfo( ptr ptr ) +@ stdcall IcmpCloseHandle(ptr) +@ stdcall IcmpCreateFile() +@ stub IcmpParseReplies +@ stub IcmpSendEcho2 +@ stdcall IcmpSendEcho(ptr long ptr long ptr ptr long long) @ stub InternalCreateIpForwardEntry @ stub InternalCreateIpNetEntry @ stub InternalDeleteIpForwardEntry -- 1.4.1