Unix Programming - Problem with detecting the reception of a datagram

This is Interesting: Free IT Magazines  
Home > Archive > Unix Programming > April 2006 > Problem with detecting the reception of a datagram





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author Problem with detecting the reception of a datagram
xoinki

2006-04-27, 7:55 am



hi all,

the program below sends a datagram to a specified host at regular
intervals, it can even broadcast datagrams, the problem here is i am
unable to detect the reception of a message,
that is... if a system with an IP address say 192.168.15.3 is not up or
not responding, then our program is unable to recieve the datagrams,
then bytes recieved would be zero.. but the listen module is not at all
executing if there is no datagram sent from a remote host..

Is this problem related to fork() system call used in main?
so that listen is executed only when a datagram has arrived?

pleeze do help thznks in advance....

here is the program..

#include<curses.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/socket.h>
#include <resolv.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/ip_icmp.h>
#include <sys/cdefs.h>
#include <sys/types.h>
#include<signal.h>

#define PACKETSIZE 64

struct hostent *hname;
struct sockaddr_in addr;

void ping(void);


struct icmphdr1
{
u_int8_t type; /* message type */
u_int8_t code; /* type sub-code */
u_int16_t checksum;
/*union
{
struct
{
u_int16_t id;
u_int16_t sequence;
} echo; /* echo datagram
u_int32_t gateway; /* gateway address
struct
{
u_int16_t __unused;
u_int16_t mtu;
} frag; /* path mtu discovery
} un;*/
};
struct icmphdr1 *icmp;
struct packet
{
struct icmphdr1 hdr;
char msg[PACKETSIZE-sizeof(struct icmphdr1)];
};

int pid=3D-1;
struct protoent *proto=3DNULL;

/*sending a packet every 10 seconds*/

void send1()
{
ping();
alarm(2);

}

/*--------------------------------------------------------------------*/
/*--- checksum - standard 1s complement checksum
---*/
/*--------------------------------------------------------------------*/
unsigned short checksum(void *b, int len)
{ unsigned short *buf =3D b;
unsigned int sum=3D0;
unsigned short result;

for ( sum =3D 0; len > 1; len -=3D 2 )
sum +=3D *buf++;
if ( len =3D=3D 1 )
sum +=3D *(unsigned char*)buf;
sum =3D (sum >> 16) + (sum & 0xFFFF);
sum +=3D (sum >> 16);
result =3D ~sum;
return result;
}

/*--------------------------------------------------------------------*/
/*--- display - present echo info
---*/
/*--------------------------------------------------------------------*/
void display(void *buf, int bytes)
{ int i;
struct iphdr *ip=3D buf;
struct icmphdr1 *icmp =3D buf+ip->ihl*4;

printf("----------------\n");
if(icmp->type=3D=3D0)
printf("muhahaha helow\n");

/* for ( i =3D 0; i < bytes; i++ )
{
if ( !(i & 15) ) printf("\nX: ", i);
printf("X ", ((unsigned char*)buf)[i]);
}*/
printf("\n");
printf("IPv%d: hdr-size=3D%d pkt-size=3D%d protocol=3D%d TTL=3D%d src=3D%s=
",
ip->version, ip->ihl*4, ntohs(ip->tot_len), ip->protocol,
ip->ttl, inet_ntoa(ip->saddr));
printf("dst=3D%s\n", inet_ntoa(ip->daddr));
//if ( icmp->un.echo.id =3D=3D pid )
{
printf("ICMP: type[%d/%d] checksum[%d]\n",
icmp->type, icmp->code, ntohs(icmp->checksum));
}
}

/*--------------------------------------------------------------------*/
/*--- listener - separate process to listen for and collect
messages--*/
/*--------------------------------------------------------------------*/
void listener(void)
{ int sd;
struct sockaddr_in addr;
unsigned char buf[1024];

sd =3D socket(PF_INET, SOCK_RAW, proto->p_proto);
//printf("hi there\n");
if ( sd < 0 )
{
perror("socket");
exit(0);
}
for (;;)
{ int bytes, len=3Dsizeof(addr);

bzero(buf, sizeof(buf));
bytes =3D recvfrom(sd, buf, sizeof(buf), 0, (struct sockaddr*)&addr,
&len);
if ( bytes > 0 )
{
// struct iphdr *ip=3D buf;
/*if(icmp->type=3D=3D0)
printf("muhahaha helow\n");

else
printf("naaaa\n");*/

display(buf, bytes);
//printf("yess\n");
}
else
perror("recvfrom");
}
exit(0);
}

/*--------------------------------------------------------------------*/
/*--- ping - Create message and send it.
---*/
/*--------------------------------------------------------------------*/
void ping()
{ const int val=3D255;
int i, sd, cnt=3D1;
struct packet pckt;
struct sockaddr_in r_addr;

// proto =3D getprotobyname("OSPFIGP");

bzero(&addr, sizeof(addr));
addr.sin_family =3D hname->h_addrtype;
addr.sin_port =3D 0;
addr.sin_addr.s_addr =3D *(long*)hname->h_addr;

sd =3D socket(PF_INET, SOCK_RAW, proto->p_proto);

if ( sd < 0 )
{
perror("socket");
return;
}
if ( setsockopt(sd, SOL_IP, IP_TTL, &val, sizeof(val)) !=3D 0)
perror("Set TTL option");
if ( fcntl(sd, F_SETFL, O_NONBLOCK) !=3D 0 )
perror("Request nonblocking I/O");
//for (;;)
{ int len=3Dsizeof(r_addr);

printf("Msg #%d\n", cnt);
if ( recvfrom(sd, &pckt, sizeof(pckt), 0, (struct sockaddr*)&r_addr,
&len) > 0 )
printf("***Got message!***\n");
bzero(&pckt, sizeof(pckt));
pckt.hdr.type =3D 0;
//pckt.hdr.un.echo.id =3D pid;
for ( i =3D 0; i < sizeof(pckt.msg)-1; i++ )
pckt.msg[i] =3D i+'0';
pckt.msg[i] =3D 0;
//pckt.hdr.un.echo.sequence =3D cnt++;
pckt.hdr.checksum =3D checksum(&pckt, sizeof(pckt));

printf("hi helo\n");
if ( sendto(sd, &pckt, sizeof(pckt), 0, (struct sockaddr*)&addr,
sizeof(addr)) <=3D 0 )
perror("sendto");
printf("ji\n");
//sleep(1);
}
}

/*--------------------------------------------------------------------*/
/*--- main - look up host and start ping processes.
---*/
/*--------------------------------------------------------------------*/
int main(int count, char *strings[])
{
/*struct hostent *hname;
struct sockaddr_in addr;*/

if ( count !=3D 2 )
{
printf("usage: %s <addr>\n", strings[0]);
exit(0);
}
if ( count > 1 )
{
pid =3D getpid();
signal(SIGALRM,send1);
pid =3D getpid();
proto =3D getprotobyname("OSPFIGP");
hname =3D gethostbyname(strings[1]);
/*bzero(&addr, sizeof(addr));
addr.sin_family =3D hname->h_addrtype;
addr.sin_port =3D 0;
addr.sin_addr.s_addr =3D *(long*)hname->h_addr;
signal(SIGALRM,send1); */
if ( fork() =3D=3D 0 )
listener();
else
send1();
while(1)
{
pause();
}=09
=09
}
else
printf("usage: myping <hostname>\n");
return 0;
}

purple_stars

2006-04-27, 7:55 am

if it were me the first thing i'd do is open another window or get
another unix box and use tcpdump to watch the packets you are sending
out to make sure they are well formed and that there isn't a problem
there. you've got an in_chksum type function in there that could be
malfunctioning, or maybe you've just got something in the header that's
messed up, or maybe you're just not understanding how the protocol
actually works, i don't know. but i'd start with the packet monitor
and take a look at the reality of whatever you are sending out and go
through it bit by bit and make sure you're really sending out and
receiving what you think you are sending out and receiving. without a
packet monitor you are blind and have no idea what's actually going on.

that's what i'd do if it was me.

xoinki wrote:
> hi all,
>
> the program below sends a datagram to a specified host at regular
> intervals, it can even broadcast datagrams, the problem here is i am
> unable to detect the reception of a message,
> that is... if a system with an IP address say 192.168.15.3 is not up or
> not responding, then our program is unable to recieve the datagrams,
> then bytes recieved would be zero.. but the listen module is not at all
> executing if there is no datagram sent from a remote host..
>
> Is this problem related to fork() system call used in main?
> so that listen is executed only when a datagram has arrived?
>
> pleeze do help thznks in advance....

[snip]

Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com