aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb')
-rw-r--r--drivers/media/dvb/dvb-core/dvb_net.c35
1 files changed, 26 insertions, 9 deletions
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c
index 997199cc5801..6a968c346a36 100644
--- a/drivers/media/dvb/dvb-core/dvb_net.c
+++ b/drivers/media/dvb/dvb-core/dvb_net.c
@@ -727,6 +727,7 @@ static void dvb_net_sec(struct net_device *dev, u8 *pkt, int pkt_len)
727 u8 *eth; 727 u8 *eth;
728 struct sk_buff *skb; 728 struct sk_buff *skb;
729 struct net_device_stats *stats = &(((struct dvb_net_priv *) dev->priv)->stats); 729 struct net_device_stats *stats = &(((struct dvb_net_priv *) dev->priv)->stats);
730 int snap = 0;
730 731
731 /* note: pkt_len includes a 32bit checksum */ 732 /* note: pkt_len includes a 32bit checksum */
732 if (pkt_len < 16) { 733 if (pkt_len < 16) {
@@ -750,9 +751,12 @@ static void dvb_net_sec(struct net_device *dev, u8 *pkt, int pkt_len)
750 return; 751 return;
751 } 752 }
752 if (pkt[5] & 0x02) { 753 if (pkt[5] & 0x02) {
753 //FIXME: handle LLC/SNAP 754 /* handle LLC/SNAP, see rfc-1042 */
754 stats->rx_dropped++; 755 if (pkt_len < 24 || memcmp(&pkt[12], "\xaa\xaa\x03\0\0\0", 6)) {
755 return; 756 stats->rx_dropped++;
757 return;
758 }
759 snap = 8;
756 } 760 }
757 if (pkt[7]) { 761 if (pkt[7]) {
758 /* FIXME: assemble datagram from multiple sections */ 762 /* FIXME: assemble datagram from multiple sections */
@@ -762,9 +766,9 @@ static void dvb_net_sec(struct net_device *dev, u8 *pkt, int pkt_len)
762 } 766 }
763 767
764 /* we have 14 byte ethernet header (ip header follows); 768 /* we have 14 byte ethernet header (ip header follows);
765 * 12 byte MPE header; 4 byte checksum; + 2 byte alignment 769 * 12 byte MPE header; 4 byte checksum; + 2 byte alignment, 8 byte LLC/SNAP
766 */ 770 */
767 if (!(skb = dev_alloc_skb(pkt_len - 4 - 12 + 14 + 2))) { 771 if (!(skb = dev_alloc_skb(pkt_len - 4 - 12 + 14 + 2 - snap))) {
768 //printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name); 772 //printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
769 stats->rx_dropped++; 773 stats->rx_dropped++;
770 return; 774 return;
@@ -773,8 +777,8 @@ static void dvb_net_sec(struct net_device *dev, u8 *pkt, int pkt_len)
773 skb->dev = dev; 777 skb->dev = dev;
774 778
775 /* copy L3 payload */ 779 /* copy L3 payload */
776 eth = (u8 *) skb_put(skb, pkt_len - 12 - 4 + 14); 780 eth = (u8 *) skb_put(skb, pkt_len - 12 - 4 + 14 - snap);
777 memcpy(eth + 14, pkt + 12, pkt_len - 12 - 4); 781 memcpy(eth + 14, pkt + 12 + snap, pkt_len - 12 - 4 - snap);
778 782
779 /* create ethernet header: */ 783 /* create ethernet header: */
780 eth[0]=pkt[0x0b]; 784 eth[0]=pkt[0x0b];
@@ -786,8 +790,21 @@ static void dvb_net_sec(struct net_device *dev, u8 *pkt, int pkt_len)
786 790
787 eth[6]=eth[7]=eth[8]=eth[9]=eth[10]=eth[11]=0; 791 eth[6]=eth[7]=eth[8]=eth[9]=eth[10]=eth[11]=0;
788 792
789 eth[12] = 0x08; /* ETH_P_IP */ 793 if (snap) {
790 eth[13] = 0x00; 794 eth[12] = pkt[18];
795 eth[13] = pkt[19];
796 } else {
797 /* protocol numbers are from rfc-1700 or
798 * http://www.iana.org/assignments/ethernet-numbers
799 */
800 if (pkt[12] >> 4 == 6) { /* version field from IP header */
801 eth[12] = 0x86; /* IPv6 */
802 eth[13] = 0xdd;
803 } else {
804 eth[12] = 0x08; /* IPv4 */
805 eth[13] = 0x00;
806 }
807 }
791 808
792 skb->protocol = dvb_net_eth_type_trans(skb, dev); 809 skb->protocol = dvb_net_eth_type_trans(skb, dev);
793 810