亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? 網卡驅動.txt

?? 帶有非常詳細注釋的網卡驅動,對于學習網卡驅動的同志來說是不可多得的好資料
?? TXT
?? 第 1 頁 / 共 3 頁
字號:
         * 如果insmod驅動的時候,指定了模擬硬件鎖的lockup=n,則在會傳輸n個數據包后,模擬一次硬件鎖住的情況,
         * 這是通過調用netif_stop_queue函數來停止傳輸隊列,標記“設備不能再傳輸數據包”實現的,它將在傳輸的超
         * 時函數中,調用netif_wake_queue函數來重新啟動傳輸隊例,同時超時函數中會再次調用“接收中斷”,這樣
         * stats.tx_packets累加,又可以重新傳輸新的數據包了(參接收中斷和超時處理函數的實現)。
         */
        if (lockup && ((priv->stats.tx_packets + 1) % lockup) == 0) {
                /* Simulate a dropped transmit interrupt */
                netif_stop_queue(dev);                        /*停止數據包的傳輸*/
                PDEBUG("Simulate lockup at %ld, txp %ld\n", jiffies,
                                (unsigned long) priv->stats.tx_packets);
        }
        else
        /*發送完成后,觸發中斷,中斷函數發現發送完成,就累加計數器,釋放skb緩存*/
                snull_interrupt(0, dev, NULL);
                
        /*
         * 看到這里,我們可以看到,這個發送函數其實并沒有把數據包通過I/O指令發送給硬件,而僅僅是做了一個地址/設備的調換,
         * 并把數據包加入到接收設備的隊例當中。
         */                
}

/*
* 數據包傳輸函數,Linux網絡堆棧,在發送數據包時,會調用驅動程序的hard_start_transmit函數,
* 在設備初始化的時候,這個函數指針指向了snull_tx。
*/
int snull_tx(struct sk_buff *skb, struct net_device *dev)
{
        int len;
        char *data, shortpkt[ETH_ZLEN];
        struct snull_priv *priv = netdev_priv(dev);
        
        data = skb->data;
        len = skb->len;
        if (len < ETH_ZLEN) {                        /*處理短幀的情況,如果小于以太幀最小長度,不足位全部補0*/
                memset(shortpkt, 0, ETH_ZLEN);
                memcpy(shortpkt, skb->data, skb->len);
                len = ETH_ZLEN;
                data = shortpkt;
        }
        dev->trans_start = jiffies; /* 保存時間戳 */

        /* 
         * 因為“發送”完成后,需要釋放skb,所以,先要保存它 ,釋放都是在網卡發送完成,產生中斷,而中斷函數收
         * 到網卡的發送完成的中斷信號后釋放
         */
        priv->skb = skb;

        /* 
         * 讓硬件把數據包發送出去,對于物理設備,就是一個讀網卡寄存器的過程,不過,這里,只是一些
         * 為了實現演示功能的虛假的欺騙函數,比如操作源/目的IP,然后調用接收函數(所以,接收時不用調用中斷)
         */
        snull_hw_tx(data, len, dev);

        return 0; /* Our simple device can not fail */
}

/*
* 傳輸超時處理函數
* 比如在傳輸數據時,由于緩沖已滿,需要關閉傳輸隊列,但是驅動程序是不能丟棄數據包,它將在“超時”的時候觸發
* 超時處理函數,這個函數將發送一個“傳輸中斷”,以填補丟失的中斷,并重新啟動傳輸隊例子
*/
void snull_tx_timeout (struct net_device *dev)
{
        struct snull_priv *priv = netdev_priv(dev);

        PDEBUG("Transmit timeout at %ld, latency %ld\n", jiffies,
                        jiffies - dev->trans_start);
        /* Simulate a transmission interrupt to get things moving */
        priv->status = SNULL_TX_INTR;
        snull_interrupt(0, dev, NULL);
        priv->stats.tx_errors++;
        netif_wake_queue(dev);
        return;
}



/*
* Ioctl 命令
*/
int snull_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
        PDEBUG("ioctl\n");
        return 0;
}

/*
* 獲取設備的狀態
*/
struct net_device_stats *snull_stats(struct net_device *dev)
{
        struct snull_priv *priv = netdev_priv(dev);
        return &priv->stats;
}

/*
* 有些網絡有硬件地址(比如Ethernet),并且在發送硬件幀時需要知道目的硬件 地址會進行ARP請求/應答,以完成MAC地址解析,
* 需要做arp請求的設備在發送之前會調用驅動程序的rebuild_header函數。需要做arp的的設備在發送之前會調用驅動程序的
* rebuild_header方 法。調用的主要參數包括指向硬件幀頭的指針,協議層地址。如果驅動程序能夠解 析硬件地址,就返回1,
* 如果不能,返回0。
* 當然,作者實現的演示設備中,不支持這個過程。 
*/
int snull_rebuild_header(struct sk_buff *skb)
{
        struct ethhdr *eth = (struct ethhdr *) skb->data;
        struct net_device *dev = skb->dev;
    
        memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
        memcpy(eth->h_dest, dev->dev_addr, dev->addr_len);
        eth->h_dest[ETH_ALEN-1]   ^= 0x01;   /* dest is us xor 1 */
        return 0;
}

/*
* 為上層協議創建一個二層的以太網首部。
* 事實上,如果一開始調用alloc_etherdev分配以太設備,它會調用ether_setup進行初始化,初始化函數會設置:
*        dev->hard_header        = eth_header;
*        dev->rebuild_header         = eth_rebuild_header;
* 驅動開發人員并不需要自己來實現這個函數,作者這樣做,只是為了展示細節。
*/

int snull_header(struct sk_buff *skb, struct net_device *dev,
                unsigned short type, void *daddr, void *saddr,
                unsigned int len)
{
        /*獲取以太頭指針*/
        struct ethhdr *eth = (struct ethhdr *)skb_push(skb,ETH_HLEN);

        eth->h_proto = htons(type);                /*填寫協議*/
        
        /*填寫來源/目的MAC地址,如果地址為空,則用設備自己的地址代替之*/
        memcpy(eth->h_source, saddr ? saddr : dev->dev_addr, dev->addr_len);
        memcpy(eth->h_dest,   daddr ? daddr : dev->dev_addr, dev->addr_len);
        
        /*
         * 將第一個octet設為0,主要是為了可以在不支持組播鏈路,如ppp鏈路上運行
         * PS:作者這樣做,僅僅是演示在PC機上的實現,事實上,直接使用ETH_ALEN-1是
         * 不適合“大頭”機器的。
         */
        eth->h_dest[ETH_ALEN-1]   ^= 0x01;   /* dest is us xor 1 */
        return (dev->hard_header_len);
}

/*
* 改變設備MTU值.
*/
int snull_change_mtu(struct net_device *dev, int new_mtu)
{
        unsigned long flags;
        struct snull_priv *priv = netdev_priv(dev);
        spinlock_t *lock = &priv->lock;
    
        /* check ranges */
        if ((new_mtu < 68) || (new_mtu > 1500))
                return -EINVAL;
        /*
         * Do anything you need, and the accept the value
         */
        spin_lock_irqsave(lock, flags);
        dev->mtu = new_mtu;
        spin_unlock_irqrestore(lock, flags);
        return 0; /* success */
}

/*
* 設備初始化函數,它必須在 register_netdev 函數被調用之前調用
*/
void snull_init(struct net_device *dev)
{
        /*設備的“私有”結構,保存一些設備一些“私有數據”*/
        struct snull_priv *priv;
#if 0
            /*
         * Make the usual checks: check_region(), probe irq, ...  -ENODEV
         * should be returned if no device found.  No resource should be
         * grabbed: this is done on open(). 
         */
#endif

            /* 
         * 初始化以太網設備的一些共用的成員
         */
        ether_setup(dev); /* assign some of the fields */

        /*設置設備的許多成員函數指針*/
        dev->open            = snull_open;
        dev->stop            = snull_release;
        dev->set_config      = snull_config;
        dev->hard_start_xmit = snull_tx;
        dev->do_ioctl        = snull_ioctl;
        dev->get_stats       = snull_stats;
        dev->change_mtu      = snull_change_mtu;  
        dev->rebuild_header  = snull_rebuild_header;
        dev->hard_header     = snull_header;
        dev->tx_timeout      = snull_tx_timeout;
        dev->watchdog_timeo = timeout;
        
        /*如果使用NAPI,設置pool函數*/
        if (use_napi) {
                dev->poll        = snull_poll;
                dev->weight      = 2;                /*weight是接口在資源緊張時,在接口上能承受多大流量的權重*/
        }
        /* keep the default flags, just add NOARP */
        dev->flags           |= IFF_NOARP;
        dev->features        |= NETIF_F_NO_CSUM;
        dev->hard_header_cache = NULL;      /* Disable caching */

        /*
         * 取得私有數據區,并初始化它.
         */
        priv = netdev_priv(dev);
        memset(priv, 0, sizeof(struct snull_priv));
        spin_lock_init(&priv->lock);
        snull_rx_ints(dev, 1);                /* 打開接收中斷標志 */
        snull_setup_pool(dev);                /*設置使用NAPI時的接收緩沖池*/
}

/*
* The devices
*/

struct net_device *snull_devs[2];



/*
* Finally, the module stuff
*/

void snull_cleanup(void)
{
        int i;
    
        for (i = 0; i < 2;  i++) {
                if (snull_devs[i]) {
                        unregister_netdev(snull_devs[i]);
                        snull_teardown_pool(snull_devs[i]);
                        free_netdev(snull_devs[i]);
                }
        }
        return;
}

/*模塊初始化,初始化的只有一個工作:分配一個設備結構并注冊它*/
int snull_init_module(void)
{
        int result, i, ret = -ENOMEM;

        /*中斷函數指針,因是否使用NAPI而指向不同的中斷函數*/
        snull_interrupt = use_napi ? snull_napi_interrupt : snull_regular_interrupt;

        /* 
         * 分配兩個設備,網絡設備都是用struct net_device來描述,alloc_netdev分配設備,第三個參數是
         * 對struct net_device結構成員進行初始化的函數,對于以太網來說,可以把alloc_netdev/snull_init
         * 兩個函數變為一個,alloc_etherdev,它會自動調用以太網的初始化函數ether_setup,因為以太網的初
         * 始化函數工作都是近乎一樣的 */
        snull_devs[0] = alloc_netdev(sizeof(struct snull_priv), "sn%d",
                        snull_init);
        snull_devs[1] = alloc_netdev(sizeof(struct snull_priv), "sn%d",
                        snull_init);
        /*分配失敗*/
        if (snull_devs[0] == NULL || snull_devs[1] == NULL)
                goto out;

        ret = -ENODEV;
        /*向內核注冊網絡設備,這樣,設備就可以被使用了*/
        for (i = 0; i < 2;  i++)
                if ((result = register_netdev(snull_devs[i])))
                        printk("snull: error %i registering device \"%s\"\n",
                                        result, snull_devs[i]->name);
                else
                        ret = 0;
   out:
        if (ret) 
                snull_cleanup();
        return ret;
}


module_init(snull_init_module);
module_exit(snull_cleanup); 

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
日本乱码高清不卡字幕| 欧美第一区第二区| 日韩一级二级三级精品视频| 久久久久久久久久久久久久久99 | 紧缚奴在线一区二区三区| 国产成人8x视频一区二区| 在线视频一区二区免费| 久久久久国产免费免费| 香蕉成人啪国产精品视频综合网| av影院午夜一区| 久久综合久色欧美综合狠狠| 亚洲福利电影网| 色综合久久久久| 国产精品丝袜久久久久久app| 久久精工是国产品牌吗| 欧美日韩国产一级| 亚洲精品欧美在线| 成人免费黄色在线| 国产日韩精品一区二区浪潮av| 免费成人av在线| 欧美欧美欧美欧美首页| 亚洲精品免费一二三区| 本田岬高潮一区二区三区| 国产日韩欧美电影| 国产一区日韩二区欧美三区| 日韩欧美中文一区| 蜜桃精品视频在线观看| 欧美日韩国产一区| 日韩精品午夜视频| 91精品国产综合久久福利软件 | 成人av午夜影院| 国产婷婷色一区二区三区四区| 青娱乐精品视频| 欧美一区二区观看视频| 亚洲成av人片在线观看| 欧美日本国产视频| 免费观看久久久4p| 精品国产乱码久久久久久免费 | 欧美成人一区二区三区在线观看| 午夜视频在线观看一区二区三区 | 制服丝袜亚洲精品中文字幕| 视频一区二区中文字幕| 日韩丝袜情趣美女图片| 激情文学综合网| 亚洲国产精品t66y| 色综合久久88色综合天天| 亚洲另类春色校园小说| 欧美日韩国产欧美日美国产精品| 五月天欧美精品| 日韩三级精品电影久久久| 久久成人18免费观看| 久久久九九九九| 99国产一区二区三精品乱码| 亚洲国产一区二区视频| 日韩精品一区在线| 成人开心网精品视频| 亚洲一区二区三区四区五区黄 | 日本不卡一区二区三区高清视频| 日韩一级片网站| 国产91精品入口| 亚洲电影一区二区| 日韩精品一区二区在线| 97久久久精品综合88久久| 亚洲国产精品久久一线不卡| 精品国产乱码久久| 91小宝寻花一区二区三区| 国产伦精品一区二区三区视频青涩 | 精品不卡在线视频| 99riav久久精品riav| 亚洲 欧美综合在线网络| xnxx国产精品| 色老汉一区二区三区| 久久国产精品72免费观看| 亚洲欧美综合另类在线卡通| 7777精品久久久大香线蕉| 成人国产精品视频| 蜜桃av一区二区三区| 中文字幕中文字幕一区| 日韩三级视频在线观看| 色一情一伦一子一伦一区| 精品一区二区三区免费观看| 亚洲激情综合网| 国产三级一区二区三区| 8x8x8国产精品| 色欧美乱欧美15图片| 国产精品伊人色| 日本强好片久久久久久aaa| 亚洲欧美中日韩| 久久午夜免费电影| 欧美一区二区三区人| 色94色欧美sute亚洲13| 成人免费看黄yyy456| 激情综合色播激情啊| 日本在线不卡视频| 一区二区三区精品| 中文字幕在线不卡视频| 国产三级一区二区| 精品国偷自产国产一区| 91精品欧美一区二区三区综合在| 91免费精品国自产拍在线不卡| 国产高清亚洲一区| 精品一区二区三区不卡| 日韩国产在线观看一区| 亚洲成人免费看| 亚洲美女区一区| 日韩一区在线播放| 国产精品每日更新| 中文字幕精品综合| 国产精品免费久久| 亚洲综合久久久久| 亚洲欧美自拍偷拍| 亚洲品质自拍视频| 亚洲欧美日韩在线| 亚洲精品久久久蜜桃| 亚洲丝袜自拍清纯另类| 亚洲欧美电影一区二区| 亚洲人成7777| 亚洲午夜影视影院在线观看| 亚洲精品国产精华液| 亚洲另类中文字| 午夜一区二区三区视频| 性感美女极品91精品| 日韩专区欧美专区| 久久er99热精品一区二区| 久久av中文字幕片| 国产精品一区2区| 国产 欧美在线| 色综合天天综合在线视频| 91九色02白丝porn| 欧美蜜桃一区二区三区| 欧美刺激脚交jootjob| xnxx国产精品| 国产精品理论片在线观看| 亚洲免费资源在线播放| 亚洲一区二区三区四区在线观看| 午夜精品久久久久影视| 青草av.久久免费一区| 国产一区视频导航| 99精品视频免费在线观看| 欧美性猛交xxxx黑人交 | 91在线观看污| 欧美日韩免费观看一区二区三区 | 亚洲免费av在线| 视频在线观看国产精品| 国产一区二区三区日韩| eeuss鲁一区二区三区| 欧美在线影院一区二区| 日韩欧美电影一区| 国产精品久久久久久久浪潮网站| 亚洲综合色成人| 国内精品视频一区二区三区八戒| www.亚洲免费av| 在线播放中文一区| 国产精品蜜臀在线观看| 日日夜夜精品视频天天综合网| 国产河南妇女毛片精品久久久| 欧美亚洲一区二区在线观看| 精品国产免费一区二区三区香蕉| 亚洲色图视频网站| 老司机精品视频在线| 91视频www| 久久久久亚洲蜜桃| 五月综合激情网| av亚洲产国偷v产偷v自拍| 欧美日韩一区二区欧美激情| 国产欧美一区二区精品性色| 五月婷婷久久综合| 色一情一乱一乱一91av| 久久久亚洲午夜电影| 偷窥少妇高潮呻吟av久久免费| av亚洲精华国产精华精华| 欧美mv日韩mv国产网站app| 亚洲在线视频网站| 成人av在线看| 精品999久久久| 国产精品1024| 欧美久久一二区| 樱桃视频在线观看一区| 成人ar影院免费观看视频| 精品国产乱码久久久久久蜜臀| 图片区小说区区亚洲影院| 日本韩国精品在线| 国产精品网曝门| 久久97超碰国产精品超碰| 欧美午夜电影网| 亚洲老妇xxxxxx| 色综合av在线| 1024成人网| 91亚洲精品乱码久久久久久蜜桃| 国产欧美日韩精品a在线观看| 久久超碰97人人做人人爱| 欧美一级夜夜爽| 免费在线观看日韩欧美| 欧美午夜精品一区二区蜜桃| 一区二区成人在线观看| 在线一区二区三区做爰视频网站| 亚洲欧洲日韩女同| 91丨porny丨国产| 日韩一区欧美小说| 欧美最猛黑人xxxxx猛交|