home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!munnari.oz.au!mips!public!thad
- From: thad@public.BTR.COM (Thaddeus P. Floryan)
- Newsgroups: comp.unix.questions
- Subject: Re: recvfrom() problems
- Message-ID: <7516@public.BTR.COM>
- Date: 26 Jul 92 22:32:03 GMT
- References: <1992Jul17.125731.1@hamp.hampshir>
- Organization: BTR Public Access UNIX, Mountain View CA
- Lines: 248
-
- In article <1992Jul17.125731.1@hamp.hampshir> dhirmes@hamp.hampshire.edu writes:
- >
- >I'm writing a program using BSD socket interface. I'm trying to
- >utilize the UDP (datagram) service, but when I run my programs, I
- >get a "Bad Address" error. I've tried several examples from tutorials,
- > but I get the same error. I'm working with SunOS 4.0.1 and some of
- >the examples were written for Ultrix. I was told there might be slight
- >differences in the TCP/IP structures used by BSD implementations. I'vewritten
- >programs usinSOCK_STREAM which have worked fine, which adds to my
- >confusion. Oh, and the error only occurs when I attempt a recvfrom(),
- >it appears to work when I use sendto().
- >
- >Can anyone help me out here?
-
- The enclosed routine has functioned fine on every system upon which I've
- tried it; it is a part of the "rsetclk" program I wrote for the 3B1 and
- archived at ftp.uu.net and osu-cis (aka archive.cis.ohio-state.edu).
-
- The systems upon which I know it works include SunOS 4.1.*, IRIX 4.0.*,
- HP-UX 7.* and 8.*, 3B1, 3B2, CTIX 6.2.*, Mac A/UX 2.*, etc.
-
- Thad Floryan [ thad@btr.com (OR) {decwrl, mips, fernwood}!btr!thad ]
-
- ---- Cut Here and feed the following to sh ----
- #!/bin/sh
- # This is a shell archive (produced by shar 3.49)
- # To extract the files from this archive, save it to a file, remove
- # everything above the "!/bin/sh" line above, and type "sh file_name".
- #
- # made 07/26/1992 22:32 UTC by thad@thadlabs
- # Source directory /usr/local/src/rsetclk
- #
- # existing files will NOT be overwritten unless -c is specified
- #
- # This shar contains:
- # length mode name
- # ------ ---------- ------------------------------------------
- # 4772 -rw-r--r-- rhost_time.c
- #
- # ============= rhost_time.c ==============
- if test -f 'rhost_time.c' -a X"$1" != X"-c"; then
- echo 'x - skipping rhost_time.c (File already exists)'
- else
- echo 'x - extracting rhost_time.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'rhost_time.c' &&
- X/****************************************************************************
- X * RHOST_TIME RHOST_TIME
- X *
- X * NAME
- X *
- X * rhost_time - gets current time_t value from a remote host adjusted
- X * to UNIX-style time.
- X *
- X * SYNOPSIS
- X *
- X * time_t rhost_time(hostname, errptr)
- X *
- X * char *hostname, *errptr
- X *
- X * DESCRIPTION
- X *
- X * Returns the UNIX-style time from a remote host's inetd server. Note
- X * the time returned by the inetd server is the number of seconds since
- X * midnight, Jan 1, 1900, in a timeval structure. Since gettimeofday()
- X * returns the number of seconds since midnight, Jan 1, 1970, the value
- X * 2208988800 seconds was added to gettimeofday(2)'s returned value and
- X * we have to make an adjustment to normal UNIX system time. Note that
- X * the tv_usec value will always be zero. For compilers that cannot
- X * handle such large numbers, 2208988800 is equivalent to 0x83AA7E80.
- X *
- X * The returned value is compatible to that from time(). Note that since
- X * we cannot assume we're running on a "real" computer whose byte order
- X * is the same as network byte order, ntohl() is applied to the value
- X * retrieved from the remote host to accomodate "little endian" machines
- X * such as the DEC {VAX or Alpha} or Intel 80?86 platforms.
- X *
- X * The hostname is a null-terminated string whose form may be anything
- X * normally used to reach that host (i.e. "host" or "host.domain.com").
- X *
- X * RETURN VALUES
- X *
- X * On successful completion, rhost_time() returns the time as documented
- X * above.
- X *
- X * On error, rhost_time() returns a -1, errno will be set, and a pointer
- X * to the error string will be returned via *errptr.
- X *
- X * BUGS
- X *
- X * The return value for the error message points to a static data area
- X * whose content is potentially overwritten by each call to rhost_time.
- X *
- X * SEE ALSO
- X *
- X * time(), stime()
- X *
- X */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/socket.h>
- X#include <sys/time.h>
- X#include <netinet/in.h>
- X#include <netdb.h>
- X#include <signal.h>
- X#include <setjmp.h>
- X#include <errno.h>
- X
- X#define SERVICE "time"
- X#define TIMEOUT 10 /* seconds to wait for reply from rhost */
- X
- Xextern char *sys_errlist[]; /* system error strings */
- X
- X jmp_buf env; /* used by timeout handler */
- X char errmsg[80]; /* text of error message */
- X
- Xtime_t
- Xrhost_time(hostname, errptr)
- X char *hostname;
- X char **errptr;
- X{
- X
- X int noanswer();
- X
- X int s;
- X int n;
- X int len;
- X int status;
- X struct timeval rtimebuf;
- X struct hostent *hp;
- X struct servent *sp;
- X struct sockaddr_in sin;
- X
- X/*
- X * Get a datagram socket in the Internet domain
- X */
- X s = socket(AF_INET, SOCK_DGRAM, 0);
- X if (s < 0) {
- X sprintf(errmsg, "socket: %s\n", sys_errlist[errno]);
- X *errptr = errmsg;
- X return -1;
- X }
- X/*
- X * Look up the port number of the service.
- X */
- X sp = getservbyname(SERVICE, "udp");
- X if (sp == NULL) {
- X errno = EINVAL;
- X sprintf(errmsg, "%s/udp: unknown service\n", SERVICE);
- X *errptr = errmsg;
- X close(s);
- X return -1;
- X }
- X/*
- X * Look up the network number of the host on the command line
- X */
- X hp = gethostbyname(hostname);
- X if (hp == NULL) {
- X errno = EINVAL;
- X sprintf(errmsg, "%s: host unknown\n", hostname);
- X *errptr = errmsg;
- X close(s);
- X return -1;
- X }
- X/*
- X * Build the address of the server on the remote machine
- X */
- X sin.sin_family = AF_INET;
- X sin.sin_port = sp->s_port;
- X
- X bcopy(hp->h_addr, &sin.sin_addr, hp->h_length);
- X/*
- X * Send a datagram to the server
- X */
- X status = sendto(s, &rtimebuf, sizeof(rtimebuf), 0, &sin, sizeof(sin));
- X if (status < 0) {
- X sprintf(errmsg, "sendto(%s): %s\n", hostname, sys_errlist[errno]);
- X *errptr = errmsg;
- X close(s);
- X return -1;
- X }
- X/*
- X * Enable timeout signal in case remote host is dead
- X */
- X signal(SIGALRM, noanswer);
- X alarm(TIMEOUT);
- X/*
- X * Test if we timed out waiting for remote host to respond; presume the
- X * remote host is down if so.
- X */
- X status = setjmp(env);
- X if (status > 0) {
- X errno = EHOSTDOWN;
- X sprintf(errmsg, "timeout(%s): %s\n", hostname, sys_errlist[errno]);
- X *errptr = errmsg;
- X close(s);
- X return -1;
- X }
- X/*
- X * Receive a datagram back
- X */
- X len = sizeof(sin);
- X n = recvfrom(s, &rtimebuf, sizeof(rtimebuf), 0, &sin, &len);
- X/*
- X * Disable timeout signal
- X */
- X alarm(0);
- X/*
- X * Test state of returned datagram
- X */
- X if (n < 0) {
- X sprintf(errmsg, "recvfrom(%s): %s", hostname, sys_errlist[errno]);
- X *errptr = errmsg;
- X close(s);
- X return -1;
- X }
- X/*
- X * Accomodate "little endian" architectures.
- X */
- X rtimebuf.tv_sec = ntohl(rtimebuf.tv_sec);
- X/*
- X * Adjust time with respect to the UNIX epoch of Jan. 1, 1970 00:00:00 GMT
- X */
- X rtimebuf.tv_sec -= 2208988800L;
- X/*
- X * Release socket
- X */
- X close(s);
- X
- X return rtimebuf.tv_sec;
- X}
- X
- X/*
- X * rhost_time() timeout handler
- X *
- X */
- Xnoanswer()
- X{
- X longjmp(env, 1);
- X}
- SHAR_EOF
- chmod 0644 rhost_time.c ||
- echo 'restore of rhost_time.c failed'
- Wc_c="`wc -c < 'rhost_time.c'`"
- test 4772 -eq "$Wc_c" ||
- echo 'rhost_time.c: original size 4772, current size' "$Wc_c"
- fi
- exit 0
-