LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 04-29-2012, 06:56 AM   #1
Himalay
LQ Newbie
 
Registered: Apr 2012
Posts: 8

Rep: Reputation: Disabled
'recvfrom' not working


'recvfrom' function is not working. This function is a part of my traceroute program. 'recvfrom' doesn't return anything. The control stops here itself. Can anyone help me?
Following is the code: recv_v4.c
Code:
#include	"trace.h"

/*
 * Return: -3 on timeout
 *		   -2 on ICMP time exceeded in transit (caller keeps going)
 *		   -1 on ICMP port unreachable (caller is done)
 *		 >= 0 return value is some other ICMP unreachable code
 */
int recv_v4(int seq, struct timeval *tv)
{
	int				hlen1, hlen2, icmplen;
	socklen_t		len;
	ssize_t			n;
	struct ip		*ip, *hip;
	struct icmp		*icmp;
	struct udphdr	*udp;

	alarm(3);
	for ( ; ; ) {
		len = pr->salen;
		n = recvfrom(recvfd, recvbuf, sizeof(recvbuf), 0, pr->sarecv, &len);
		if (n < 0) {
			if (errno == EINTR)
				return(-3);		/* alarm expired */
			else
			{
				printf("\nrecvfrom error");
				exit(1);
			}
		}
		gettimeofday(tv, NULL);		/* get time of packet arrival */

		ip = (struct ip *) recvbuf;	/* start of IP header */
		hlen1 = ip->ip_hl << 2;		/* length of IP header */
	
		icmp = (struct icmp *) (recvbuf + hlen1); /* start of ICMP header */
		if ( (icmplen = n - hlen1) < 8)
		{
			printf("\nicmplen (%d) < 8", icmplen);
			exit(1);
		}
	
		if (icmp->icmp_type == ICMP_TIMXCEED &&
			icmp->icmp_code == ICMP_TIMXCEED_INTRANS) {
			if (icmplen < 8 + 20 + 8)
			{
				printf("\nicmplen (%d) < 8 + 20 + 8", icmplen);
				exit(1);
			}
			hip = (struct ip *) (recvbuf + hlen1 + 8);
			hlen2 = hip->ip_hl << 2;
			udp = (struct udphdr *) (recvbuf + hlen1 + 8 + hlen2);
 			if (hip->ip_p == IPPROTO_UDP &&
				udp->uh_sport == htons(sport) &&
				udp->uh_dport == htons(dport + seq))
				return(-2);		/* we hit an intermediate router */

		} else if (icmp->icmp_type == ICMP_UNREACH) {
			if (icmplen < 8 + 20 + 8)
			{
				printf("icmplen (%d) < 8 + 20 + 8", icmplen);
				exit(1);
			}

			hip = (struct ip *) (recvbuf + hlen1 + 8);
			hlen2 = hip->ip_hl << 2;
			udp = (struct udphdr *) (recvbuf + hlen1 + 8 + hlen2);
 			if (hip->ip_p == IPPROTO_UDP &&
				udp->uh_sport == htons(sport) &&
				udp->uh_dport == htons(dport + seq)) {
				if (icmp->icmp_code == ICMP_UNREACH_PORT)
					return(-1);	/* have reached destination */
				else
					return(icmp->icmp_code);	/* 0, 1, 2, ... */
			}
		} else if (verbose) {
			printf(" (from %s: type = %d, code = %d)\n",
					Sock_ntop_host(pr->sarecv, pr->salen),
					icmp->icmp_type, icmp->icmp_code);
		}
		/* Some other ICMP error, recvfrom() again */
	}
}

Last edited by Himalay; 04-29-2012 at 07:00 AM.
 
Old 04-29-2012, 07:19 AM   #2
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
Quote:
Originally Posted by Himalay View Post
'recvfrom' function is not working. This function is a part of my traceroute program. 'recvfrom' doesn't return anything. The control stops here itself. Can anyone help me?
If your socket is set up using the default settings, then it is blocking socket. Thus recvfrom() could potentially block indefinitely. When the alarm() expires, recvfrom() will return a result value of less than 0; errno will be set to EINTR. So when you indicate that recvfrom() is not returning anything, can you please elaborate more?

Perhaps your recvfrom() is not receiving data? Are you sure that the socket is being sent any data?


P.S. In lieu of using alarm(), you should probably do something like this:
Code:
struct timeval timeout = { 3, 0};   /* 3 seconds, 0 microseconds */
setsockopt(recvfd, SOL_SOCKET, SO_RCVTIMEO, (const void*) &timeout, sizeof(timeout));

Last edited by dwhitney67; 04-29-2012 at 07:41 AM.
 
Old 04-30-2012, 02:33 AM   #3
Himalay
LQ Newbie
 
Registered: Apr 2012
Posts: 8

Original Poster
Rep: Reputation: Disabled
I tried your suggestion "dwhitney67" still no result.
What i mean to say control stops there itself is, suppose if i give 'printf' statement after recvfrom function 'printf' is not printing. But it is timing out i.e. sig_alrm function is called, still control doesn't come to 'if (n < 0)' statement.
 
Old 04-30-2012, 05:32 AM   #4
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
Quote:
Originally Posted by Himalay View Post
I tried your suggestion "dwhitney67" still no result.
Do you have a signal handler associated with SIGALRM? Or is your program merely terminating with the following message:
Code:
Alarm clock
Try this simple program to see if you get the desired results you seek:
Code:
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>

int main()
{
    char buf[50];

    int sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

    /* typically the socket would be bound to a port; we don't care about this for this example. */

    struct timeval timeout = { 3, 0};   /* 3 seconds, 0 microseconds */
    setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (char*) &timeout, sizeof(timeout));

    int n = recvfrom(sd, buf, sizeof(buf), 0, NULL, NULL);

    if (n < 0)
    {
        if (errno == EINTR)
        {
            fprintf(stderr, "recvfrom() interrupted.\n");
        }
        else
        {
            fprintf(stderr, "Error from recvfrom() - %s (%d)\n", strerror(errno), errno);
        }
    }

    return 0;
}
If copied correctly, the program above will produce this result:
Code:
Error from recvfrom() - Resource temporarily unavailable (11)
The signal, 11, is equivalent to EAGAIN (or EWOULDBLOCK); you can take this to imply that a timeout occurred.
 
Old 04-30-2012, 05:43 AM   #5
Himalay
LQ Newbie
 
Registered: Apr 2012
Posts: 8

Original Poster
Rep: Reputation: Disabled
I tried your code 'dwhitney', nothing is being printed. It is hanging it seems.
Yes. I am having signal handler. It prints 'inside signal' and then it is hanging it seems.
Following is the code.
Code:
#include        "trace.h"

int gotalarm;

void
sig_alrm(int signo)
{
printf("\n inside signal ");
        gotalarm = 1;   /* set flag to note that alarm occurred */
        return;                 /* and interrupt the recvfrom() */
}
 
Old 04-30-2012, 06:08 AM   #6
dwhitney67
Senior Member
 
Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,541

Rep: Reputation: 335Reputation: 335Reputation: 335Reputation: 335
Quote:
Originally Posted by Himalay View Post
I tried your code 'dwhitney', nothing is being printed. It is hanging it seems.
Here are some basic questions:
1) What OS are you using?
2) What compiler are you using?
3) What steps did you take to build the sample application I offered?

Also, a suggestion for your application... when using printf(), output a newline character at the end of the text you wish to see; this forces a flush of the output stream. Otherwise the output you are hoping to see is buffered until some byte limit is reached (1K bytes, 4K bytes, ??).
 
Old 04-30-2012, 06:28 AM   #7
Himalay
LQ Newbie
 
Registered: Apr 2012
Posts: 8

Original Poster
Rep: Reputation: Disabled
Quote:
Here are some basic questions:
1) What OS are you using?
2) What compiler are you using?
3) What steps did you take to build the sample application I offered?
I am using Windows XP Professional OS,
CYGWIN gcc compiler
gcc test.c
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
udp recvfrom returns 0 adetheheat Linux - Networking 3 04-08-2011 02:33 PM
Non blocking recvfrom simasimon Programming 4 11-22-2010 02:40 PM
problem with recvfrom saheelahamed Linux - Networking 1 08-28-2007 03:10 PM
recvfrom in its own thread? estratos Programming 9 02-18-2006 03:26 AM
Problem in recvfrom() live_dont_exist Programming 5 05-08-2005 04:25 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 07:47 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration