1diff -ur ipw2200-1.1.4/ipw2200.c ipw2200-1.1.4-inject/ipw2200.c 2--- ipw2200-1.1.4/ipw2200.c 2006-08-21 04:38:32.000000000 +0200 3+++ ipw2200-1.1.4-inject/ipw2200.c 2006-08-23 14:20:31.000000000 +0200 4@@ -30,6 +30,8 @@ 5 6 ******************************************************************************/ 7 8+#include <linux/version.h> 9+ 10 #include "ipw2200.h" 11 12 13@@ -1945,6 +1945,66 @@ 14 static DEVICE_ATTR(net_stats, S_IWUSR | S_IRUGO, 15 show_net_stats, store_net_stats); 16 17+static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb, int pri); 18+ 19+/* SYSFS INJECT */ 20+static ssize_t store_inject(struct device *d, 21+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12) 22+ struct device_attribute *attr, 23+#endif 24+ const char *buf, size_t count) 25+{ 26+ struct ipw_priv *priv = (struct ipw_priv *)d->driver_data; 27+ struct ieee80211_device *ieee = priv->ieee; 28+ struct ieee80211_txb * txb; 29+ struct sk_buff *skb_frag; 30+ unsigned char * newbuf; 31+ unsigned long flags; 32+ 33+ // should test (ieee->is_queue_full) 34+ 35+ // Fw only accepts data, so avoid accidental fw errors. 36+ if ( (buf[0]&0x0c) != '\x08') { 37+ //printk("ipw2200: inject: discarding non-data frame (type=%02X)\n",(int)(unsigned char)buf[0]); 38+ return count; 39+ } 40+ 41+ if (count>1500) { 42+ count=1500; 43+ printk("ipw2200: inject: cutting down frame to 1500 bytes\n"); 44+ } 45+ 46+ spin_lock_irqsave(&priv->lock, flags); 47+ 48+ // Create a txb with one skb 49+ txb = kmalloc(sizeof(struct ieee80211_txb) + sizeof(u8 *), GFP_ATOMIC); 50+ if (!txb) 51+ goto nosepuede; 52+ txb->nr_frags=1; 53+ txb->frag_size = ieee->tx_headroom; 54+ txb->fragments[0]=__dev_alloc_skb(count + ieee->tx_headroom, GFP_ATOMIC); 55+ if (!txb->fragments[0]) { 56+ kfree(txb); 57+ goto nosepuede; 58+ } 59+ skb_reserve(txb->fragments[0], ieee->tx_headroom); 60+ txb->encrypted=0; 61+ txb->payload_size=count; 62+ skb_frag = txb->fragments[0]; 63+ newbuf=skb_put(skb_frag, count); 64+ 65+ // copy data into txb->skb and send it 66+ memcpy(newbuf, buf, count); 67+ 68+ ipw_tx_skb(priv, txb, 0); 69+ 70+nosepuede: 71+ spin_unlock_irqrestore(&priv->lock, flags); 72+ return count; 73+} 74+ 75+static DEVICE_ATTR(inject, S_IWUSR, NULL, store_inject); 76+ 77 static void notify_wx_assoc_event(struct ipw_priv *priv) 78 { 79 union iwreq_data wrqu; 80@@ -11478,6 +11538,7 @@ 81 #ifdef CONFIG_IPW2200_PROMISCUOUS 82 &dev_attr_rtap_iface.attr, 83 &dev_attr_rtap_filter.attr, 84+ &dev_attr_inject.attr, 85 #endif 86 NULL 87 }; 88diff -ur ipw2200-1.1.4/Makefile ipw2200-1.1.4-inject/Makefile 89--- ipw2200-1.1.4/Makefile 2006-08-21 04:38:29.000000000 +0200 90+++ ipw2200-1.1.4-inject/Makefile 2006-08-23 14:22:06.000000000 +0200 91@@ -30,14 +30,14 @@ 92 # simply uncomment: 93 # 94 # NOTE: To use RADIOTAP you must also enable MONITOR above. 95-#CONFIG_IPW2200_RADIOTAP=y 96+CONFIG_IPW2200_RADIOTAP=y 97 98 # The above monitor mode provides standard monitor mode. The following 99 # will create a new interface (named rtap%d) which will be sent all 100 # 802.11 frames received on the interface 101 # 102 # NOTE: To use PROMISCUOUS you must also enable MONITOR above. 103-#CONFIG_IPW2200_PROMISCUOUS=y 104+CONFIG_IPW2200_PROMISCUOUS=y 105 106 endif 107 108