Messages in this thread Patch in this message | | | Date | Sun, 08 May 2005 20:42:37 +0200 | From | Johannes Stezenbach <> | Subject | [DVB patch 08/37] dvb_net: handle IPv6 and LLC/SNAP |
| |
handle IPv6 and LLC/SNAP (Bertrand Mazieres, Matthieu Castet, Johannes Stezenbach)
Signed-off-by: Johannes Stezenbach <js@linuxtv.org> ---
drivers/media/dvb/dvb-core/dvb_net.c | 35 ++++++++++++++++++++++++++--------- 1 files changed, 26 insertions(+), 9 deletions(-)
Index: linux-2.6.12-rc4/drivers/media/dvb/dvb-core/dvb_net.c =================================================================== --- linux-2.6.12-rc4.orig/drivers/media/dvb/dvb-core/dvb_net.c 2005-05-08 16:10:01.000000000 +0200 +++ linux-2.6.12-rc4/drivers/media/dvb/dvb-core/dvb_net.c 2005-05-08 16:10:07.000000000 +0200 @@ -727,6 +727,7 @@ static void dvb_net_sec(struct net_devic u8 *eth; struct sk_buff *skb; struct net_device_stats *stats = &(((struct dvb_net_priv *) dev->priv)->stats); + int snap = 0; /* note: pkt_len includes a 32bit checksum */ if (pkt_len < 16) { @@ -750,9 +751,12 @@ static void dvb_net_sec(struct net_devic return; } if (pkt[5] & 0x02) { - //FIXME: handle LLC/SNAP - stats->rx_dropped++; - return; + /* handle LLC/SNAP, see rfc-1042 */ + if (pkt_len < 24 || memcmp(&pkt[12], "\xaa\xaa\x03\0\0\0", 6)) { + stats->rx_dropped++; + return; + } + snap = 8; } if (pkt[7]) { /* FIXME: assemble datagram from multiple sections */ @@ -762,9 +766,9 @@ static void dvb_net_sec(struct net_devic } /* we have 14 byte ethernet header (ip header follows); - * 12 byte MPE header; 4 byte checksum; + 2 byte alignment + * 12 byte MPE header; 4 byte checksum; + 2 byte alignment, 8 byte LLC/SNAP */ - if (!(skb = dev_alloc_skb(pkt_len - 4 - 12 + 14 + 2))) { + if (!(skb = dev_alloc_skb(pkt_len - 4 - 12 + 14 + 2 - snap))) { //printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name); stats->rx_dropped++; return; @@ -773,8 +777,8 @@ static void dvb_net_sec(struct net_devic skb->dev = dev; /* copy L3 payload */ - eth = (u8 *) skb_put(skb, pkt_len - 12 - 4 + 14); - memcpy(eth + 14, pkt + 12, pkt_len - 12 - 4); + eth = (u8 *) skb_put(skb, pkt_len - 12 - 4 + 14 - snap); + memcpy(eth + 14, pkt + 12 + snap, pkt_len - 12 - 4 - snap); /* create ethernet header: */ eth[0]=pkt[0x0b]; @@ -786,8 +790,21 @@ static void dvb_net_sec(struct net_devic eth[6]=eth[7]=eth[8]=eth[9]=eth[10]=eth[11]=0; - eth[12] = 0x08; /* ETH_P_IP */ - eth[13] = 0x00; + if (snap) { + eth[12] = pkt[18]; + eth[13] = pkt[19]; + } else { + /* protocol numbers are from rfc-1700 or + * http://www.iana.org/assignments/ethernet-numbers + */ + if (pkt[12] >> 4 == 6) { /* version field from IP header */ + eth[12] = 0x86; /* IPv6 */ + eth[13] = 0xdd; + } else { + eth[12] = 0x08; /* IPv4 */ + eth[13] = 0x00; + } + } skb->protocol = dvb_net_eth_type_trans(skb, dev); --
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |