diff options
| -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 7f7dd450226a..b98592a8bac8 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) | |||
| 145 | 145 | ||
| 146 | /* Create the Extended DDP header */ | 146 | /* Create the Extended DDP header */ |
| 147 | ddp = (struct ddpehdr *)skb->data; | 147 | ddp = (struct ddpehdr *)skb->data; |
| 148 | ddp->deh_len = skb->len; | 148 | ddp->deh_len_hops = htons(skb->len + (1<<10)); |
| 149 | ddp->deh_hops = 1; | ||
| 150 | ddp->deh_pad = 0; | ||
| 151 | ddp->deh_sum = 0; | 149 | ddp->deh_sum = 0; |
| 152 | 150 | ||
| 153 | /* | 151 | /* |
| @@ -170,7 +168,6 @@ static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 170 | ddp->deh_sport = 72; | 168 | ddp->deh_sport = 72; |
| 171 | 169 | ||
| 172 | *((__u8 *)(ddp+1)) = 22; /* ddp type = IP */ | 170 | *((__u8 *)(ddp+1)) = 22; /* ddp type = IP */ |
| 173 | *((__u16 *)ddp)=ntohs(*((__u16 *)ddp)); /* fix up length field */ | ||
| 174 | 171 | ||
| 175 | skb->protocol = htons(ETH_P_ATALK); /* Protocol has changed */ | 172 | skb->protocol = htons(ETH_P_ATALK); /* Protocol has changed */ |
| 176 | 173 | ||
diff --git a/include/linux/atalk.h b/include/linux/atalk.h index 6ba3aa8a81f4..75b8baca08f3 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) | |||
| 88 | #include <asm/byteorder.h> | 88 | #include <asm/byteorder.h> |
| 89 | 89 | ||
| 90 | struct ddpehdr { | 90 | struct ddpehdr { |
| 91 | #ifdef __LITTLE_ENDIAN_BITFIELD | 91 | __be16 deh_len_hops; /* lower 10 bits are length, next 4 - hops */ |
| 92 | __u16 deh_len:10, | ||
| 93 | deh_hops:4, | ||
| 94 | deh_pad:2; | ||
| 95 | #else | ||
| 96 | __u16 deh_pad:2, | ||
| 97 | deh_hops:4, | ||
| 98 | deh_len:10; | ||
| 99 | #endif | ||
| 100 | __be16 deh_sum; | 92 | __be16 deh_sum; |
| 101 | __be16 deh_dnet; | 93 | __be16 deh_dnet; |
| 102 | __be16 deh_snet; | 94 | __be16 deh_snet; |
| @@ -112,36 +104,6 @@ static __inline__ struct ddpehdr *ddp_hdr(struct sk_buff *skb) | |||
| 112 | return (struct ddpehdr *)skb->h.raw; | 104 | return (struct ddpehdr *)skb->h.raw; |
| 113 | } | 105 | } |
| 114 | 106 | ||
| 115 | /* | ||
| 116 | * Don't drop the struct into the struct above. You'll get some | ||
| 117 | * surprise padding. | ||
| 118 | */ | ||
| 119 | struct ddpebits { | ||
| 120 | #ifdef __LITTLE_ENDIAN_BITFIELD | ||
| 121 | __u16 deh_len:10, | ||
| 122 | deh_hops:4, | ||
| 123 | deh_pad:2; | ||
| 124 | #else | ||
| 125 | __u16 deh_pad:2, | ||
| 126 | deh_hops:4, | ||
| 127 | deh_len:10; | ||
| 128 | #endif | ||
| 129 | }; | ||
| 130 | |||
| 131 | /* Short form header */ | ||
| 132 | struct ddpshdr { | ||
| 133 | #ifdef __LITTLE_ENDIAN_BITFIELD | ||
| 134 | __u16 dsh_len:10, | ||
| 135 | dsh_pad:6; | ||
| 136 | #else | ||
| 137 | __u16 dsh_pad:6, | ||
| 138 | dsh_len:10; | ||
| 139 | #endif | ||
| 140 | __u8 dsh_dport; | ||
| 141 | __u8 dsh_sport; | ||
| 142 | /* And netatalk apps expect to stick the type in themselves */ | ||
| 143 | }; | ||
| 144 | |||
| 145 | /* AppleTalk AARP headers */ | 107 | /* AppleTalk AARP headers */ |
| 146 | struct elapaarp { | 108 | struct elapaarp { |
| 147 | __be16 hw_type; | 109 | __be16 hw_type; |
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index 96dc6bb52d14..708e2e0371af 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, | |||
| 1002 | return sum; | 1002 | return sum; |
| 1003 | } | 1003 | } |
| 1004 | 1004 | ||
| 1005 | static unsigned short atalk_checksum(const struct sk_buff *skb, int len) | 1005 | static __be16 atalk_checksum(const struct sk_buff *skb, int len) |
| 1006 | { | 1006 | { |
| 1007 | unsigned long sum; | 1007 | unsigned long sum; |
| 1008 | 1008 | ||
| @@ -1010,7 +1010,7 @@ static unsigned short atalk_checksum(const struct sk_buff *skb, int len) | |||
| 1010 | sum = atalk_sum_skb(skb, 4, len-4, 0); | 1010 | sum = atalk_sum_skb(skb, 4, len-4, 0); |
| 1011 | 1011 | ||
| 1012 | /* Use 0xFFFF for 0. 0 itself means none */ | 1012 | /* Use 0xFFFF for 0. 0 itself means none */ |
| 1013 | return sum ? htons((unsigned short)sum) : 0xFFFF; | 1013 | return sum ? htons((unsigned short)sum) : htons(0xFFFF); |
| 1014 | } | 1014 | } |
| 1015 | 1015 | ||
| 1016 | static struct proto ddp_proto = { | 1016 | static struct proto ddp_proto = { |
| @@ -1289,7 +1289,7 @@ static int handle_ip_over_ddp(struct sk_buff *skb) | |||
| 1289 | #endif | 1289 | #endif |
| 1290 | 1290 | ||
| 1291 | static void atalk_route_packet(struct sk_buff *skb, struct net_device *dev, | 1291 | static void atalk_route_packet(struct sk_buff *skb, struct net_device *dev, |
| 1292 | struct ddpehdr *ddp, struct ddpebits *ddphv, | 1292 | struct ddpehdr *ddp, __u16 len_hops, |
| 1293 | int origlen) | 1293 | int origlen) |
| 1294 | { | 1294 | { |
| 1295 | struct atalk_route *rt; | 1295 | struct atalk_route *rt; |
| @@ -1317,10 +1317,12 @@ static void atalk_route_packet(struct sk_buff *skb, struct net_device *dev, | |||
| 1317 | 1317 | ||
| 1318 | /* Route the packet */ | 1318 | /* Route the packet */ |
| 1319 | rt = atrtr_find(&ta); | 1319 | rt = atrtr_find(&ta); |
| 1320 | if (!rt || ddphv->deh_hops == DDP_MAXHOPS) | 1320 | /* increment hops count */ |
| 1321 | len_hops += 1 << 10; | ||
| 1322 | if (!rt || !(len_hops & (15 << 10))) | ||
| 1321 | goto free_it; | 1323 | goto free_it; |
| 1324 | |||
| 1322 | /* FIXME: use skb->cb to be able to use shared skbs */ | 1325 | /* FIXME: use skb->cb to be able to use shared skbs */ |
| 1323 | ddphv->deh_hops++; | ||
| 1324 | 1326 | ||
| 1325 | /* | 1327 | /* |
| 1326 | * Route goes through another gateway, so set the target to the | 1328 | * 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 | /* Fix up skb->len field */ | 1337 | /* Fix up skb->len field */ |
| 1336 | skb_trim(skb, min_t(unsigned int, origlen, | 1338 | skb_trim(skb, min_t(unsigned int, origlen, |
| 1337 | (rt->dev->hard_header_len + | 1339 | (rt->dev->hard_header_len + |
| 1338 | ddp_dl->header_length + ddphv->deh_len))); | 1340 | ddp_dl->header_length + (len_hops & 1023)))); |
| 1339 | 1341 | ||
| 1340 | /* Mend the byte order */ | ||
| 1341 | /* FIXME: use skb->cb to be able to use shared skbs */ | 1342 | /* FIXME: use skb->cb to be able to use shared skbs */ |
| 1342 | *((__u16 *)ddp) = ntohs(*((__u16 *)ddphv)); | 1343 | ddp->deh_len_hops = htons(len_hops); |
| 1343 | 1344 | ||
| 1344 | /* | 1345 | /* |
| 1345 | * Send the buffer onwards | 1346 | * Send the buffer onwards |
| @@ -1394,7 +1395,7 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev, | |||
| 1394 | struct atalk_iface *atif; | 1395 | struct atalk_iface *atif; |
| 1395 | struct sockaddr_at tosat; | 1396 | struct sockaddr_at tosat; |
| 1396 | int origlen; | 1397 | int origlen; |
| 1397 | struct ddpebits ddphv; | 1398 | __u16 len_hops; |
| 1398 | 1399 | ||
| 1399 | /* Don't mangle buffer if shared */ | 1400 | /* Don't mangle buffer if shared */ |
| 1400 | if (!(skb = skb_share_check(skb, GFP_ATOMIC))) | 1401 | 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 | 1407 | ||
| 1407 | ddp = ddp_hdr(skb); | 1408 | ddp = ddp_hdr(skb); |
| 1408 | 1409 | ||
| 1409 | /* | 1410 | len_hops = ntohs(ddp->deh_len_hops); |
| 1410 | * Fix up the length field [Ok this is horrible but otherwise | ||
| 1411 | * I end up with unions of bit fields and messy bit field order | ||
| 1412 | * compiler/endian dependencies..] | ||
| 1413 | */ | ||
| 1414 | *((__u16 *)&ddphv) = ntohs(*((__u16 *)ddp)); | ||
| 1415 | 1411 | ||
| 1416 | /* Trim buffer in case of stray trailing data */ | 1412 | /* Trim buffer in case of stray trailing data */ |
| 1417 | origlen = skb->len; | 1413 | origlen = skb->len; |
| 1418 | skb_trim(skb, min_t(unsigned int, skb->len, ddphv.deh_len)); | 1414 | skb_trim(skb, min_t(unsigned int, skb->len, len_hops & 1023)); |
| 1419 | 1415 | ||
| 1420 | /* | 1416 | /* |
| 1421 | * Size check to see if ddp->deh_len was crap | 1417 | * 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 | * valid for net byte orders all over the networking code... | 1426 | * valid for net byte orders all over the networking code... |
| 1431 | */ | 1427 | */ |
| 1432 | if (ddp->deh_sum && | 1428 | if (ddp->deh_sum && |
| 1433 | atalk_checksum(skb, ddphv.deh_len) != ddp->deh_sum) | 1429 | atalk_checksum(skb, len_hops & 1023) != ddp->deh_sum) |
| 1434 | /* Not a valid AppleTalk frame - dustbin time */ | 1430 | /* Not a valid AppleTalk frame - dustbin time */ |
| 1435 | goto freeit; | 1431 | goto freeit; |
| 1436 | 1432 | ||
| @@ -1444,7 +1440,7 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev, | |||
| 1444 | /* Not ours, so we route the packet via the correct | 1440 | /* Not ours, so we route the packet via the correct |
| 1445 | * AppleTalk iface | 1441 | * AppleTalk iface |
| 1446 | */ | 1442 | */ |
| 1447 | atalk_route_packet(skb, dev, ddp, &ddphv, origlen); | 1443 | atalk_route_packet(skb, dev, ddp, len_hops, origlen); |
| 1448 | goto out; | 1444 | goto out; |
| 1449 | } | 1445 | } |
| 1450 | 1446 | ||
| @@ -1489,7 +1485,7 @@ static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev, | |||
| 1489 | /* Find our address */ | 1485 | /* Find our address */ |
| 1490 | struct atalk_addr *ap = atalk_find_dev_addr(dev); | 1486 | struct atalk_addr *ap = atalk_find_dev_addr(dev); |
| 1491 | 1487 | ||
| 1492 | if (!ap || skb->len < sizeof(struct ddpshdr)) | 1488 | if (!ap || skb->len < sizeof(__be16) || skb->len > 1023) |
| 1493 | goto freeit; | 1489 | goto freeit; |
| 1494 | 1490 | ||
| 1495 | /* Don't mangle buffer if shared */ | 1491 | /* Don't mangle buffer if shared */ |
| @@ -1519,11 +1515,8 @@ static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev, | |||
| 1519 | /* | 1515 | /* |
| 1520 | * Not sure about this bit... | 1516 | * Not sure about this bit... |
| 1521 | */ | 1517 | */ |
| 1522 | ddp->deh_len = skb->len; | 1518 | /* Non routable, so force a drop if we slip up later */ |
| 1523 | ddp->deh_hops = DDP_MAXHOPS; /* Non routable, so force a drop | 1519 | ddp->deh_len_hops = htons(skb->len + (DDP_MAXHOPS << 10)); |
| 1524 | if we slip up later */ | ||
| 1525 | /* Mend the byte order */ | ||
| 1526 | *((__u16 *)ddp) = htons(*((__u16 *)ddp)); | ||
| 1527 | } | 1520 | } |
| 1528 | skb->h.raw = skb->data; | 1521 | skb->h.raw = skb->data; |
| 1529 | 1522 | ||
| @@ -1622,16 +1615,7 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr | |||
| 1622 | SOCK_DEBUG(sk, "SK %p: Begin build.\n", sk); | 1615 | SOCK_DEBUG(sk, "SK %p: Begin build.\n", sk); |
| 1623 | 1616 | ||
| 1624 | ddp = (struct ddpehdr *)skb_put(skb, sizeof(struct ddpehdr)); | 1617 | ddp = (struct ddpehdr *)skb_put(skb, sizeof(struct ddpehdr)); |
| 1625 | ddp->deh_pad = 0; | 1618 | ddp->deh_len_hops = htons(len + sizeof(*ddp)); |
| 1626 | ddp->deh_hops = 0; | ||
| 1627 | ddp->deh_len = len + sizeof(*ddp); | ||
| 1628 | /* | ||
| 1629 | * Fix up the length field [Ok this is horrible but otherwise | ||
| 1630 | * I end up with unions of bit fields and messy bit field order | ||
| 1631 | * compiler/endian dependencies.. | ||
| 1632 | */ | ||
| 1633 | *((__u16 *)ddp) = ntohs(*((__u16 *)ddp)); | ||
| 1634 | |||
| 1635 | ddp->deh_dnet = usat->sat_addr.s_net; | 1619 | ddp->deh_dnet = usat->sat_addr.s_net; |
| 1636 | ddp->deh_snet = at->src_net; | 1620 | ddp->deh_snet = at->src_net; |
| 1637 | ddp->deh_dnode = usat->sat_addr.s_node; | 1621 | 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 | struct sockaddr_at *sat = (struct sockaddr_at *)msg->msg_name; | 1696 | struct sockaddr_at *sat = (struct sockaddr_at *)msg->msg_name; |
| 1713 | struct ddpehdr *ddp; | 1697 | struct ddpehdr *ddp; |
| 1714 | int copied = 0; | 1698 | int copied = 0; |
| 1699 | int offset = 0; | ||
| 1715 | int err = 0; | 1700 | int err = 0; |
| 1716 | struct ddpebits ddphv; | ||
| 1717 | struct sk_buff *skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, | 1701 | struct sk_buff *skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, |
| 1718 | flags & MSG_DONTWAIT, &err); | 1702 | flags & MSG_DONTWAIT, &err); |
| 1719 | if (!skb) | 1703 | if (!skb) |
| @@ -1721,25 +1705,18 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr | |||
| 1721 | 1705 | ||
| 1722 | /* FIXME: use skb->cb to be able to use shared skbs */ | 1706 | /* FIXME: use skb->cb to be able to use shared skbs */ |
| 1723 | ddp = ddp_hdr(skb); | 1707 | ddp = ddp_hdr(skb); |
| 1724 | *((__u16 *)&ddphv) = ntohs(*((__u16 *)ddp)); | 1708 | copied = ntohs(ddp->deh_len_hops) & 1023; |
| 1725 | 1709 | ||
| 1726 | if (sk->sk_type == SOCK_RAW) { | 1710 | if (sk->sk_type != SOCK_RAW) { |
| 1727 | copied = ddphv.deh_len; | 1711 | offset = sizeof(*ddp); |
| 1728 | if (copied > size) { | 1712 | copied -= offset; |
| 1729 | copied = size; | 1713 | } |
| 1730 | msg->msg_flags |= MSG_TRUNC; | ||
| 1731 | } | ||
| 1732 | 1714 | ||
| 1733 | err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); | 1715 | if (copied > size) { |
| 1734 | } else { | 1716 | copied = size; |
| 1735 | copied = ddphv.deh_len - sizeof(*ddp); | 1717 | msg->msg_flags |= MSG_TRUNC; |
| 1736 | if (copied > size) { | ||
| 1737 | copied = size; | ||
| 1738 | msg->msg_flags |= MSG_TRUNC; | ||
| 1739 | } | ||
| 1740 | err = skb_copy_datagram_iovec(skb, sizeof(*ddp), | ||
| 1741 | msg->msg_iov, copied); | ||
| 1742 | } | 1718 | } |
| 1719 | err = skb_copy_datagram_iovec(skb, offset, msg->msg_iov, copied); | ||
| 1743 | 1720 | ||
| 1744 | if (!err) { | 1721 | if (!err) { |
| 1745 | if (sat) { | 1722 | if (sat) { |
