Skip to contentSkip to conversation

recvfrom and sockaddr_in.sin_port

DISCUSSION Andi Kleen 1 participant 1 message Jul 8, 2001

Subsystems (2)
lore
Share & tools
lore

Andi Kleen

author
#0 lore raw
Quoted 3 lines · Adam

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.

Quoted 4 lines

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.

include/linux/in.h +5 -1
diff -burp linux/include/linux/in.h linux-work/include/linux/in.h
@@ -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
 
 
 /*
net/ipv4/af_inet.c +1 -1
diff -burp linux/net/ipv4/af_inet.c linux-work/net/ipv4/af_inet.c
@@ -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);
 }
 
net/ipv4/raw.c +1 -1
diff -burp linux/net/ipv4/raw.c linux-work/net/ipv4/raw.c
@@ -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);
net/ipv4/udp.c +1 -1
diff -burp linux/net/ipv4/udp.c linux-work/net/ipv4/udp.c
@@ -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