Chinaunix首页 | 论坛 | 博客
  • 博客访问: 363232
  • 博文数量: 161
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 345
  • 用 户 组: 普通用户
  • 注册时间: 2013-12-13 11:04
文章分类

全部博文(161)

文章存档

2015年(15)

2014年(144)

2013年(2)

我的朋友

分类: 网络与安全

2014-12-01 09:40:49

修改的是kernel-2.6.30.-279中的mac80211驱动
因为在中断的下半部,只有工作队列才能休眠,写文件输入io操作,很有可能休眠,所以要把原来的tasklet修改为工作队列
mac80211/rx.c

点击(此处)折叠或打开

  1. void ieee80211_rx_irqsafe(struct ieee80211_hw *hw, struct sk_buff *skb)
  2. {
  3.     struct ieee80211_local *local = hw_to_local(hw);

  4.     BUILD_BUG_ON(sizeof(struct ieee80211_rx_status) > sizeof(skb->cb));

  5.     skb->pkt_type = IEEE80211_RX_MSG;
  6.     skb_queue_tail(&local->skb_queue, skb);
  7.    //tasklet_schedule(&local->tasklet);//原来是tasklet
  8.     schedule_work(&local->my_work);//现在使用工作队列
  9. }

工作队列的处理函数
mac80211/main.c

点击(此处)折叠或打开

  1. char mac[6] = { 0xc0, 0xf2, 0xfb, 0x95, 0xb0, 0x50 };
  2. struct pcap_hdr {
  3.     char Magic[4];
  4.     char Major[2];
  5.     char Minor[2];
  6.     char ThisZone[4];
  7.     char SigFigs[4];
  8.     char SnapLen[4];
  9.     char LinkType[4];
  10. };
  11. struct packet_hdr {
  12.     int Time1;
  13.     int Time2;
  14.     int Caplen;
  15.     int Len;
  16. };
  17. char radiotap[8];
  18. struct pcap_hdr phdr = { .Magic = { 0xd4, 0xc3, 0xb2, 0xa1 }, .Major = { 0x02,
  19.         0x00 }, .Minor = { 0 }, .ThisZone = { 0 }, .SigFigs = { 0 }, .SnapLen =
  20.         { 0xff, 0xff, 0x0, 0x0 }, .LinkType = { 0x7f, 0x0, 0x0, 0x0 }, };

  21. static void ieee80211_my_work_handler(struct work_struct *work) {
  22.     struct ieee80211_local *local =container_of(work,struct ieee80211_local,my_work);
  23.     struct sta_info *sta, *tmp;
  24.     struct skb_eosp_msg_data *eosp_data;
  25.     struct sk_buff *skb;

  26.     while ((skb = skb_dequeue(&local->skb_queue)) || (skb = skb_dequeue(
  27.             &local->skb_queue_unreliable))) {

  28.         {
  29.             struct ieee80211_hdr *hdr;
  30.             //struct my_struct_t *my_name=container_of(work,struct my_struct_t,my_work);
  31.             hdr = (struct ieee80211_hdr *) (skb->data);
  32.             if (file == NULL) {
  33.                 file = filp_open("/root/test.pcap",
  34.                         O_RDWR | O_APPEND | O_CREAT, 0644);
  35.                 old_fs = get_fs();
  36.                 set_fs(KERNEL_DS);
  37.                 pos = 0;
  38.                 vfs_write(file, (char*) &phdr, sizeof(struct pcap_hdr), &pos);
  39.                 set_fs(old_fs);
  40.             }
  41.             if (IS_ERR(file)) {
  42.                 printk("error occured while opening file%s.\n",
  43.                         "/root/test.pcap");
  44.             }

  45.             old_fs = get_fs();
  46.             set_fs(KERNEL_DS);
  47.             pos = 0;
  48.             struct packet_hdr pkt_hdr;

  49.             memset(&pkt_hdr, 0, sizeof(pkt_hdr));
  50.             pkt_hdr.Time1 = 0;
  51.             pkt_hdr.Time2 = 0;
  52.             pkt_hdr.Caplen = skb->len + 8;
  53.             pkt_hdr.Len = skb->len + 8;
  54.             printk("time1:%d\n", 0);
  55.             printk("time1:%d\n", 0);
  56.             printk("caplen:%d\n", pkt_hdr.Caplen);
  57.             printk("len:%d\n", pkt_hdr.Len);
  58.             printk("skb->pkt_type:%d\n", skb->pkt_type);
  59.             printk("skb->tstamp:%ld\n", skb->tstamp);

  60.             memset(radiotap, 0, sizeof(radiotap));
  61.             radiotap[2] = 0x08;
  62.             //vfs_write(file, (char*) &buf, strlen(buf), &pos);
  63.             //file->f_op->write(file,(char*)&buf,strlen(buf),&pos);
  64.             vfs_write(file, (char*) &pkt_hdr, sizeof(struct packet_hdr), &pos);
  65.             pos = 0;
  66.             vfs_write(file, (char*) &radiotap, 8, &pos);
  67.             pos = 0;
  68.             printk(KERN_ERR "addr1:%02x:%02x:%02x:%02x:%02x:%02x\t",hdr->addr1[0],hdr->addr1[1],hdr->addr1[2],hdr->addr1[3],hdr->addr1[4],hdr->addr1[5]);
  69.             printk(KERN_ERR "addr2:%02x:%02x:%02x:%02x:%02x:%02x\t",hdr->addr2[0],hdr->addr2[1],hdr->addr2[2],hdr->addr2[3],hdr->addr2[4],hdr->addr2[5]);
  70.             printk(KERN_ERR "addr3:%02x:%02x:%02x:%02x:%02x:%02x\n",hdr->addr3[0],hdr->addr3[1],hdr->addr3[2],hdr->addr3[3],hdr->addr3[4],hdr->addr3[5]);
  71.             vfs_write(file, (char*) hdr, skb->len, &pos);
  72.             set_fs(old_fs);
  73.             /*
  74.              if (file != NULL) {
  75.              filp_close(file, NULL);
  76.              file = NULL;
  77.              }
  78.              */
  79.         }

  80.         switch (skb->pkt_type) {
  81.         case IEEE80211_RX_MSG:
  82.             /* Clear skb->pkt_type in order to not confuse kernel
  83.              * netstack. */
  84.             skb->pkt_type = 0;
  85.             //ieee80211_rx(local_to_hw(local), skb);
  86.             break;
  87.         case IEEE80211_TX_STATUS_MSG:
  88.             skb->pkt_type = 0;
  89.             ieee80211_tx_status(local_to_hw(local), skb);
  90.             break;
  91.         case IEEE80211_EOSP_MSG:
  92.             eosp_data = (void *) skb->cb;
  93.             for_each_sta_info(local, eosp_data->sta, sta, tmp)
  94.                 {
  95.                     /* skip wrong virtual interface */
  96.                     if (memcmp(eosp_data->iface, sta->sdata->vif.addr, ETH_ALEN))
  97.                         continue;
  98.                     clear_sta_flag(sta, WLAN_STA_SP);
  99.                     break;
  100.                 }
  101.             dev_kfree_skb(skb);
  102.             break;
  103.         default:
  104.             WARN(1, "mac80211: Packet is of unknown type %d\n", skb->pkt_type);
  105.             dev_kfree_skb(skb);
  106.             break;
  107.         }
  108.     }
  109. }

点击(此处)折叠或打开

  1. struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
  2.         const struct ieee80211_ops *ops) {

  3.     struct ieee80211_local *local;
  4.     int priv_size, i;
  5.     struct wiphy *wiphy;

  6.     /* Ensure 32-byte alignment of our private data and hw private data.
  7.      * We use the wiphy priv data for both our ieee80211_local and for
  8.      * the driver's private data
  9.      *
  10.      * In memory it'll be like this:
  11.      *
  12.      * +-------------------------+
  13.      * | struct wiphy     |
  14.      * +-------------------------+
  15.      * | struct ieee80211_local |
  16.      * +-------------------------+
  17.      * | driver's private data |
  18.      * +-------------------------+
  19.      *
  20.      */

  21.     priv_size = ALIGN(sizeof(*local), NETDEV_ALIGN) + priv_data_len;

  22.     wiphy = wiphy_new(&mac80211_config_ops, priv_size);

  23.     if (!wiphy)
  24.         return NULL;

  25.     wiphy->mgmt_stypes = ieee80211_default_mgmt_stypes;

  26.     wiphy->privid = mac80211_wiphy_privid;

  27.     wiphy->flags |= WIPHY_FLAG_NETNS_OK | WIPHY_FLAG_4ADDR_AP
  28.             | WIPHY_FLAG_4ADDR_STATION;

  29.     if (!ops->set_key)
  30.         wiphy->flags |= WIPHY_FLAG_IBSS_RSN;

  31.     wiphy->bss_priv_size = sizeof(struct ieee80211_bss);

  32.     local = wiphy_priv(wiphy);

  33.     local->hw.wiphy = wiphy;

  34.     local->hw.priv = (char *) local + ALIGN(sizeof(*local), NETDEV_ALIGN);

  35.     BUG_ON(!ops->tx);
  36.     BUG_ON(!ops->start);
  37.     BUG_ON(!ops->stop);
  38.     BUG_ON(!ops->config);
  39.     BUG_ON(!ops->add_interface);
  40.     BUG_ON(!ops->remove_interface);
  41.     BUG_ON(!ops->configure_filter);
  42.     local->ops = ops;

  43.     /* set up some defaults */
  44.     local->hw.queues = 1;
  45.     local->hw.max_rates = 1;
  46.     local->hw.max_report_rates = 0;
  47.     local->hw.max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF;
  48.     local->hw.max_tx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF;
  49.     local->hw.conf.long_frame_max_tx_count = wiphy->retry_long;
  50.     local->hw.conf.short_frame_max_tx_count = wiphy->retry_short;
  51.     local->user_power_level = -1;
  52.     local->uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES;
  53.     local->uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN;

  54.     INIT_LIST_HEAD(&local->interfaces);
  55.     mutex_init(&local->iflist_mtx);
  56.     mutex_init(&local->mtx);

  57.     mutex_init(&local->key_mtx);
  58.     spin_lock_init(&local->filter_lock);
  59.     spin_lock_init(&local->queue_stop_reason_lock);

  60.     /*
  61.      * The rx_skb_queue is only accessed from tasklets,
  62.      * but other SKB queues are used from within IRQ
  63.      * context. Therefore, this one needs a different
  64.      * locking class so our direct, non-irq-safe use of
  65.      * the queue's lock doesn't throw lockdep warnings.
  66.      */
  67.     skb_queue_head_init_class(&local->rx_skb_queue,
  68.             &ieee80211_rx_skb_queue_class);

  69.     INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work);

  70.     ieee80211_work_init(local);

  71.     INIT_WORK(&local->restart_work, ieee80211_restart_work);

  72.     INIT_WORK(&local->reconfig_filter, ieee80211_reconfig_filter);
  73.     INIT_WORK(&local->recalc_smps, ieee80211_recalc_smps_work);
  74.     local->smps_mode = IEEE80211_SMPS_OFF;

  75.     INIT_WORK(&local->dynamic_ps_enable_work, ieee80211_dynamic_ps_enable_work);
  76.     INIT_WORK(&local->dynamic_ps_disable_work,
  77.             ieee80211_dynamic_ps_disable_work);
  78.     setup_timer(&local->dynamic_ps_timer, ieee80211_dynamic_ps_timer,
  79.             (unsigned long) local);

  80.     INIT_WORK(&local->sched_scan_stopped_work,
  81.             ieee80211_sched_scan_stopped_work);

  82.     sta_info_init(local);

  83.     for (i = 0; i < IEEE80211_MAX_QUEUES; i++) {
  84.         skb_queue_head_init(&local->pending[i]);
  85.         atomic_set(&local->agg_queue_stop[i], 0);
  86.     }
  87.     tasklet_init(&local->tx_pending_tasklet, ieee80211_tx_pending,
  88.             (unsigned long) local);

  89.     tasklet_init(&local->tasklet, ieee80211_tasklet_handler,
  90.             (unsigned long) local);
  91.     INIT_WORK(&local->my_work, ieee80211_my_work_handler);//初始化工作队列

  92.     skb_queue_head_init(&local->skb_queue);
  93.     skb_queue_head_init(&local->skb_queue_unreliable);

  94.     /* init dummy netdev for use w/ NAPI */
  95.     init_dummy_netdev(&local->napi_dev);

  96.     ieee80211_led_names(local);

  97.     ieee80211_hw_roc_setup(local);

  98.     return local_to_hw(local);
  99. }

重新加载一下驱动就可以
rmmod rtl8187
rmmod mac80211
insmod mac80211.ko
insmod /root/linux_module/rtl8187/rtl8187.ko


阅读(1318) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~