Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

UDP Sockets sendto() failures

0 views
Skip to first unread message

Vikas Aggarwal

unread,
Jan 2, 1997, 3:00:00 AM1/2/97
to

I dont know if this is a known fact, but on Linux 1.2 and FreeBSD 2.1
platforms, the sendto() call does not work (for UDP). Replacing the
sendto() with a connect() + send() sequence works though.

I dont want to post a test code snippet in case this is a known fact,
but in case it is not (is it in the FAQ), I will post the code snippet
which is failing (hope I am not making any mistakes in the code).

-vikas
Vikas Aggarwal


Vikas Aggarwal

unread,
Jan 4, 1997, 3:00:00 AM1/4/97
to

Since a number of people have suggested that it is more likely that I
have a bug in my code, I am posting my code below.

Due apologies for wasting other people's time if it indeed turns out to
be a bug in my code.

-vikas

I had written in an earlier posting:
: I dont know if this is a known fact, but on Linux 1.2 and FreeBSD 2.1


: platforms, the sendto() call does not work (for UDP). Replacing the
: sendto() with a connect() + send() sequence works though.

:


/*
* Test snippet to see if sendto() works. Use :
* tcpdump udp port xxxx
* to look for the packets.
*
* I cannot seem to get sendto() working on FreeBSD 2.1.x (works on
* SunOS 4.1.x)
*
* Note that sendto() reports proper number of bytes sent, but tcpdump
* does NOT show any data.
*
* -vi...@navya.com (Vikas Aggarwal)
*/

#include <sys/types.h>
#include <sys/socket.h> /* for AF_INET */
#include <sys/ioctl.h>
#include <sys/file.h>

#include <netinet/in.h> /* for struct in_addr */
#include <sys/un.h> /* for struct sockaddr_un (Unix style sockets) */
#include <arpa/inet.h> /* for inet_ntoa() */

#include <errno.h>
#include <netdb.h> /* for getservbyname() struct hostent definition */
#include <syslog.h> /* for report(), openlog, etc. */
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <sys/time.h> /* for timeval struct */
#ifdef AIX
# include <sys/select.h>
#endif

#include <stdio.h>

char *Strerror(n)
int n;
{
#if !defined(__FreeBSD__) && !defined(__BSDI__)
extern char *sys_errlist[];
#endif

return (char *)sys_errlist[n];
}

/*
* - Create a socket of type DGRAM or STREAM
* - Bind to proper Port and local address
* - Return the socket to the calling routine
*/
newsocket_ip(type, port, service)
int type; /* SOCK_DGRAM or SOCK_STREAM */
int port; /* which port number, used IF service not specified */
char *service; /* service name. If not specified, use port */
{ /* begin newsocket() */
int sockfd;
struct sockaddr_in my_addr; /* IP domain */

/* Pick up a socket */
if ((sockfd = socket(AF_INET, type, 0)) < 0)
{
fprintf(stderr, "Error socket: IP port %d %s", port, Strerror(errno));
return(-1);
}

/* Get port we need to pay attention to */

bzero(&my_addr, sizeof(my_addr));
my_addr.sin_family = AF_INET;
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);

if (service && *service)
{
register struct servent *sp;

if (type == SOCK_DGRAM)
sp = getservbyname(service, "udp");
else if (type == SOCK_STREAM)
sp = getservbyname(service, "tcp");
else
fprintf(stderr, "daemon: Unknown type %d (not DGRAM or STREAM)", type);

if (sp != NULL)
my_addr.sin_port = sp->s_port;
}

if (my_addr.sin_port == 0)
my_addr.sin_port = htons(port);

if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(my_addr)) < 0)
{
fprintf(stderr, "bind: %d %s, exiting", port, Strerror(errno));
return(-1);
}

return (sockfd); /* return the socket */

} /* end newsocket_ip() */

/*
* Send a UDP message on an open file descriptor to the destination specified.
*/
send_udpmesg(buf, bufsize, dgramfd, host, port)
char *buf;
char *host; /* destination IP address */
int port, bufsize, dgramfd;
{
int nsent;
static int connected;
char *desthost;
struct sockaddr_in dest_addr_in;

if (host == NULL) desthost = "127.0.0.1"; /* localhost */
else desthost = host;

bzero(&dest_addr_in, sizeof(dest_addr_in));
dest_addr_in.sin_family = AF_INET;
dest_addr_in.sin_addr.s_addr = inet_addr(desthost);
dest_addr_in.sin_port = port;

/* Now send off the packet to the destination */
fprintf(stderr, "Using sendto()... to %s port %d\n", host, port);
nsent = sendto(dgramfd, buf, bufsize, 0, (struct sockaddr *)&dest_addr_in,
sizeof(struct sockaddr_in));

if (nsent != bufsize)
{
fprintf(stderr, "sendto(%s)- %s", desthost, Strerror(errno));
return(-1);
}
else
{
/* report(LOG_INFO, "send_udpmesg()Sent datagram to %s port %d",
* desthost, port);
*/
}

return(nsent);
} /* send_udpmesg() */


main()
{
int fd = newsocket_ip(SOCK_DGRAM, 0, NULL);
int nread, fromport, destport;
char buf[1024], desthost[32], strport[8], *fromhost;

printf("Enter dest host IP: "); fgets(desthost, 32, stdin);
printf("Enter dest port >1023: "); fgets(strport, 8 , stdin);
printf("Enter data line: "); fgets(buf, 1024, stdin);

desthost[strlen(desthost) - 1] = '\0'; /* get rid of '\n' */
destport = atoi(strport);
if (send_udpmesg(buf, strlen(buf), fd, desthost, destport) != strlen(buf))
exit (-1);
else
fprintf(stderr, "(main) Sent UDP message to port %d\n", destport);

exit (0);
}

Steinar Haug

unread,
Jan 4, 1997, 3:00:00 AM1/4/97
to

[Vikas Aggarwal]

| Since a number of people have suggested that it is more likely that I
| have a bug in my code, I am posting my code below.

I think you do - a missing htons() for the port number.

| send_udpmesg(buf, bufsize, dgramfd, host, port)

. is called with port number in host order.

| bzero(&dest_addr_in, sizeof(dest_addr_in));
| dest_addr_in.sin_family = AF_INET;
| dest_addr_in.sin_addr.s_addr = inet_addr(desthost);
| dest_addr_in.sin_port = port;

. and here you stuff it into the sockaddr_in, still in host order.
You need a htons() here.

Steinar Haug, Nethelp consulting, sth...@nethelp.no

Andrew Gierth

unread,
Jan 4, 1997, 3:00:00 AM1/4/97
to Vikas Aggarwal

>>>>> "Vikas" == Vikas Aggarwal <vi...@netplex-tech.Com> writes:

Vikas> Since a number of people have suggested that it is more likely that I
Vikas> have a bug in my code, I am posting my code below.

A bug indeed - byte-order claims another victim.

Vikas> * I cannot seem to get sendto() working on FreeBSD 2.1.x (works on
Vikas> * SunOS 4.1.x)

This is a BIG, BIG clue that should shout "BYTE ORDER" at you loudly.

Sparcs and 68000's are big-endian, which makes them tolerant of missing
conversions, since host and network byte-order are the same. x86's are
little-endian, so the conversions matter.

Vikas> /*
Vikas> * Send a UDP message on an open file descriptor to the destination specified.
Vikas> */
Vikas> send_udpmesg(buf, bufsize, dgramfd, host, port)
Vikas> char *buf;
Vikas> char *host; /* destination IP address */
Vikas> int port, bufsize, dgramfd;

*Always*, *ALWAYS*, document, for port numbers, whether they are in host
or network order.

Vikas> {
Vikas> int nsent;
Vikas> static int connected;
Vikas> char *desthost;
Vikas> struct sockaddr_in dest_addr_in;

Vikas> if (host == NULL) desthost = "127.0.0.1"; /* localhost */
Vikas> else desthost = host;

Vikas> bzero(&dest_addr_in, sizeof(dest_addr_in));
Vikas> dest_addr_in.sin_family = AF_INET;
Vikas> dest_addr_in.sin_addr.s_addr = inet_addr(desthost);
Vikas> dest_addr_in.sin_port = port;

sin_port must always be in network order... you need an htons() call there.

--
Andrew Gierth (and...@microlise.co.uk)

"Ceterum censeo Microsoftam delendam esse" - Alain Knaff in nanam

Boyd Roberts

unread,
Jan 6, 1997, 3:00:00 AM1/6/97
to

In article <E3H7y...@netplex-tech.com>, vi...@netplex-tech.Com says...

>
>Due apologies for wasting other people's time if it indeed turns out to
>be a bug in my code.

Distinct lack of htons() on the destination port.

--
Boyd Roberts <bo...@france3.fr> N 31 447109 5411310

``Not only is UNIX dead, but it's starting to smell really bad.'' -- rob


0 new messages