Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2a50f28c authored by Al Viro's avatar Al Viro Committed by David S. Miller
Browse files

[ATALK]: endianness annotations

parent 82fe7c92
Loading
Loading
Loading
Loading
+1 −4
Original line number Diff line number Diff line
@@ -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 */

+1 −39
Original line number Diff line number Diff line
@@ -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;
+28 −51
Original line number Diff line number Diff line
@@ -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);
	}
	err = skb_copy_datagram_iovec(skb, offset, msg->msg_iov, copied);

	if (!err) {
		if (sat) {