Index: trunk/src/icmp/.depend
===================================================================
--- trunk/src/icmp/.depend	(revision 3569)
+++ 	(revision )
@@ -1,163 +1,0 @@
-$(OBJDIR)\icmp.obj: \
-    o:\odin\src\icmp\icmp.cpp \
-    d:\ibmcpp\include\sys\types.h \
-    d:\ibmcpp\include\time.h \
-    d:\ibmcpp\include\malloc.h \
-    d:\ibmcpp\include\string.h \
-    d:\ibmcpp\include\errno.h \
-    o:\odin\include\win\windef.h \
-    o:\odin\include\win\winbase.h \
-    o:\odin\include\win\winsock.h \
-    o:\odin\include\win\winerror.h \
-    d:\toolkit\h\netinet\in_systm.h \
-    d:\toolkit\h\netinet\ip.h \
-    d:\ibmcpp\include\process.h \
-    o:\odin\include\win\ipexport.h \
-    o:\odin\include\win\icmpapi.h \
-    o:\odin\src\icmp\icmp.h \
-    o:\odin\include\misc.h
-
-o:\odin\include\codepage.h: \
-    d:\toolkit\h\uconv.h
-
-o:\odin\include\comtype.h:
-
-o:\odin\include\cpuhlp.h:
-
-o:\odin\include\dcdata.h:
-
-o:\odin\include\exceptions.h: \
-    o:\odin\include\win32type.h \
-    o:\odin\include\misc.h
-
-o:\odin\include\excpt.h:
-
-o:\odin\include\exitlist.h:
-
-o:\odin\include\handlemanager.h: \
-    o:\odin\include\winos2def.h
-
-o:\odin\include\heap.h: \
-    o:\odin\include\win\winbase.h
-
-o:\odin\include\heapcode.h: \
-    o:\odin\include\heapshared.h
-
-o:\odin\include\heapshared.h: \
-    d:\ibmcpp\include\stddef.h \
-    d:\ibmcpp\include\stdlib.h \
-    d:\ibmcpp\include\umalloc.h
-
-o:\odin\include\heapstring.h: \
-    o:\odin\include\odin.h
-
-o:\odin\include\midimapr.h:
-
-o:\odin\include\misc.h: \
-    o:\odin\include\win32type.h \
-    d:\ibmcpp\include\builtin.h \
-    o:\odin\include\versionos2.h \
-    o:\odin\include\unicode.h
-
-o:\odin\include\nameid.h:
-
-o:\odin\include\odin.h: \
-    d:\ibmcpp\include\builtin.h
-
-o:\odin\include\odin32validate.h:
-
-o:\odin\include\odininst.h:
-
-o:\odin\include\odinlx.h:
-
-o:\odin\include\odinrsrc.h:
-
-o:\odin\include\odinwrap.h: \
-    o:\odin\include\os2sel.h \
-    d:\ibmcpp\include\malloc.h
-
-o:\odin\include\os2mewrap.h: \
-    d:\toolkit\h\os2me.h
-
-o:\odin\include\os2newapi.h:
-
-o:\odin\include\os2sel.h:
-
-o:\odin\include\os2win.h: \
-    o:\odin\include\win32type.h \
-    o:\odin\include\odin.h \
-    o:\odin\include\win\windef.h \
-    o:\odin\include\win\winbase.h \
-    o:\odin\include\win\wingdi.h \
-    o:\odin\include\win\winuser.h \
-    o:\odin\include\win\winerror.h \
-    o:\odin\include\win\commdlg.h \
-    o:\odin\include\win\ddeml.h \
-    o:\odin\include\win\mmsystem.h \
-    o:\odin\include\os2sel.h \
-    o:\odin\include\misc.h
-
-o:\odin\include\os2wrap.h: \
-    d:\toolkit\h\os2.h \
-    o:\odin\include\os2sel.h \
-    o:\odin\include\os2newapi.h
-
-o:\odin\include\pefile.h: \
-    o:\odin\include\os2wrap.h \
-    o:\odin\include\win32type.h \
-    o:\odin\include\win\peexe.h \
-    d:\ibmcpp\include\stdlib.h
-
-o:\odin\include\pmmenu.h:
-
-o:\odin\include\spy.h:
-
-o:\odin\include\unicode.h: \
-    o:\odin\include\uniconv.h
-
-o:\odin\include\uniconv.h: \
-    d:\ibmcpp\include\stddef.h \
-    d:\ibmcpp\include\time.h
-
-o:\odin\include\versionos2.h:
-
-o:\odin\include\vmutex.h:
-
-o:\odin\include\vsemaphore.h:
-
-o:\odin\include\win32api.h: \
-    o:\odin\include\win32type.h \
-    o:\odin\include\winconst.h
-
-o:\odin\include\win32type.h: \
-    o:\odin\include\odin.h
-
-o:\odin\include\win32util.h:
-
-o:\odin\include\win32wnd.h:
-
-o:\odin\include\winaccel.h:
-
-o:\odin\include\winconst.h:
-
-o:\odin\include\wincursor.h:
-
-o:\odin\include\wineuni.h:
-
-o:\odin\include\winicon.h:
-
-o:\odin\include\winkeyboard.h:
-
-o:\odin\include\winmenu.h:
-
-o:\odin\include\winos2def.h:
-
-o:\odin\include\winres.h:
-
-o:\odin\include\wprocess.h: \
-    o:\odin\include\win\winprocess.h \
-    o:\odin\include\winconst.h \
-    o:\odin\include\win\thread.h
-
-o:\odin\src\icmp\icmp.h:
-
Index: trunk/src/icmp/icmp.cpp
===================================================================
--- trunk/src/icmp/icmp.cpp	(revision 3570)
+++ trunk/src/icmp/icmp.cpp	(revision 3570)
@@ -0,0 +1,466 @@
+/*
+ * 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.
+ */
+
+/* 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 <sys/types.h>
+#include <time.h>
+#include <malloc.h>
+#include <string.h>
+#include <errno.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winsock.h"
+#include "winerror.h"
+
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+
+#include <process.h>
+
+#include <ipexport.h>
+#include <icmpapi.h>
+
+#include "icmp.h"
+
+#include <misc.h>
+
+#define ISOCK_SOCKET                SOCKET
+#define ISOCK_ISVALID(a)            ((a)!=INVALID_SOCKET)
+#define ISOCK_getsockopt(a,b,c,d,e) getsockopt(a,b,c,d,e)
+#define ISOCK_recvfrom(a,b,c,d,e,f) recvfrom(a,b,c,d,e,f)
+#define ISOCK_select(a,b,c,d,e)     select(a,b,c,d,e)
+#define ISOCK_sendto(a,b,c,d,e,f)   sendto(a,b,c,d,e,f)
+#define ISOCK_setsockopt(a,b,c,d,e) setsockopt(a,b,c,d,e)
+#define ISOCK_shutdown(a,b)         shutdown(a,b)
+#define ISOCK_socket(a,b,c)         socket(a,b,c)
+
+typedef struct {
+    ISOCK_SOCKET 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;
+
+/* Odin specific - private def of gettimeofday func */
+void gettimeofday(struct timeval *t,struct timezone *z)
+{
+  t->tv_sec=clock();
+  t->tv_usec=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
+ */
+HANDLE WINAPI IcmpCreateFile(VOID)
+{
+    icmp_t* icp;
+
+    ISOCK_SOCKET sid=ISOCK_socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);
+    if (!ISOCK_ISVALID(sid)) {
+        SetLastError(ERROR_ACCESS_DENIED);
+        return INVALID_HANDLE_VALUE;
+    }
+
+    icp=(icmp_t *)malloc(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
+ */
+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;
+    }
+
+    ISOCK_shutdown(icp->sid,2);
+    free(icp);
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *              IcmpSendEcho
+ */
+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;
+    fd_set fdr;
+    struct timeval timeout,send_time,recv_time;
+    struct sockaddr_in addr;
+    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 (ReplySize<sizeof(ICMP_ECHO_REPLY)+ICMP_MINLEN) {
+        SetLastError(IP_BUF_TOO_SMALL);
+        return 0;
+    }
+    /* check the request size against SO_MAX_MSG_SIZE using getsockopt */
+
+    /* Prepare the request */
+    id=getpid() & 0xFFFF;
+    seq=InterlockedIncrement(&icmp_sequence) & 0xFFFF;
+
+    reqsize=ICMP_MINLEN+RequestSize;
+    reqbuf=(unsigned char *)malloc(reqsize);
+    if (reqbuf==NULL) {
+        SetLastError(ERROR_OUTOFMEMORY);
+        return 0;
+    }
+
+    icmp_header=(struct icmp*)reqbuf;
+    icmp_header->icmp_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) {
+            int len;
+            /* Before we mess with the options, get the default values */
+            len=sizeof(val);
+            ISOCK_getsockopt(icp->sid,IPPROTO_IP,IP_TTL,(char *)&val,&len);
+            icp->default_opts.Ttl=val;
+
+            len=sizeof(val);
+            ISOCK_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;
+        ISOCK_setsockopt(icp->sid,IPPROTO_IP,IP_TTL,(char *)&val,sizeof(val));
+        val=RequestOptions->Tos;
+        ISOCK_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;
+        ISOCK_setsockopt(icp->sid,IPPROTO_IP,IP_TTL,(char *)&val,sizeof(val));
+        val=icp->default_opts.Tos;
+        ISOCK_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
+     */
+    FD_ZERO(&fdr);
+    FD_SET(icp->sid,&fdr);
+    timeout.tv_sec=Timeout/1000;
+    timeout.tv_usec=(Timeout % 1000)*1000;
+    addrlen=sizeof(addr);
+    ier=(struct icmp_echo_reply *)ReplyBuffer;
+    ip_header=(struct ip *) ((char *) ReplyBuffer+sizeof(ICMP_ECHO_REPLY));
+    endbuf=(char *) ReplyBuffer+ReplySize;
+    maxlen=ReplySize-sizeof(ICMP_ECHO_REPLY);
+
+    /* Send the packet */
+    dprintf(("ICMP: Sending %d bytes (RequestSize=%d) to %s\n", reqsize, RequestSize, inet_ntoa(addr.sin_addr)));
+
+    gettimeofday(&send_time,NULL);
+    res=ISOCK_sendto(icp->sid, (const char *)reqbuf, reqsize, 0, (struct sockaddr*)&addr, sizeof(addr));
+    free(reqbuf);
+    if (res<0) {
+        if (errno==WSAEMSGSIZE)
+            SetLastError(IP_PACKET_TOO_BIG);
+        else {
+            switch (errno) {
+            case WSAENETUNREACH:
+                SetLastError(IP_DEST_NET_UNREACHABLE);
+                break;
+            case WSAEHOSTUNREACH:
+                SetLastError(IP_DEST_NET_UNREACHABLE);
+                break;
+            default:
+                dprintf(("ICMP: unknown error: errno=%d\n",errno));
+                SetLastError(ERROR_UNKNOWN);
+            }
+        }
+        return 0;
+    }
+
+    /* Get the reply */
+    ip_header_len=0; /* because gcc was complaining */
+    while ((res=ISOCK_select(icp->sid+1,&fdr,NULL,NULL,&timeout))>0) {
+        gettimeofday(&recv_time,NULL);
+        res=ISOCK_recvfrom(icp->sid, (char*)ip_header, maxlen, 0, (struct sockaddr*)&addr,&addrlen);
+        dprintf(("ICMP: 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);
+            dprintf(("ICMP: 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) ||
+                        (rep_icmp_header->icmp_seq!=seq) ||
+                        (rep_icmp_header->icmp_cksum!=cksum)) {
+                        /* This was not a reply to one of our packets after all */
+                        dprintf(("ICMP: 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));
+                        dprintf(("ICMP: 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.
+             */
+            timeout.tv_sec=Timeout/1000-(recv_time.tv_sec-send_time.tv_sec);
+            timeout.tv_usec=(Timeout % 1000)*1000+send_time.tv_usec-(recv_time.tv_usec-send_time.tv_usec);
+            if (timeout.tv_usec<0) {
+                timeout.tv_usec+=1000000;
+                timeout.tv_sec--;
+            }
+            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.tv_sec-send_time.tv_sec)*1000+(recv_time.tv_usec-send_time.tv_usec)/1000;
+            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=(char *)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.tv_sec=0;
+            timeout.tv_usec=0;
+        }
+        FD_ZERO(&fdr);
+        FD_SET(icp->sid,&fdr);
+    }
+    res=ier-(ICMP_ECHO_REPLY*)ReplyBuffer;
+    if (res==0)
+        SetLastError(IP_REQ_TIMED_OUT);
+    dprintf(("ICMP: 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. 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.
+ *
+ */
Index: trunk/src/icmp/icmp.def
===================================================================
--- trunk/src/icmp/icmp.def	(revision 3570)
+++ trunk/src/icmp/icmp.def	(revision 3570)
@@ -0,0 +1,13 @@
+; $Id: icmp.def,v 1.1 2000-05-19 18:48:59 jeroen Exp $
+
+LIBRARY ICMP
+PROTMODE
+DATA MULTIPLE NONSHARED
+
+EXPORTS
+ IcmpCloseHandle = _IcmpCloseHandle@4      @1
+ IcmpCreateFile  = _IcmpCreateFile@0       @2
+ IcmpSendEcho    = _IcmpSendEcho@32        @3
+; do_echo_rep     = _do_echo_rep@0          @4
+; do_echo_req     = _do_echo_req@0          @5
+; register_icmp   = _register_icmp@0        @6
Index: trunk/src/icmp/icmp.h
===================================================================
--- trunk/src/icmp/icmp.h	(revision 3570)
+++ trunk/src/icmp/icmp.h	(revision 3570)
@@ -0,0 +1,184 @@
+/*
+ * 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. 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.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 $
+ */
+
+/*
+ * Interface Control Message Protocol Definitions.
+ * Per RFC 792, September 1981.
+ */
+
+/* Some internal defs */
+#define u_int16_t  WORD
+#define u_int32_t  DWORD
+
+/*
+ * 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)
Index: trunk/src/icmp/icmprsrc.orc
===================================================================
--- trunk/src/icmp/icmprsrc.orc	(revision 3570)
+++ trunk/src/icmp/icmprsrc.orc	(revision 3570)
@@ -0,0 +1,41 @@
+/* $Id: icmprsrc.orc,v 1.1 2000-05-19 18:48:59 jeroen Exp $ */
+
+#include "winuser.h"
+#include "odinrsrc.h"
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version (based on NT 4 SP3)
+//
+
+1 VERSIONINFO
+ FILEVERSION ODIN_FILEVERSION
+ PRODUCTVERSION ODIN_PRODUCTVERSION
+ FILEFLAGSMASK 0x3fL
+ FILEFLAGS 0xaL
+ FILEOS 0x10001L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904E4"
+        BEGIN
+            VALUE "Comments", "Odin32 System Dll\0"
+            VALUE "CompanyName", "Odin Team\0"
+            VALUE "FileDescription", "ICMP System dll\0"
+            VALUE "FileVersion", "4.57\0"
+            VALUE "InternalName", "ICMP\0"
+            VALUE "LegalCopyright", "Copyright (C) 2000\0"
+            VALUE "LegalTrademarks", "\0"
+            VALUE "OriginalFilename", "ICMP.DLL\0"
+            VALUE "ProductName", "Odin32 - ICMP\0"
+            VALUE "ProductVersion", "4.57\0"
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x409, 0x04E4
+    END
+END
Index: trunk/src/icmp/makefile
===================================================================
--- trunk/src/icmp/makefile	(revision 3570)
+++ trunk/src/icmp/makefile	(revision 3570)
@@ -0,0 +1,70 @@
+# $Id: makefile,v 1.1 2000-05-19 18:48:59 jeroen Exp $
+#
+# icmp.dll makefile
+#
+# Project Odin Software License can be found in LICENSE.TXT
+#
+#
+
+# Directory macros.
+PDWIN32_INCLUDE = ..\..\include
+PDWIN32_LIB     = ..\..\lib
+PDWIN32_BIN     = ..\..\$(OBJDIR)
+PDWIN32_TOOLS   = ..\..\tools\bin
+
+# Compiler, tools, and interference rules.
+!include $(PDWIN32_INCLUDE)/pdwin32.mk
+
+# Flag overloads and local macros.
+CLEANEXTRAS = icmprsrc.asm
+
+# Object files. All objects should be prefixed with $(OBJDIR)!
+OBJS = \
+$(OBJDIR)\icmp.obj \
+$(OBJDIR)\icmprsrc.obj \
+$(PDWIN32_LIB)\dllentry.obj
+
+# Target name - name of the dll without extention and path.
+TARGET = icmp
+
+
+# All rule - build objs, target dll, copies dll to bin and makes libs.
+all:    $(OBJDIR) \
+        $(OBJDIR)\$(TARGET).dll \
+        $(PDWIN32_BIN)\$(TARGET).dll \
+        lib
+
+
+# Lib rule - build importlibrary (and evt. other libs)
+lib: $(TARGET).lib $(PDWIN32_LIB)\$(TARGET).lib
+
+
+# Dll rule - builds the target dll.
+$(OBJDIR)\$(TARGET).dll: $(OBJS) $(TARGET).def $(OBJDIR)\$(TARGET).lrf
+    $(LD2) $(LD2FLAGS) @$(OBJDIR)\$(TARGET).lrf
+
+
+# Linker file - creates the parameter file passed on to the linker.
+$(OBJDIR)\$(TARGET).lrf: makefile
+    @echo Creating file <<$@
+/OUT:$(OBJDIR)\$(TARGET).dll
+/MAP:$(OBJDIR)\$(TARGET).map
+$(OBJS)
+OS2386.LIB
+$(PDWIN32_LIB)/WSOCK32.LIB
+$(RTLLIB_O)
+$(PDWIN32_LIB)/odincrt.lib
+$(PDWIN32_LIB)/kernel32.lib
+$(TARGET).def
+<<keep
+
+
+# Dep rule - makes depenencies for C, C++ and Asm files.
+dep:
+    $(DEPEND) -I$(PDWIN32_INCLUDE);$(PDWIN32_INCLUDE)\win \
+        *.c *.cpp *.h *.asm *.inc $(PDWIN32_INCLUDE)\*.h
+
+
+# Includes the common rules.
+!include $(PDWIN32_INCLUDE)/pdwin32.post
+
