Solved

How do I get ICMP messages back?

Posted on 1998-02-17
9
279 Views
Last Modified: 2008-03-03
I am using a UDP connected socket to send a datagram to a remote host. I want to see if I get ECONNREFUSED or ETIMEDOUT back... How do I do that?

Simple code example would be nice.
0
Comment
Question by:Rumata
  • 4
  • 4
9 Comments
 
LVL 4

Expert Comment

by:emmons
ID: 1257285
After you create the socket, you need to call 'connect' to establish the address to be used in future output to the socket.
If connect comes back < 0, then you check errno for the various connection errors.

.
.
.
sockfd=socket( AF_INET, SOCK_DGRAM, 0);
if( sockfd < 0) /* socket error */
if ( bind( sockfd, . . .) < 0) /* bind error */
if( connect( sockfd, ...) < 0) /* connect error */

 
0
 

Author Comment

by:Rumata
ID: 1257286
Maybe my question was not clear, but I already did socket, bind and connect calls. Now, I do a send call. It goes through fine (even though the port on remote does not accept anything). Now, I want to know of ECONNREFUSED occured (which it should've because port is not accepting anything). So, my question is how do I know ECONNREFUSED occured...
0
 
LVL 32

Expert Comment

by:jhance
ID: 1257287
You can't get this error with a UDP connection.  There is no feedback from the socket as to whether what you sent made it through, was lost, was refused, or anything else.  UDP is like a CB radio, you can key the mic and talk all day but you never know if anyone heard you unless they talk back at you.  If you need this kind of information, you need to switch to a TCP connection OR use some type of protocol or handshaking between your sending socket and the receiver to verify that what you sent was received.
0
 
LVL 4

Expert Comment

by:emmons
ID: 1257288
Dang! Got in there too late.
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 4

Expert Comment

by:emmons
ID: 1257289
Jhance, I am sorry, but you are wrong. All you said is true for UDP sockets that are NOT connected (using the connect call). I am quoting Stevens:

There is another feature provided for connectionless clients that call connect. ... For example, the Internet protocols specify that a host should generate an ICMP prot unreachable message if it recieves a UDP datagram specifying a UDP prot for which no process is waiting to read from. The host that sent the UDP datagram and recives tis ICMP message can try ot identify the process that sent the datagram and notify the process. 4.3BSD for example notifies the process with a "connection refused" error ...

And so on
0
 

Author Comment

by:Rumata
ID: 1257290
emmons, are you saying that I can do 2 sends, and the second send will return -1 with errno having the error code?
0
 

Author Comment

by:Rumata
ID: 1257291
emmons, i tried sending two send messages, but none of them return -1. Check it out.


#include "trace.h"
#include <string.h>
#include <errno.h>
#include <sys/signal.h>
#include <fcntl.h>

extern int errno;
int main(int argc, char *argv[])
{
  int n, len;
  int sockfd;
  struct sockaddr_in local_addr, remote_addr;
  char line[30];
  int ttl=1;
  long oldmask;


 

  /* Set the remote host info */
  bzero((char *)&remote_addr, sizeof(remote_addr));
  remote_addr.sin_family = AF_INET;
  remote_addr.sin_addr.s_addr = inet_addr("128.59.35.130");
  remote_addr.sin_port = htons(TRACE_PORT);
 
  /* Open a UDP socket */
  if ((sockfd=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP))<0)
    {
      fprintf(stderr,"Can't open datagram socket!\n");
      sigsetmask(oldmask);
      exit(1);
    }
 
  /* Set the local host info */
  bzero((char *) &local_addr, sizeof(local_addr));
  local_addr.sin_family = AF_INET;
  local_addr.sin_addr.s_addr = htonl(INADDR_ANY);     /* Get the local IP */
  local_addr.sin_port = htons(0);                     /* Get a free port  */
 
  /* Bind the local address */
  if (bind(sockfd, (struct sockaddr *)&local_addr, sizeof(local_addr)) < 0)
    {
      fprintf(stderr,"Can't bind the local address!\n");
      close(sockfd);
      sigsetmask(oldmask);
      exit(1);
    }
  if (connect(sockfd, (struct sockaddr *)&remote_addr, sizeof(remote_addr)) < 0)
    {
      fprintf(stderr,"Can't connect!\n");
      close(sockfd);
      sigsetmask(oldmask);
      exit(1);
    }
  /* Send a stupid datagram */
  strcpy(line, "I am a stupid datagram");
  n=strlen(line);


  if (send(sockfd, line, n, 0) < 0)
    {
      fprintf(stderr,"Can't send!\n");
      close(sockfd);
      sigsetmask(oldmask);
      exit(1);
    }

  if (send(sockfd, line, n, 0) < 0)
    {
      fprintf(stderr,"Can't send!\n");
      close(sockfd);
      sigsetmask(oldmask);
      exit(1);
    }

  fprintf(stderr, "Done!!!\n");
  sigsetmask(oldmask);
  close(sockfd);
}


0
 

Author Comment

by:Rumata
ID: 1257292
Are you sure that the server does not have something on the UDP port?
I just ran your code here.
I changed one thing, I added a for loop around the second send command, since I was getting a HOST UNREACHABLE error here behind my firewall.
The code returned an error consistanly on the 5th try.
When I set the IP address to be my current machine, I got an error on the second send.
Try putting in the for loop and printing out errno when (if?) you get an error.

for ( i=0; i<50; i++) {
  printf( "Trying for the %d time\n", i);
 if (send(sockfd, line, n, 0) < 0) {
  fprintf(stderr,"Can't send!\n");
  printf( "errno = %d\n", errno);
  close(sockfd);
  sigsetmask(oldmask);
  exit(1);
 }
}


/* with your IP address */
{emmons@home} /home/cemmons/bin/aix4==> ./rumata
Trying for the 5 time
Can't send!
errno = 81

/* with my IP address */
{emmons@home} /home/cemmons/bin/aix4==> ./rumata
Trying for the 0 time
Can't send!
errno = 79
{emmons@home} /home/cemmons/bin/aix4==> ./rumata
Trying for the 0 time
Can't send!
errno = 79
{emmons@home} /home/cemmons/bin/aix4==> ./rumata
Trying for the 0 time
Can't send!
errno = 79
{emmons@home} /home/cemmons/bin/aix4==> ./rumata
Trying for the 0 time
Can't send!
errno = 79

0
 
LVL 4

Accepted Solution

by:
emmons earned 50 total points
ID: 1257293
emmons, it worked!

THANKS a lot...
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Suggested Solutions

Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
The goal of this video is to provide viewers with basic examples to understand opening and writing to files in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to create, access, and change arrays in the C programming language.

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now