diff options
| author | Al Viro <viro@zeniv.linux.org.uk> | 2006-09-26 21:22:08 -0700 | 
|---|---|---|
| committer | David S. Miller <davem@sunset.davemloft.net> | 2006-09-28 17:53:58 -0700 | 
| commit | 2a50f28c326d20ab4556be1b867ecddf6aefbb88 (patch) | |
| tree | 6890abb1bf8ebfadca86b19bceb48502bda47001 | |
| parent | 82fe7c924e61f9444b376498496942d41fbe9d26 (diff) | |
| download | olio-linux-3.10-2a50f28c326d20ab4556be1b867ecddf6aefbb88.tar.xz olio-linux-3.10-2a50f28c326d20ab4556be1b867ecddf6aefbb88.zip  | |
[ATALK]: endianness annotations
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | drivers/net/appletalk/ipddp.c | 5 | ||||
| -rw-r--r-- | include/linux/atalk.h | 40 | ||||
| -rw-r--r-- | net/appletalk/ddp.c | 79 | 
3 files changed, 30 insertions, 94 deletions
diff --git a/drivers/net/appletalk/ipddp.c b/drivers/net/appletalk/ipddp.c index 7f7dd450226..b98592a8bac 100644 --- a/drivers/net/appletalk/ipddp.c +++ b/drivers/net/appletalk/ipddp.c @@ -145,9 +145,7 @@ static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev)  	/* Create the Extended DDP header */  	ddp = (struct ddpehdr *)skb->data; -        ddp->deh_len = skb->len; -        ddp->deh_hops = 1; -        ddp->deh_pad = 0; +        ddp->deh_len_hops = htons(skb->len + (1<<10));          ddp->deh_sum = 0;  	/* @@ -170,7 +168,6 @@ static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev)          ddp->deh_sport = 72;          *((__u8 *)(ddp+1)) = 22;        	/* ddp type = IP */ -        *((__u16 *)ddp)=ntohs(*((__u16 *)ddp));	/* fix up length field */          skb->protocol = htons(ETH_P_ATALK);     /* Protocol has changed */ diff --git a/include/linux/atalk.h b/include/linux/atalk.h index 6ba3aa8a81f..75b8baca08f 100644 --- a/include/linux/atalk.h +++ b/include/linux/atalk.h @@ -88,15 +88,7 @@ static inline struct atalk_sock *at_sk(struct sock *sk)  #include <asm/byteorder.h>  struct ddpehdr { -#ifdef __LITTLE_ENDIAN_BITFIELD -	__u16	deh_len:10, -		deh_hops:4, -		deh_pad:2; -#else -	__u16	deh_pad:2, -		deh_hops:4, -		deh_len:10; -#endif +	__be16	deh_len_hops;	/* lower 10 bits are length, next 4 - hops */  	__be16	deh_sum;  	__be16	deh_dnet;  	__be16	deh_snet; @@ -112,36 +104,6 @@ static __inline__ struct ddpehdr *ddp_hdr(struct sk_buff *skb)  	return (struct ddpehdr *)skb->h.raw;  } -/* - *	Don't drop the struct into the struct above.  You'll get some - *	surprise padding. - */ -struct ddpebits { -#ifdef __LITTLE_ENDIAN_BITFIELD -	__u16	deh_len:10, -		deh_hops:4, -		deh_pad:2; -#else -	__u16	deh_pad:2, -		deh_hops:4, -		deh_len:10; -#endif -}; - -/* Short form header */ -struct ddpshdr { -#ifdef __LITTLE_ENDIAN_BITFIELD -	__u16	dsh_len:10, -		dsh_pad:6; -#else -	__u16	dsh_pad:6, -		dsh_len:10; -#endif -	__u8	dsh_dport; -	__u8	dsh_sport; -	/* And netatalk apps expect to stick the type in themselves */ -}; -  /* AppleTalk AARP headers */  struct elapaarp {  	__be16	hw_type; diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index 96dc6bb52d1..708e2e0371a 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c @@ -1002,7 +1002,7 @@ static unsigned long atalk_sum_skb(const struct sk_buff *skb, int offset,  	return sum;  } -static unsigned short atalk_checksum(const struct sk_buff *skb, int len) +static __be16 atalk_checksum(const struct sk_buff *skb, int len)  {  	unsigned long sum; @@ -1010,7 +1010,7 @@ static unsigned short atalk_checksum(const struct sk_buff *skb, int len)  	sum = atalk_sum_skb(skb, 4, len-4, 0);  	/* Use 0xFFFF for 0. 0 itself means none */ -	return sum ? htons((unsigned short)sum) : 0xFFFF; +	return sum ? htons((unsigned short)sum) : htons(0xFFFF);  }  static struct proto ddp_proto = { @@ -1289,7 +1289,7 @@ static int handle_ip_over_ddp(struct sk_buff *skb)  #endif  static void atalk_route_packet(struct sk_buff *skb, struct net_device *dev, -			       struct ddpehdr *ddp, struct ddpebits *ddphv, +			       struct ddpehdr *ddp, __u16 len_hops,  			       int origlen)  {  	struct atalk_route *rt; @@ -1317,10 +1317,12 @@ static void atalk_route_packet(struct sk_buff *skb, struct net_device *dev,  	/* Route the packet */  	rt = atrtr_find(&ta); -	if (!rt || ddphv->deh_hops == DDP_MAXHOPS) +	/* increment hops count */ +	len_hops += 1 << 10; +	if (!rt || !(len_hops & (15 << 10)))  		goto free_it; +  	/* FIXME: use skb->cb to be able to use shared skbs */ -	ddphv->deh_hops++;  	/*  	 * Route goes through another gateway, so set the target to the @@ -1335,11 +1337,10 @@ static void atalk_route_packet(struct sk_buff *skb, struct net_device *dev,          /* Fix up skb->len field */          skb_trim(skb, min_t(unsigned int, origlen,  			    (rt->dev->hard_header_len + -			     ddp_dl->header_length + ddphv->deh_len))); +			     ddp_dl->header_length + (len_hops & 1023)))); -	/* Mend the byte order */  	/* FIXME: use skb->cb to be able to use shared skbs */ -	*((__u16 *)ddp) = ntohs(*((__u16 *)ddphv)); +	ddp->deh_len_hops = htons(len_hops);  	/*  	 * Send the buffer onwards @@ -1394,7 +1395,7 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev,  	struct atalk_iface *atif;  	struct sockaddr_at tosat;          int origlen; -        struct ddpebits ddphv; +	__u16 len_hops;  	/* Don't mangle buffer if shared */  	if (!(skb = skb_share_check(skb, GFP_ATOMIC)))  @@ -1406,16 +1407,11 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev,  	ddp = ddp_hdr(skb); -	/* -	 *	Fix up the length field	[Ok this is horrible but otherwise -	 *	I end up with unions of bit fields and messy bit field order -	 *	compiler/endian dependencies..] -	 */ -	*((__u16 *)&ddphv) = ntohs(*((__u16 *)ddp)); +	len_hops = ntohs(ddp->deh_len_hops);  	/* Trim buffer in case of stray trailing data */  	origlen = skb->len; -	skb_trim(skb, min_t(unsigned int, skb->len, ddphv.deh_len)); +	skb_trim(skb, min_t(unsigned int, skb->len, len_hops & 1023));  	/*  	 * Size check to see if ddp->deh_len was crap @@ -1430,7 +1426,7 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev,  	 * valid for net byte orders all over the networking code...  	 */  	if (ddp->deh_sum && -	    atalk_checksum(skb, ddphv.deh_len) != ddp->deh_sum) +	    atalk_checksum(skb, len_hops & 1023) != ddp->deh_sum)  		/* Not a valid AppleTalk frame - dustbin time */  		goto freeit; @@ -1444,7 +1440,7 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev,  		/* Not ours, so we route the packet via the correct  		 * AppleTalk iface  		 */ -		atalk_route_packet(skb, dev, ddp, &ddphv, origlen); +		atalk_route_packet(skb, dev, ddp, len_hops, origlen);  		goto out;  	} @@ -1489,7 +1485,7 @@ static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev,  		/* Find our address */  		struct atalk_addr *ap = atalk_find_dev_addr(dev); -		if (!ap || skb->len < sizeof(struct ddpshdr)) +		if (!ap || skb->len < sizeof(__be16) || skb->len > 1023)  			goto freeit;  		/* Don't mangle buffer if shared */ @@ -1519,11 +1515,8 @@ static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev,  		/*  		 * Not sure about this bit...  		 */ -		ddp->deh_len   = skb->len; -		ddp->deh_hops  = DDP_MAXHOPS;	/* Non routable, so force a drop -						   if we slip up later */ -		/* Mend the byte order */ -		*((__u16 *)ddp) = htons(*((__u16 *)ddp)); +		/* Non routable, so force a drop if we slip up later */ +		ddp->deh_len_hops = htons(skb->len + (DDP_MAXHOPS << 10));  	}  	skb->h.raw = skb->data; @@ -1622,16 +1615,7 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr  	SOCK_DEBUG(sk, "SK %p: Begin build.\n", sk);  	ddp = (struct ddpehdr *)skb_put(skb, sizeof(struct ddpehdr)); -	ddp->deh_pad  = 0; -	ddp->deh_hops = 0; -	ddp->deh_len  = len + sizeof(*ddp); -	/* -	 * Fix up the length field [Ok this is horrible but otherwise -	 * I end up with unions of bit fields and messy bit field order -	 * compiler/endian dependencies.. -	 */ -	*((__u16 *)ddp) = ntohs(*((__u16 *)ddp)); - +	ddp->deh_len_hops  = htons(len + sizeof(*ddp));  	ddp->deh_dnet  = usat->sat_addr.s_net;  	ddp->deh_snet  = at->src_net;  	ddp->deh_dnode = usat->sat_addr.s_node; @@ -1712,8 +1696,8 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr  	struct sockaddr_at *sat = (struct sockaddr_at *)msg->msg_name;  	struct ddpehdr *ddp;  	int copied = 0; +	int offset = 0;  	int err = 0; -        struct ddpebits ddphv;  	struct sk_buff *skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,  						flags & MSG_DONTWAIT, &err);  	if (!skb) @@ -1721,25 +1705,18 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr  	/* FIXME: use skb->cb to be able to use shared skbs */  	ddp = ddp_hdr(skb); -	*((__u16 *)&ddphv) = ntohs(*((__u16 *)ddp)); +	copied = ntohs(ddp->deh_len_hops) & 1023; -	if (sk->sk_type == SOCK_RAW) { -		copied = ddphv.deh_len; -		if (copied > size) { -			copied = size; -			msg->msg_flags |= MSG_TRUNC; -		} +	if (sk->sk_type != SOCK_RAW) { +		offset = sizeof(*ddp); +		copied -= offset; +	} -		err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); -	} else { -		copied = ddphv.deh_len - sizeof(*ddp); -		if (copied > size) { -			copied = size; -			msg->msg_flags |= MSG_TRUNC; -		} -		err = skb_copy_datagram_iovec(skb, sizeof(*ddp), -					      msg->msg_iov, copied); +	if (copied > size) { +		copied = size; +		msg->msg_flags |= MSG_TRUNC;  	} +	err = skb_copy_datagram_iovec(skb, offset, msg->msg_iov, copied);  	if (!err) {  		if (sat) {  |