* Re: recvfrom and sockaddr_in.sin_port
2001-07-08 17:14 Adam
@ 2001-07-08 17:05 ` Chris Wedgwood
2001-07-08 18:08 ` Adam
0 siblings, 1 reply; 7+ messages in thread
From: Chris Wedgwood @ 2001-07-08 17:05 UTC (permalink / raw)
To: Adam; +Cc: linux-kernel
On Sun, Jul 08, 2001 at 12:14:47PM -0500, Adam wrote:
I have attached a simple program I used for generating those
results.
'fromlen' needs to be set to sizeof 'from' before the recvfrom syscall
--cw
^ permalink raw reply [flat|nested] 7+ messages in thread
* recvfrom and sockaddr_in.sin_port
@ 2001-07-08 17:14 Adam
2001-07-08 17:05 ` Chris Wedgwood
0 siblings, 1 reply; 7+ messages in thread
From: Adam @ 2001-07-08 17:14 UTC (permalink / raw)
To: linux-kernel
[-- Attachment #1: Type: TEXT/PLAIN, Size: 1066 bytes --]
hello,
I'm using recvfrom, and upon return it should fill in
from argument with sockaddr_in data structure. from
ip(7) man page I get that it has format of :
struct sockaddr_in {
sa_family_t sin_family; /* address family: AF_INET */
u_int16_t sin_port; /* port in network byte order*/
struct in_addr sin_addr; /* internet address */
};
for PF_INET type of socket. Now if I run the program the, data in
the from field comes out as:
2 0 0 0 192 168 1 4 61 63 140 200 85 214 2
| | |
AF_INET :2
IP :192.168.1.4
and as show in above example and other repeated test, the port
part is always set to 0. Shouldn't that be set to port number?
on similar token the "padding" part after the IP is always set
to the same pattern. Shouldn't it rather be zeroed, or be
some random data?
I have attached a simple program I used for generating those
results.
--
Adam
http://www.eax.com The Supreme Headquarters of the 32 bit registers
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Type: TEXT/x-csrc; name="test.c", Size: 1713 bytes --]
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
int main (int argc, char **argv) {
size_t buflen = 1024;
char buf[buflen];
struct sockaddr_in from;
socklen_t fromlen = sizeof(struct sockaddr_in);
int flags;
int rawsock;
int bytesread;
int i;
unsigned char * ptr;
rawsock = socket(PF_INET,SOCK_RAW,IPPROTO_TCP);
if (rawsock == -1)
perror("socket():");
flags = MSG_WAITALL;
memset(&from,0,fromlen);
bytesread = recvfrom(rawsock,&buf,buflen,flags,
(struct sockaddr*)(&from),&fromlen);
ptr = (unsigned char*)&from;
for(i=0;i<fromlen;i++) {
printf("%i ",*ptr);
ptr++;
}
printf("\n");
if (bytesread == -1) {
printf("err # : %i \n",errno);
perror("recvfrom():");
return -1;
}
if (argc ==2) {
struct hostent *host;
printf("msg len: %i \n",bytesread);
printf("frm len: %i \n",fromlen);
printf("IPv4 : type:%i port:%X addr:%X \n",
from.sin_family,
ntohs(from.sin_port),
from.sin_addr.s_addr);
host=gethostbyaddr(&(from.sin_addr.s_addr),
fromlen,from.sin_family);
if (host == NULL ) {
printf("err # : %i \n",h_errno);
herror("gethostbyaddr():");
}
printf("host: (");
ptr = (unsigned char*)(&(from.sin_addr.s_addr));
for(i=0;i<4;i++) {
printf("%i",*(ptr++));
if (i<3)
printf(".");
}
if (host == NULL)
printf(") \n");
else
printf(") %s \n",host->h_name);
}
return 0;
}
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: recvfrom and sockaddr_in.sin_port
2001-07-08 18:08 ` Adam
@ 2001-07-08 17:21 ` Chris Wedgwood
2001-07-08 18:42 ` Adam
0 siblings, 1 reply; 7+ messages in thread
From: Chris Wedgwood @ 2001-07-08 17:21 UTC (permalink / raw)
To: Adam; +Cc: linux-kernel
On Sun, Jul 08, 2001 at 01:08:37PM -0500, Adam wrote:
isn't it set? to quote from the example I have attached:
socklen_t fromlen = sizeof(struct sockaddr_in);
sorry, I misread the source (the memset line)
you are using raw sockets, what does port mean for raw sockets?
--cw
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: recvfrom and sockaddr_in.sin_port
2001-07-08 17:05 ` Chris Wedgwood
@ 2001-07-08 18:08 ` Adam
2001-07-08 17:21 ` Chris Wedgwood
0 siblings, 1 reply; 7+ messages in thread
From: Adam @ 2001-07-08 18:08 UTC (permalink / raw)
To: Chris Wedgwood; +Cc: linux-kernel
> I have attached a simple program I used for generating those
> results.
>
> 'fromlen' needs to be set to sizeof 'from' before the recvfrom syscall
isn't it set? to quote from the example I have attached:
socklen_t fromlen = sizeof(struct sockaddr_in);
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: recvfrom and sockaddr_in.sin_port
2001-07-08 18:42 ` Adam
@ 2001-07-08 18:31 ` Chris Wedgwood
0 siblings, 0 replies; 7+ messages in thread
From: Chris Wedgwood @ 2001-07-08 18:31 UTC (permalink / raw)
To: Adam; +Cc: linux-kernel
On Sun, Jul 08, 2001 at 01:42:28PM -0500, Adam wrote:
so it seem to imply that only tcp packets only are to be passed.
still group "SOCK_RAW" is subset of the PF_INET group (the way
I see it), so from ip(7) man page I should use sockaddr_in
structure, which should be defined in this particular case,
as it ought be for IPPROTO_UDP.
have you dumped the packet contents? presumably its a raw packet,
protocol 6, and the header and such like is returned
i see no reason, for raw packets to fill out sin_port whatoever, it
just doesn't make sense that raw packets have a port
--cw
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: recvfrom and sockaddr_in.sin_port
2001-07-08 17:21 ` Chris Wedgwood
@ 2001-07-08 18:42 ` Adam
2001-07-08 18:31 ` Chris Wedgwood
0 siblings, 1 reply; 7+ messages in thread
From: Adam @ 2001-07-08 18:42 UTC (permalink / raw)
To: Chris Wedgwood; +Cc: linux-kernel
> isn't it set? to quote from the example I have attached:
> socklen_t fromlen = sizeof(struct sockaddr_in);
> sorry, I misread the source (the memset line)
> you are using raw sockets, what does port mean for raw sockets?
well, from raw(7) man page:
raw_socket = socket(PF_INET, SOCK_RAW, int protocol);
[...]
All packets [...] matching the protocol number speci
fied for the raw socket are passed to this socket.
so it seem to imply that only tcp packets only are to be passed.
still group "SOCK_RAW" is subset of the PF_INET group (the way
I see it), so from ip(7) man page I should use sockaddr_in
structure, which should be defined in this particular case,
as it ought be for IPPROTO_UDP.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: recvfrom and sockaddr_in.sin_port
@ 2001-07-08 19:28 Andi Kleen
0 siblings, 0 replies; 7+ messages in thread
From: Andi Kleen @ 2001-07-08 19:28 UTC (permalink / raw)
Cc: linux-kernel, davem
Adam <adam@eax.com> writes:
>
> and as show in above example and other repeated test, the port
> part is always set to 0. Shouldn't that be set to port number?
SOCK_RAW has no ports, so no.
>
> on similar token the "padding" part after the IP is always set
> to the same pattern. Shouldn't it rather be zeroed, or be
> some random data?
It should stay at the old value or alternatively be zeroed. That's a
kernel bug.
Here is a patch that implements the first alternative. David, please consider
applying.
diff -burp linux/include/linux/in.h linux-work/include/linux/in.h
--- linux/include/linux/in.h Thu Jul 5 13:18:27 2001
+++ linux-work/include/linux/in.h Sun Jul 8 19:05:30 2001
@@ -109,6 +109,10 @@ struct in_pktinfo
};
/* Structure describing an Internet (IP) socket address. */
+/* Note here and in others places is the assumption made that there
+ are no holes in in this structure. This is ok for all architectures
+ which layout structures members at worst to their natural
+ alignment. -AK */
#define __SOCK_SIZE__ 16 /* sizeof(struct sockaddr) */
struct sockaddr_in {
sa_family_t sin_family; /* Address family */
@@ -119,7 +123,7 @@ struct sockaddr_in {
unsigned char __pad[__SOCK_SIZE__ - sizeof(short int) -
sizeof(unsigned short int) - sizeof(struct in_addr)];
};
-#define sin_zero __pad /* for BSD UNIX comp. -FvK */
+#define sin_zero __pad
/*
diff -burp linux/net/ipv4/af_inet.c linux-work/net/ipv4/af_inet.c
--- linux/net/ipv4/af_inet.c Wed Jul 4 17:21:32 2001
+++ linux-work/net/ipv4/af_inet.c Sun Jul 8 19:05:31 2001
@@ -729,7 +729,7 @@ static int inet_getname(struct socket *s
sin->sin_port = sk->sport;
sin->sin_addr.s_addr = addr;
}
- *uaddr_len = sizeof(*sin);
+ *uaddr_len = sizeof(offsetof(struct sockaddr_in, sin_zero));
return(0);
}
diff -burp linux/net/ipv4/raw.c linux-work/net/ipv4/raw.c
--- linux/net/ipv4/raw.c Wed Jul 4 17:21:32 2001
+++ linux-work/net/ipv4/raw.c Sun Jul 8 19:06:10 2001
@@ -493,7 +493,7 @@ int raw_recvmsg(struct sock *sk, struct
goto out;
if (addr_len)
- *addr_len = sizeof(*sin);
+ *addr_len = offsetof(struct sockaddr_in, sin_zero);
if (flags & MSG_ERRQUEUE) {
err = ip_recv_error(sk, msg, len);
diff -burp linux/net/ipv4/udp.c linux-work/net/ipv4/udp.c
--- linux/net/ipv4/udp.c Thu Apr 12 21:11:39 2001
+++ linux-work/net/ipv4/udp.c Sun Jul 8 19:05:31 2001
@@ -635,7 +635,7 @@ int udp_recvmsg(struct sock *sk, struct
* Check any passed addresses
*/
if (addr_len)
- *addr_len=sizeof(*sin);
+ *addr_len=offsetof(struct sockaddr_in, sin_zero);
if (flags & MSG_ERRQUEUE)
return ip_recv_error(sk, msg, len);
-Andi
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2001-07-08 19:28 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2001-07-08 19:28 recvfrom and sockaddr_in.sin_port Andi Kleen
-- strict thread matches above, loose matches on Subject: below --
2001-07-08 17:14 Adam
2001-07-08 17:05 ` Chris Wedgwood
2001-07-08 18:08 ` Adam
2001-07-08 17:21 ` Chris Wedgwood
2001-07-08 18:42 ` Adam
2001-07-08 18:31 ` Chris Wedgwood
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox