www.delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin-apps/2000/07/12/09:10:46

Mailing-List: contact cygwin-apps-help AT sourceware DOT cygnus DOT com; run by ezmlm
Sender: cygwin-apps-owner AT sourceware DOT cygnus DOT com
List-Subscribe: <mailto:cygwin-apps-subscribe AT sources DOT redhat DOT com>
List-Archive: <http://sources.redhat.com/ml/cygwin-apps/>
List-Post: <mailto:cygwin-apps AT sources DOT redhat DOT com>
List-Help: <mailto:cygwin-apps-help AT sources DOT redhat DOT com>, <http://sources.redhat.com/lists.html#faqs>
Delivered-To: mailing list cygwin-apps AT sources DOT redhat DOT com
Message-ID: <001201bfec03$3f8549a0$f7c723cb@lifelesswks>
From: "Robert Collins" <robert DOT collins AT itdomain DOT com DOT au>
To: "cygapp" <cygwin-apps AT sourceware DOT cygnus DOT com>
Cc: "cygapp" <cygwin-apps AT sourceware DOT cygnus DOT com>
References: <007d01bfebfb$1aff7090$f7c723cb AT lifelesswks> <396C6CBC DOT E79EA907 AT cygnus DOT com>
Subject: Re: sendto function
Date: Wed, 12 Jul 2000 23:15:26 +1000
MIME-Version: 1.0
X-Priority: 3
X-MSMail-Priority: Normal
X-Mailer: Microsoft Outlook Express 5.00.2919.6700
X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2919.6700

This is a multi-part message in MIME format.

------=_NextPart_000_000F_01BFEC57.1022CFD0
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: 7bit

That as the fragment where I think the problem occurs. I've attached the
whole program now as it's pretty small.

It's an optional process used by squid to ping web servers to decide whether
a direct connection or parent connection is most efficient.

yes, it calls socket and so on.

I doctored the icmp.h and in.h headers from Linux (where other cygwin
headers seem to have come from :-) ) - so I won't be surprised if the
problem is the supporting code is missing.../

Rob

----- Original Message -----
From: "Corinna Vinschen" <vinschen AT cygnus DOT com>
To: "Robert Collins" <robert DOT collins AT itdomain DOT com DOT au>
Cc: "cygapp" <cygwin-apps AT sourceware DOT cygnus DOT com>
Sent: Wednesday, July 12, 2000 11:03 PM
Subject: Re: sendto function


> Robert Collins wrote:
> >
> > Is the sendto function capable of sending icmp packets?
> >
> > The following code fragment is not working properly...
> > It runs on Un*x at the moment, and I'm hoping for some hint/direction
for me
> > to alter it, or alter cygwin to get it working.
>
> This works on unix? I'm missing the icmp_sock definition
> as well as the socket() call. fd 2 is used which is stderr
> typically. Are you sure that you got your icmp_sock descriptor
> by a socket() call? Or is that application called by inetd
> with already opened descriptors?
>
> Corinna
>
> --
> Corinna Vinschen
> Cygwin Developer
> Cygnus Solutions, a Red Hat company
>

------=_NextPart_000_000F_01BFEC57.1022CFD0
Content-Type: application/octet-stream;
	name="pinger.c"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="pinger.c"

=0A=
/*=0A=
 * $Id: pinger.c,v 1.1.1.3.12.2.6.1 2000/07/11 23:41:19 rbcollins Exp $=0A=
 *=0A=
 * DEBUG: section 42    ICMP Pinger program=0A=
 * AUTHOR: Duane Wessels=0A=
 *=0A=
 * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/=0A=
 * ----------------------------------------------------------=0A=
 *=0A=
 *  Squid is the result of efforts by numerous individuals from the=0A=
 *  Internet community.  Development is led by Duane Wessels of the=0A=
 *  National Laboratory for Applied Network Research and funded by the=0A=
 *  National Science Foundation.  Squid is Copyrighted (C) 1998 by=0A=
 *  the Regents of the University of California.  Please see the=0A=
 *  COPYRIGHT file for full details.  Squid incorporates software=0A=
 *  developed and/or copyrighted by other sources.  Please see the=0A=
 *  CREDITS file for full details.=0A=
 *=0A=
 *  This program is free software; you can redistribute it and/or modify=0A=
 *  it under the terms of the GNU General Public License as published by=0A=
 *  the Free Software Foundation; either version 2 of the License, or=0A=
 *  (at your option) any later version.=0A=
 *  =0A=
 *  This program is distributed in the hope that it will be useful,=0A=
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of=0A=
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the=0A=
 *  GNU General Public License for more details.=0A=
 *  =0A=
 *  You should have received a copy of the GNU General Public License=0A=
 *  along with this program; if not, write to the Free Software=0A=
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.=0A=
 *=0A=
 */=0A=
=0A=
#include "squid.h"=0A=
=0A=
#if USE_ICMP=0A=
=0A=
#include <netinet/in_systm.h>=0A=
#include <netinet/in.h>=0A=
#include <netinet/ip.h>=0A=
#include <netinet/ip_icmp.h>=0A=
=0A=
#ifndef _SQUID_LINUX_=0A=
#ifndef _SQUID_CYGWIN_=0A=
#define icmphdr icmp=0A=
#define iphdr ip=0A=
#endif=0A=
#endif=0A=
=0A=
#if defined (_SQUID_LINUX_) || defined (_SQUID_CYGWIN_)=0A=
#ifdef icmp_id=0A=
#undef icmp_id=0A=
#endif=0A=
#ifdef icmp_seq=0A=
#undef icmp_seq=0A=
#endif=0A=
#define icmp_type type=0A=
#define icmp_code code=0A=
#define icmp_cksum checksum=0A=
#define icmp_id un.echo.id=0A=
#define icmp_seq un.echo.sequence=0A=
#define ip_hl ihl=0A=
#define ip_v version=0A=
#define ip_tos tos=0A=
#define ip_len tot_len=0A=
#define ip_id id=0A=
#define ip_off frag_off=0A=
#define ip_ttl ttl=0A=
#define ip_p protocol=0A=
#define ip_sum check=0A=
#define ip_src saddr=0A=
#define ip_dst daddr=0A=
#endif=0A=
=0A=
#if ALLOW_SOURCE_PING=0A=
#define MAX_PKT_SZ 8192=0A=
#define MAX_PAYLOAD (MAX_PKT_SZ - sizeof(struct icmphdr) - sizeof (char) =
- sizeof(struct timeval) - 1)=0A=
#else=0A=
#define MAX_PAYLOAD SQUIDHOSTNAMELEN=0A=
#define MAX_PKT_SZ (MAX_PAYLOAD + sizeof(struct timeval) + sizeof (char) =
+ sizeof(struct icmphdr) + 1)=0A=
#endif=0A=
=0A=
typedef struct {=0A=
    struct timeval tv;=0A=
    unsigned char opcode;=0A=
    char payload[MAX_PAYLOAD];=0A=
} icmpEchoData;=0A=
=0A=
int icmp_ident =3D -1;=0A=
int icmp_pkts_sent =3D 0;=0A=
=0A=
static const char *icmpPktStr[] =3D=0A=
{=0A=
    "Echo Reply",=0A=
    "ICMP 1",=0A=
    "ICMP 2",=0A=
    "Destination Unreachable",=0A=
    "Source Quench",=0A=
    "Redirect",=0A=
    "ICMP 6",=0A=
    "ICMP 7",=0A=
    "Echo",=0A=
    "ICMP 9",=0A=
    "ICMP 10",=0A=
    "Time Exceeded",=0A=
    "Parameter Problem",=0A=
    "Timestamp",=0A=
    "Timestamp Reply",=0A=
    "Info Request",=0A=
    "Info Reply",=0A=
    "Out of Range Type"=0A=
};=0A=
=0A=
static int in_cksum(unsigned short *ptr, int size);=0A=
static void pingerRecv(void);=0A=
static void pingerLog(struct icmphdr *, struct in_addr, int, int);=0A=
static int ipHops(int ttl);=0A=
static void pingerSendtoSquid(pingerReplyData * preply);=0A=
=0A=
void=0A=
pingerOpen(void)=0A=
{=0A=
    struct protoent *proto =3D NULL;=0A=
    if ((proto =3D getprotobyname("icmp")) =3D=3D 0) {=0A=
	debug(42, 0) ("pingerOpen: unknown protocol: icmp\n");=0A=
	exit(1);=0A=
    }=0A=
    icmp_sock =3D socket(PF_INET, SOCK_RAW, proto->p_proto);=0A=
    if (icmp_sock < 0) {=0A=
	debug(50, 0) ("pingerOpen: icmp_sock: %s\n", xstrerror());=0A=
	exit(1);=0A=
    }=0A=
    icmp_ident =3D getpid() & 0xffff;=0A=
    debug(42, 0) ("pinger: ICMP socket opened\n");=0A=
}=0A=
=0A=
void=0A=
pingerClose(void)=0A=
{=0A=
    close(icmp_sock);=0A=
    icmp_sock =3D -1;=0A=
    icmp_ident =3D 0;=0A=
}=0A=
=0A=
static void=0A=
pingerSendEcho(struct in_addr to, int opcode, char *payload, int len)=0A=
{=0A=
    LOCAL_ARRAY(char, pkt, MAX_PKT_SZ);=0A=
    struct icmphdr *icmp =3D NULL;=0A=
    icmpEchoData *echo;=0A=
    int icmp_pktsize =3D sizeof(struct icmphdr);=0A=
    struct sockaddr_in S;=0A=
    memset(pkt, '\0', MAX_PKT_SZ);=0A=
    icmp =3D (struct icmphdr *) (void *) pkt;=0A=
    /*=0A=
     * cevans - beware signed/unsigned issues in untrusted data from=0A=
     * the network!!=0A=
     */=0A=
    if (len < 0) {=0A=
	len =3D 0;=0A=
    }=0A=
    icmp->icmp_type =3D ICMP_ECHO;=0A=
    icmp->icmp_code =3D 0;=0A=
    icmp->icmp_cksum =3D 0;=0A=
    icmp->icmp_id =3D icmp_ident;=0A=
    icmp->icmp_seq =3D (u_short) icmp_pkts_sent++;=0A=
    echo =3D (icmpEchoData *) (icmp + 1);=0A=
    echo->opcode =3D (unsigned char) opcode;=0A=
    echo->tv =3D current_time;=0A=
    icmp_pktsize +=3D sizeof(icmpEchoData) - MAX_PAYLOAD;=0A=
    if (payload) {=0A=
	if (len > MAX_PAYLOAD)=0A=
	    len =3D MAX_PAYLOAD;=0A=
	xmemcpy(echo->payload, payload, len);=0A=
	icmp_pktsize +=3D len;=0A=
    }=0A=
    icmp->icmp_cksum =3D in_cksum((u_short *) icmp, icmp_pktsize);=0A=
    S.sin_family =3D AF_INET;=0A=
    /*=0A=
     * cevans: alert: trusting to-host, was supplied in network packet=0A=
     */=0A=
    S.sin_addr =3D to;=0A=
    S.sin_port =3D 0;=0A=
    assert(icmp_pktsize <=3D MAX_PKT_SZ);=0A=
    sendto(icmp_sock,=0A=
	pkt,=0A=
	icmp_pktsize,=0A=
	0,=0A=
	(struct sockaddr *) &S,=0A=
	sizeof(struct sockaddr_in));=0A=
debug(50,0) ("WSAError is %s\n", xstrerror());=0A=
    pingerLog(icmp, to, 0, 0);=0A=
}=0A=
=0A=
static void=0A=
pingerRecv(void)=0A=
{=0A=
    int n;=0A=
    socklen_t fromlen;=0A=
    struct sockaddr_in from;=0A=
    int iphdrlen =3D 20;=0A=
    struct iphdr *ip =3D NULL;=0A=
    struct icmphdr *icmp =3D NULL;=0A=
    static char *pkt =3D NULL;=0A=
    struct timeval now;=0A=
    icmpEchoData *echo;=0A=
    static pingerReplyData preply;=0A=
=0A=
    if (pkt =3D=3D NULL)=0A=
	pkt =3D xmalloc(MAX_PKT_SZ);=0A=
    fromlen =3D sizeof(from);=0A=
    n =3D recvfrom(icmp_sock,=0A=
	pkt,=0A=
	MAX_PKT_SZ,=0A=
	0,=0A=
	(struct sockaddr *) &from,=0A=
	&fromlen);=0A=
#if GETTIMEOFDAY_NO_TZP=0A=
    gettimeofday(&now);=0A=
#else=0A=
    gettimeofday(&now, NULL);=0A=
#endif=0A=
    debug(42, 9) ("pingerRecv: %d bytes from %s\n", n, =
inet_ntoa(from.sin_addr));=0A=
    ip =3D (struct iphdr *) (void *) pkt;=0A=
#if HAVE_IP_HL=0A=
    iphdrlen =3D ip->ip_hl << 2;=0A=
#else /* HAVE_IP_HL */=0A=
#if WORDS_BIGENDIAN=0A=
    iphdrlen =3D (ip->ip_vhl >> 4) << 2;=0A=
#else=0A=
    iphdrlen =3D (ip->ip_vhl & 0xF) << 2;=0A=
#endif=0A=
#endif /* HAVE_IP_HL */=0A=
    icmp =3D (struct icmphdr *) (void *) (pkt + iphdrlen);=0A=
debug(42, 9) ("pingerRecv: icmp-type %d from %s\n", icmp->icmp_type, =
inet_ntoa(from.sin_addr));=0A=
debug(42, 9) ("pingerRecv: icmp-id %d for ident %d from %s\n", =
icmp->icmp_id, icmp_ident, inet_ntoa(from.sin_addr));    if =
(icmp->icmp_type !=3D ICMP_ECHOREPLY)=0A=
	return;=0A=
=0A=
    if (icmp->icmp_id !=3D icmp_ident)=0A=
	return;=0A=
    echo =3D (icmpEchoData *) (void *) (icmp + 1);=0A=
debug(42, 9) ("pingerRecv: about to send to squid for reply from %s\n", =
inet_ntoa(from.sin_addr));=0A=
    preply.from =3D from.sin_addr;=0A=
    preply.opcode =3D echo->opcode;=0A=
    preply.hops =3D ipHops(ip->ip_ttl);=0A=
    preply.rtt =3D tvSubMsec(echo->tv, now);=0A=
    preply.psize =3D n - iphdrlen - (sizeof(icmpEchoData) - MAX_PKT_SZ);=0A=
    debug(42, 9) ("pingerRecv: about to send to squid for reply from =
%s\n", inet_ntoa(from.sin_addr)); =0A=
    pingerSendtoSquid(&preply);=0A=
    pingerLog(icmp, from.sin_addr, preply.rtt, preply.hops);=0A=
}=0A=
=0A=
=0A=
static int=0A=
in_cksum(unsigned short *ptr, int size)=0A=
{=0A=
    long sum;=0A=
    unsigned short oddbyte;=0A=
    unsigned short answer;=0A=
    sum =3D 0;=0A=
    while (size > 1) {=0A=
	sum +=3D *ptr++;=0A=
	size -=3D 2;=0A=
    }=0A=
    if (size =3D=3D 1) {=0A=
	oddbyte =3D 0;=0A=
	*((unsigned char *) &oddbyte) =3D *(unsigned char *) ptr;=0A=
	sum +=3D oddbyte;=0A=
    }=0A=
    sum =3D (sum >> 16) + (sum & 0xffff);=0A=
    sum +=3D (sum >> 16);=0A=
    answer =3D ~sum;=0A=
    return (answer);=0A=
}=0A=
=0A=
static void=0A=
pingerLog(struct icmphdr *icmp, struct in_addr addr, int rtt, int hops)=0A=
{=0A=
    debug(42, 2) ("pingerLog: %9d.%06d %-16s %d %-15.15s %dms %d hops\n",=0A=
	(int) current_time.tv_sec,=0A=
	(int) current_time.tv_usec,=0A=
	inet_ntoa(addr),=0A=
	(int) icmp->icmp_type,=0A=
	icmpPktStr[icmp->icmp_type],=0A=
	rtt,=0A=
	hops);=0A=
}=0A=
=0A=
static int=0A=
ipHops(int ttl)=0A=
{=0A=
    if (ttl < 33)=0A=
	return 33 - ttl;=0A=
    if (ttl < 63)=0A=
	return 63 - ttl;	/* 62 =3D (64+60)/2 */=0A=
    if (ttl < 65)=0A=
	return 65 - ttl;	/* 62 =3D (64+60)/2 */=0A=
    if (ttl < 129)=0A=
	return 129 - ttl;=0A=
    if (ttl < 193)=0A=
	return 193 - ttl;=0A=
    return 256 - ttl;=0A=
}=0A=
=0A=
static int=0A=
pingerReadRequest(void)=0A=
{=0A=
    static pingerEchoData pecho;=0A=
    int n;=0A=
    int guess_size;=0A=
    memset(&pecho, '\0', sizeof(pecho));=0A=
    n =3D recv(0, (char *) &pecho, sizeof(pecho), 0);=0A=
    if (n < 0)=0A=
	return n;=0A=
    if (0 =3D=3D n) {=0A=
	/* EOF indicator */=0A=
	fprintf(stderr, "EOF encountered\n");=0A=
	errno =3D 0;=0A=
	return -1;=0A=
    }=0A=
    guess_size =3D n - (sizeof(pingerEchoData) - PINGER_PAYLOAD_SZ);=0A=
    if (guess_size !=3D pecho.psize) {=0A=
	fprintf(stderr, "size mismatch, guess=3D%d psize=3D%d\n",=0A=
	    guess_size, pecho.psize);=0A=
	/* don't process this message, but keep running */=0A=
	return 0;=0A=
    }=0A=
    pingerSendEcho(pecho.to,=0A=
	pecho.opcode,=0A=
	pecho.payload,=0A=
	pecho.psize);=0A=
    return n;=0A=
}=0A=
=0A=
static void=0A=
pingerSendtoSquid(pingerReplyData * preply)=0A=
{=0A=
    int len =3D sizeof(pingerReplyData) - MAX_PKT_SZ + preply->psize;=0A=
    if (send(1, (char *) preply, len, 0) < 0) {=0A=
	debug(50, 0) ("pinger: send: %s\n", xstrerror());=0A=
	exit(1);=0A=
    }=0A=
}=0A=
=0A=
time_t=0A=
getCurrentTime(void)=0A=
{=0A=
#if GETTIMEOFDAY_NO_TZP=0A=
    gettimeofday(&current_time);=0A=
#else=0A=
    gettimeofday(&current_time, NULL);=0A=
#endif=0A=
    return squid_curtime =3D current_time.tv_sec;=0A=
}=0A=
=0A=
=0A=
int=0A=
main(int argc, char *argv[])=0A=
{=0A=
    fd_set R;=0A=
    int x;=0A=
    struct timeval tv;=0A=
    const char *debug_args =3D "ALL,1";=0A=
    char *t;=0A=
    time_t last_check_time =3D 0;=0A=
=0A=
/*=0A=
 * cevans - do this first. It grabs a raw socket. After this we can=0A=
 * drop privs=0A=
 */=0A=
    pingerOpen();=0A=
    setgid(getgid());=0A=
    setuid(getuid());=0A=
=0A=
    if ((t =3D getenv("SQUID_DEBUG")))=0A=
	debug_args =3D xstrdup(t);=0A=
    getCurrentTime();=0A=
    _db_init(NULL, debug_args);=0A=
=0A=
    for (;;) {=0A=
	tv.tv_sec =3D 10;=0A=
	tv.tv_usec =3D 0;=0A=
	FD_ZERO(&R);=0A=
	FD_SET(0, &R);=0A=
	FD_SET(icmp_sock, &R);=0A=
	x =3D select(icmp_sock + 1, &R, NULL, NULL, &tv);=0A=
	getCurrentTime();=0A=
	if (x < 0)=0A=
	    exit(1);=0A=
	if (FD_ISSET(0, &R))=0A=
	    if (pingerReadRequest() < 0) {=0A=
		debug(42, 0) ("Pinger exiting.\n");=0A=
		exit(1);=0A=
	    }=0A=
	if (FD_ISSET(icmp_sock, &R))=0A=
	    pingerRecv();=0A=
	if (10 + last_check_time < squid_curtime) {=0A=
	    if (send(1, (char *) &tv, 0, 0) < 0)=0A=
		exit(1);=0A=
	    last_check_time =3D squid_curtime;=0A=
	}=0A=
    }=0A=
    /* NOTREACHED */=0A=
}=0A=
=0A=
#else=0A=
#include <stdio.h>=0A=
int=0A=
main(int argc, char *argv[])=0A=
{=0A=
    fprintf(stderr, "%s: ICMP support not compiled in.\n", argv[0]);=0A=
    return 1;=0A=
}=0A=
#endif /* USE_ICMP */=0A=

------=_NextPart_000_000F_01BFEC57.1022CFD0--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019