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

[ATALK]: endianness annotations

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 82fe7c92
...@@ -145,9 +145,7 @@ static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -145,9 +145,7 @@ static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev)
/* Create the Extended DDP header */ /* Create the Extended DDP header */
ddp = (struct ddpehdr *)skb->data; ddp = (struct ddpehdr *)skb->data;
ddp->deh_len = skb->len; ddp->deh_len_hops = htons(skb->len + (1<<10));
ddp->deh_hops = 1;
ddp->deh_pad = 0;
ddp->deh_sum = 0; ddp->deh_sum = 0;
/* /*
...@@ -170,7 +168,6 @@ static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -170,7 +168,6 @@ static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev)
ddp->deh_sport = 72; ddp->deh_sport = 72;
*((__u8 *)(ddp+1)) = 22; /* ddp type = IP */ *((__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 */ skb->protocol = htons(ETH_P_ATALK); /* Protocol has changed */
......
...@@ -88,15 +88,7 @@ static inline struct atalk_sock *at_sk(struct sock *sk) ...@@ -88,15 +88,7 @@ static inline struct atalk_sock *at_sk(struct sock *sk)
#include <asm/byteorder.h> #include <asm/byteorder.h>
struct ddpehdr { struct ddpehdr {
#ifdef __LITTLE_ENDIAN_BITFIELD __be16 deh_len_hops; /* lower 10 bits are length, next 4 - hops */
__u16 deh_len:10,
deh_hops:4,
deh_pad:2;
#else
__u16 deh_pad:2,
deh_hops:4,
deh_len:10;
#endif
__be16 deh_sum; __be16 deh_sum;
__be16 deh_dnet; __be16 deh_dnet;
__be16 deh_snet; __be16 deh_snet;
...@@ -112,36 +104,6 @@ static __inline__ struct ddpehdr *ddp_hdr(struct sk_buff *skb) ...@@ -112,36 +104,6 @@ static __inline__ struct ddpehdr *ddp_hdr(struct sk_buff *skb)
return (struct ddpehdr *)skb->h.raw; 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 */ /* AppleTalk AARP headers */
struct elapaarp { struct elapaarp {
__be16 hw_type; __be16 hw_type;
......
...@@ -1002,7 +1002,7 @@ static unsigned long atalk_sum_skb(const struct sk_buff *skb, int offset, ...@@ -1002,7 +1002,7 @@ static unsigned long atalk_sum_skb(const struct sk_buff *skb, int offset,
return sum; 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; unsigned long sum;
...@@ -1010,7 +1010,7 @@ static unsigned short atalk_checksum(const struct sk_buff *skb, int len) ...@@ -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); sum = atalk_sum_skb(skb, 4, len-4, 0);
/* Use 0xFFFF for 0. 0 itself means none */ /* 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 = { static struct proto ddp_proto = {
...@@ -1289,7 +1289,7 @@ static int handle_ip_over_ddp(struct sk_buff *skb) ...@@ -1289,7 +1289,7 @@ static int handle_ip_over_ddp(struct sk_buff *skb)
#endif #endif
static void atalk_route_packet(struct sk_buff *skb, struct net_device *dev, 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) int origlen)
{ {
struct atalk_route *rt; struct atalk_route *rt;
...@@ -1317,10 +1317,12 @@ static void atalk_route_packet(struct sk_buff *skb, struct net_device *dev, ...@@ -1317,10 +1317,12 @@ static void atalk_route_packet(struct sk_buff *skb, struct net_device *dev,
/* Route the packet */ /* Route the packet */
rt = atrtr_find(&ta); 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; goto free_it;
/* FIXME: use skb->cb to be able to use shared skbs */ /* 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 * 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, ...@@ -1335,11 +1337,10 @@ static void atalk_route_packet(struct sk_buff *skb, struct net_device *dev,
/* Fix up skb->len field */ /* Fix up skb->len field */
skb_trim(skb, min_t(unsigned int, origlen, skb_trim(skb, min_t(unsigned int, origlen,
(rt->dev->hard_header_len + (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 */ /* 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 * Send the buffer onwards
...@@ -1394,7 +1395,7 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev, ...@@ -1394,7 +1395,7 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev,
struct atalk_iface *atif; struct atalk_iface *atif;
struct sockaddr_at tosat; struct sockaddr_at tosat;
int origlen; int origlen;
struct ddpebits ddphv; __u16 len_hops;
/* Don't mangle buffer if shared */ /* Don't mangle buffer if shared */
if (!(skb = skb_share_check(skb, GFP_ATOMIC))) if (!(skb = skb_share_check(skb, GFP_ATOMIC)))
...@@ -1406,16 +1407,11 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev, ...@@ -1406,16 +1407,11 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev,
ddp = ddp_hdr(skb); ddp = ddp_hdr(skb);
/* len_hops = ntohs(ddp->deh_len_hops);
* 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));
/* Trim buffer in case of stray trailing data */ /* Trim buffer in case of stray trailing data */
origlen = skb->len; 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 * 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, ...@@ -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... * valid for net byte orders all over the networking code...
*/ */
if (ddp->deh_sum && 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 */ /* Not a valid AppleTalk frame - dustbin time */
goto freeit; goto freeit;
...@@ -1444,7 +1440,7 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev, ...@@ -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 /* Not ours, so we route the packet via the correct
* AppleTalk iface * AppleTalk iface
*/ */
atalk_route_packet(skb, dev, ddp, &ddphv, origlen); atalk_route_packet(skb, dev, ddp, len_hops, origlen);
goto out; goto out;
} }
...@@ -1489,7 +1485,7 @@ static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev, ...@@ -1489,7 +1485,7 @@ static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev,
/* Find our address */ /* Find our address */
struct atalk_addr *ap = atalk_find_dev_addr(dev); 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; goto freeit;
/* Don't mangle buffer if shared */ /* Don't mangle buffer if shared */
...@@ -1519,11 +1515,8 @@ static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev, ...@@ -1519,11 +1515,8 @@ static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev,
/* /*
* Not sure about this bit... * Not sure about this bit...
*/ */
ddp->deh_len = skb->len; /* Non routable, so force a drop if we slip up later */
ddp->deh_hops = DDP_MAXHOPS; /* Non routable, so force a drop ddp->deh_len_hops = htons(skb->len + (DDP_MAXHOPS << 10));
if we slip up later */
/* Mend the byte order */
*((__u16 *)ddp) = htons(*((__u16 *)ddp));
} }
skb->h.raw = skb->data; skb->h.raw = skb->data;
...@@ -1622,16 +1615,7 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr ...@@ -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); SOCK_DEBUG(sk, "SK %p: Begin build.\n", sk);
ddp = (struct ddpehdr *)skb_put(skb, sizeof(struct ddpehdr)); ddp = (struct ddpehdr *)skb_put(skb, sizeof(struct ddpehdr));
ddp->deh_pad = 0; ddp->deh_len_hops = htons(len + sizeof(*ddp));
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_dnet = usat->sat_addr.s_net; ddp->deh_dnet = usat->sat_addr.s_net;
ddp->deh_snet = at->src_net; ddp->deh_snet = at->src_net;
ddp->deh_dnode = usat->sat_addr.s_node; ddp->deh_dnode = usat->sat_addr.s_node;
...@@ -1712,8 +1696,8 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr ...@@ -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 sockaddr_at *sat = (struct sockaddr_at *)msg->msg_name;
struct ddpehdr *ddp; struct ddpehdr *ddp;
int copied = 0; int copied = 0;
int offset = 0;
int err = 0; int err = 0;
struct ddpebits ddphv;
struct sk_buff *skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, struct sk_buff *skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
flags & MSG_DONTWAIT, &err); flags & MSG_DONTWAIT, &err);
if (!skb) if (!skb)
...@@ -1721,25 +1705,18 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr ...@@ -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 */ /* FIXME: use skb->cb to be able to use shared skbs */
ddp = ddp_hdr(skb); ddp = ddp_hdr(skb);
*((__u16 *)&ddphv) = ntohs(*((__u16 *)ddp)); copied = ntohs(ddp->deh_len_hops) & 1023;
if (sk->sk_type == SOCK_RAW) { if (sk->sk_type != SOCK_RAW) {
copied = ddphv.deh_len; offset = sizeof(*ddp);
if (copied > size) { copied -= offset;
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) { if (copied > size) {
copied = size; copied = size;
msg->msg_flags |= MSG_TRUNC; msg->msg_flags |= MSG_TRUNC;
} }
err = skb_copy_datagram_iovec(skb, sizeof(*ddp), err = skb_copy_datagram_iovec(skb, offset, msg->msg_iov, copied);
msg->msg_iov, copied);
}
if (!err) { if (!err) {
if (sat) { if (sat) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment