历史上的今天
返回首页

历史上的今天

今天是:2024年10月12日(星期六)

正在发生

2018年10月12日 | Tiny210驱动之虚拟网卡驱动

2018-10-12 来源:eefocus

virt_net.c驱动:

// 参考 drivers\net\cs89x0.c

 

#include "linux/module.h"

#include "linux/errno.h"

#include "linux/netdevice.h"

#include "linux/etherdevice.h"

#include "linux/kernel.h"

#include "linux/types.h"

#include "linux/fcntl.h"

#include "linux/interrupt.h"

#include "linux/ioport.h"

#include "linux/in.h"

#include "linux/skbuff.h"

#include "linux/slab.h"

#include "linux/spinlock.h"

#include "linux/string.h"

#include "linux/init.h"

#include "linux/bitops.h"

#include "linux/delay.h"

#include "linux/ip.h"

#include "asm/system.h"

#include "asm/io.h"

#include "asm/irq.h"

static struct net_device *vnet_dev;

static void emulator_rx_packet(struct sk_buff *skb, struct net_device *dev)

{

    // 参考LDD3 

    unsigned char *type;

    struct iphdr *ih;

    __be32 *saddr, *daddr, tmp;

    unsigned char    tmp_dev_addr[ETH_ALEN];

    struct ethhdr *ethhdr;

    

    struct sk_buff *rx_skb;

        

    // 从硬件读出/保存数据

    // 对调"源/目的"的mac地址 

    ethhdr = (struct ethhdr *)skb->data;

    memcpy(tmp_dev_addr, ethhdr->h_dest, ETH_ALEN);

    memcpy(ethhdr->h_dest, ethhdr->h_source, ETH_ALEN);

    memcpy(ethhdr->h_source, tmp_dev_addr, ETH_ALEN);

    // 对调"源/目的"的ip地址     

    ih = (struct iphdr *)(skb->data + sizeof(struct ethhdr));

    saddr = &ih->saddr;

    daddr = &ih->daddr;

    tmp = *saddr;

    *saddr = *daddr;

    *daddr = tmp;

    

    //((u8 *)saddr)[2] ^= 1; // change the third octet (class C) 

    //((u8 *)daddr)[2] ^= 1;

    type = skb->data + sizeof(struct ethhdr) + sizeof(struct iphdr);

    //printk("tx package type = x\n", *type);

    // 修改类型, 原来0x8表示ping

    *type = 0;                  // 0表示reply 

    

    ih->check = 0;           // and rebuild the checksum (ip needs it) 

    ih->check = ip_fast_csum((unsigned char *)ih,ih->ihl);

    

    // 构造一个sk_buff

    rx_skb = dev_alloc_skb(skb->len + 2);

    skb_reserve(rx_skb, 2); // align IP on 16B boundary     

    memcpy(skb_put(rx_skb, skb->len), skb->data, skb->len);

    // Write metadata, and then pass to the receive level 

    rx_skb->dev = dev;

    rx_skb->protocol = eth_type_trans(rx_skb, dev);

    rx_skb->ip_summed = CHECKSUM_UNNECESSARY; // don't check it 

    dev->stats.rx_packets++;

    dev->stats.rx_bytes += skb->len;

    // 提交sk_buff

    netif_rx(rx_skb);

}

static int virt_net_send_packet(struct sk_buff *skb, struct net_device *dev)

{

    static int cnt = 0;

    printk("virt_net_send_packet cnt = %d\n", ++cnt);

    // 对于真实的网卡, 把skb里的数据通过网卡发送出去 

    netif_stop_queue(dev); // 停止该网卡的队列 

    // ......                               // 把skb的数据写入网卡 

    // 构造一个假的sk_buff,上报 

    emulator_rx_packet(skb, dev);

    dev_kfree_skb (skb);       // 释放skb 

    netif_wake_queue(dev); // 数据全部发送出去后,唤醒网卡的队列 

    // 更新统计信息 

    dev->stats.tx_packets++;

    dev->stats.tx_bytes += skb->len;

    

    return 0;

}

static const struct net_device_ops virt_netdev_ops = {

    .ndo_start_xmit = virt_net_send_packet,

};

static int virt_net_init(void)

{

    // 1. 分配一个net_device结构体 

    vnet_dev = alloc_netdev(0, "vnet%d", ether_setup);  // alloc_etherdev 

    // 2. 设置 

    vnet_dev->netdev_ops    = &virt_netdev_ops;

    // 设置MAC地址 

    vnet_dev->dev_addr[0] = 0x08;

    vnet_dev->dev_addr[1] = 0x89;

    vnet_dev->dev_addr[2] = 0x89;

    vnet_dev->dev_addr[3] = 0x89;

    vnet_dev->dev_addr[4] = 0x89;

    vnet_dev->dev_addr[5] = 0x11;

    // 设置下面两项才能ping通 

    vnet_dev->flags           |= IFF_NOARP;

    vnet_dev->features        |= NETIF_F_NO_CSUM;    

    // 3. 注册 

    //register_netdevice(vnet_dev);

    register_netdev(vnet_dev);

    

    return 0;

}

static void virt_net_exit(void)

{

    unregister_netdev(vnet_dev);

    free_netdev(vnet_dev);

}

module_init(virt_net_init);

module_exit(virt_net_exit);

MODULE_AUTHOR("thisway.diy@163.com,17653039@qq.com");

MODULE_LICENSE("GPL");


推荐阅读

史海拾趣

EUDYNA公司的发展小趣事

在2004年,电子行业的两大巨头FUJITSU富士通与SUMITOMO住友电气工业宣布合并,成立了EUDYNA半导体有限公司。这一合并不仅是两家公司资源的整合,更是技术力量的融合。EUDYNA自诞生之日起,就承载着推动半导体行业创新的重任。通过不断研发,EUDYNA在光波、微波器件领域逐渐崭露头角,成为全球客户的信赖之选。

台湾诚阳(BC)公司的发展小趣事

台湾诚阳(BC)公司始终坚守品质至上的原则。从原材料的采购到生产过程的每一个环节,公司都严格把控,确保产品的品质达到最高标准。同时,公司还建立了完善的售后服务体系,为客户提供及时、专业的技术支持和服务。这种对品质的执着追求,使得台湾诚阳在客户中赢得了良好的口碑,品牌影响力逐渐扩大。

Electromagnetic Industries Llp公司的发展小趣事

作为一家有社会责任感的企业,EMI公司不仅关注经济效益的增长,还积极履行社会责任。公司积极参与各种公益活动和社会救助行动,为灾区捐款捐物、支持教育事业等。同时,公司还注重环保和可持续发展,通过引进环保技术和设备、加强废弃物处理等措施降低生产过程中的环境污染。这些行动展现了EMI公司的良好企业形象和社会责任感。

Fluke公司的发展小趣事

进入21世纪,随着科技的不断进步,电子行业对产品的性能和质量要求越来越高。EMI公司意识到,只有不断创新才能在激烈的市场竞争中立于不败之地。因此,公司加大了对研发的投入,引进了一批高端技术人才,并建立了完善的研发体系。经过几年的努力,EMI公司成功研发出了一系列具有自主知识产权的电磁产品,这些产品在性能和质量上均达到了国际先进水平,赢得了客户的广泛赞誉。

Harwin公司的发展小趣事

Harbour Industries始终将产品质量视为企业的生命线。为了确保产品质量达到国际一流水平,公司不断引入先进的质量管理体系。1990年代末期,Harbour成功通过了ISO9001产品质量认证。这一认证不仅标志着公司的质量管理体系已经达到了国际标准,也为其在全球市场中的竞争提供了有力保障。此外,Harbour还实行了“过程管理”来确定和控制产品成本,进一步提升了其市场竞争力和盈利能力。

Datasensor公司的发展小趣事

1972年,意大利的Romano Volta博士凭借对光电技术的深厚理解和前瞻性眼光,创立了DATALOGIC公司,并致力于自动化机器的光电传感器和控制产品的开发。这是Datasensor公司的起点,也是其日后成为全球工业自动化光电检测领域领导者的基石。在初创期,公司面临技术挑战、市场竞争和资金压力等多重困难,但Romano Volta博士的坚定信念和团队的共同努力,使公司逐渐站稳脚跟,并开始赢得市场的认可。

问答坊 | AI 解惑

【新手指南之一】哪一种人不宜学单片机?(转帖)

不宜学单片机的人容易问:我到底该学什么; ----踏踏实实的学点基本的吧?连单片机都不知道是什么就想去学ARM? c语言不会想搞LINUX?别老是好高骛远. 不宜学单片机的人容易问:谁有xxx源码?--(你给人家多少钱啊?自己的劳动白送你?) 不宜 ...…

查看全部问答>

国赛C题??!!

本帖最后由 paulhyde 于 2014-9-15 09:02 编辑 今年的c题和03年的B题有什么区别?加了“直流”,怎么理解?  …

查看全部问答>

基于WSN的路灯监控管理系统

基于WSN的路灯监控管理系统 摘要:介绍了一个基于无线传感器网络的远程路灯监控管理系统,系统主要由传感器节点、远程控制终端(RTU)和监控中心组成。在单个路灯中嵌入无线传感模块,形成具有采集、收发信息数据,控制各个路灯节点以及自组织等功 ...…

查看全部问答>

Emc 教程经典3-4章

Emc 教程经典3-4章…

查看全部问答>

推荐一下嵌入式和WINCE的书吧

现在刚刚接触嵌入式,以前只有工控的经验,哪些书比较好一点?大学的时候研究过windows内核,对于操作系统也比较了解。对于嵌入式的开发环境和流程还不是很了解,希望能尽快入门,以后上来和大家一起讨论问题。…

查看全部问答>

高分求助 TCP/IP问题

现象:1、我用2410和2440 一个做服务器一个做客户端可以正常通信       2、他们也都可以和PC正常通信 他们不管是做服务器还是客户端,都是可以正常通信       3、以上链接都是通过交叉网线连得 现在的 ...…

查看全部问答>

过年了,没啥事,散点分给大家吧!

祝大家牛年进步! 为了提倡环保,节省纸张,在春节千万别送我贺卡,请在尽可能大的人民币上写下祝福的话送我就可以了,节约是美德,祝春节快乐!…

查看全部问答>

GPRS MODEM自动连接网络的问题

     已经新建立了一个连接,使用RasDial()函数连接到了 输入 at 指令的模块,问题是怎么让程序自动输入at指令 并且自动 按继续按钮连接上网呢?谢谢大家了. at指令是:at+cgdcont=1,\"ip\",\"cmnet\" 和  atdt*99# ,我 ...…

查看全部问答>

6410按键处理,有时候按下键没响应,有时候按下出好几个字符,求助大家!

我把6410的按键驱动映射为我需要的字符了,可是总是响应时有些问题,有时候按下键不能响应,有时候会出好几个字符,这是怎么回事啊,我应该修改哪些地方啊?…

查看全部问答>

散分~增加人气

这里怎么没人气啊,帖子好少…

查看全部问答>