[ATALK]: endianness annotations

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index 96dc6bb..708e2e0 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -1002,7 +1002,7 @@
 	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 @@
 	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 @@
 #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 @@
 
 	/* 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 @@
         /* 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 @@
 	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 @@
 
 	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 @@
 	 * 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 @@
 		/* 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 @@
 		/* 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 @@
 		/*
 		 * 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 @@
 	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 @@
 	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,26 +1705,19 @@
 
 	/* 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;
-		}
-
-		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 (sk->sk_type != SOCK_RAW) {
+		offset = sizeof(*ddp);
+		copied -= offset;
 	}
 
+	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) {
 			sat->sat_family      = AF_APPLETALK;