*BSD News Article 86095


Return to BSD News archive

Newsgroups: comp.unix.programmer,comp.unix.bsd.freebsd.misc
Path: euryale.cc.adfa.oz.au!newshost.carno.net.au!harbinger.cc.monash.edu.au!news.mel.connect.com.au!munnari.OZ.AU!news.ecn.uoknor.edu!feed1.news.erols.com!news.bbnplanet.com!cpk-news-hub1.bbnplanet.com!newsserver.jvnc.net!newsreader.jvnc.net!netplex-tech.com!not-for-mail
From: vikas@netplex-tech.Com (Vikas Aggarwal)
Subject: Re: UDP Sockets sendto() failures
Message-ID: <E3H7yK.18t@netplex-tech.com>
Followup-To: comp.unix.programmer,comp.unix.bsd.freebsd.misc
Lines: 179
Sender: news@netplex-tech.com
Organization: Netplex Technologies Inc.
X-Newsreader: TIN [UNIX 1.3 950824BETA PL0]
References: <E3DxuK.6I8@netplex-tech.com>
Date: Sat, 4 Jan 1997 09:06:19 GMT
Xref: euryale.cc.adfa.oz.au comp.unix.programmer:48287 comp.unix.bsd.freebsd.misc:33521

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.
 *
 *      -vikas@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);
}