Date: Fri, 14 Sep 2001 12:23:57 -0700 From: Jos Backus <josb@cncdsl.com> To: freebsd-net@freebsd.org Subject: How does getsockname() work? Message-ID: <20010914122357.A49323@lizzy.bugworks.com>
next in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
I am seeing the following difference between FreeBSD and Solaris when using
the attached program, which uses getsockname().
I am using the following command to test this program:
snmpwalk -p 1234 <host> public
<host> being either goldenbytes or taiko.
On FreeBSD 4 I see:
goldenbytes:~/udp% ./udp &
[1] 64015
goldenbytes:~/udp% received on 0.0.0.0:0
received 37 bytes from 157.57.212.23:1446
received on 0.0.0.0:0
received 37 bytes from 157.57.212.23:1446
received on 0.0.0.0:0
received 37 bytes from 157.57.212.23:1446
received on 0.0.0.0:0
received 37 bytes from 157.57.212.23:1446
On Solaris 7 I see:
taiko:~/udp% ./udp &
[1] 21129
taiko:~/udp% received on 0.0.0.0:1234
received 37 bytes from 157.57.212.23:1448
received on 0.0.0.0:1234
received 37 bytes from 157.57.212.23:1448
received on 0.0.0.0:1234
received 37 bytes from 157.57.212.23:1448
received on 0.0.0.0:1234
received 37 bytes from 157.57.212.23:1448
The 0.0.0.0 is caused by using INADDR_ANY as the binding address; what I don't
understand is why Solaris shows the portnumber whereas FreeBSD doesn't. Surely
I am doing something wrong, but what?
Thanks,
--
Jos Backus _/ _/_/_/ Santa Clara, CA
_/ _/ _/
_/ _/_/_/
_/ _/ _/ _/
josb@cncdsl.com _/_/ _/_/_/ use Std::Disclaimer;
[-- Attachment #2 --]
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PDU_SIZE 1500
struct sock {
int fport;
int fsockfd;
long sockbuflen;
};
static int
init_sock(ctx)
struct sock *ctx;
{
struct sockaddr_in local_address;
bzero(&local_address, sizeof local_address);
local_address.sin_family = AF_INET;
local_address.sin_addr.s_addr = htonl(INADDR_ANY);
local_address.sin_port = htons(ctx->fport);
if ((ctx->fsockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
fprintf(stderr, "socket(): %s\n", strerror(errno));
exit(1);
}
if (bind(ctx->fsockfd,
(struct sockaddr *)&local_address, sizeof local_address) < 0) {
fprintf(stderr, "bind(): %s\n", strerror(errno));
exit(1);
}
}
static int
receive(ctx)
struct sock *ctx;
{
unsigned char fpdu[PDU_SIZE];
struct sockaddr_in remote_address;
struct sockaddr_in local_address;
int i, len, n, local_len;
while (1) {
len = sizeof remote_address;
if ((n = recvfrom(ctx->fsockfd, (char *)fpdu,
sizeof(fpdu), 0,
(struct sockaddr *)&remote_address, &len)) == -1) {
fprintf(stderr, "recvfrom(): %s\n", strerror(errno));
exit(1);
}
if (getsockname(ctx->fsockfd, (struct sockaddr *)&local_address,
&local_len) == -1) {
fprintf(stderr, "getsockname(): %s\n", strerror(errno));
exit(1);
}
if (n > PDU_SIZE) {
fprintf(stderr, "Warning: %d excess bytes discarded\n",
n - PDU_SIZE);
n = PDU_SIZE;
}
if (len != sizeof remote_address) {
fprintf(stderr, "recvfrom() return address length %d - expected %d\n",
len, sizeof remote_address);
exit(1);
}
fprintf(stderr, "received on %s:%d\n",
inet_ntoa(local_address.sin_addr),
(int)ntohs(local_address.sin_port));
fprintf(stderr, "received %d bytes from %s:%d\n",
n,
inet_ntoa(remote_address.sin_addr),
(int)ntohs(remote_address.sin_port));
}
}
int
main(int ac, char *av[])
{
struct sock s;
s.fport = 1234;
s.sockbuflen = 65536;
init_sock(&s);
receive(&s);
}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010914122357.A49323>
