send_udp 构造一个udp数据包并根据网络设备发送

int send_udp(struct net_device *odev, u16 local_port, u32 remote_ip, u16 remote_port, u8 *msg, int len) { struct sk_buff *skb; int total_len, eth_len, ip_len, udp_len, header_len; struct udphdr *udph; struct iphdr *iph; struct ethhdr *eth; u32 local_ip; //local_ip = inet_select_addr(odev, remote_ip, RT_SCOPE_LINK); // 选择网络设备地址 local_ip = inet_select_addr(odev, 0, RT_SCOPE_UNIVERSE); printk( "local ip is "NIPQUAD_FMT"/n", NIPQUAD( local_ip ) ); local_ip = ntohl( local_ip ); if ( !local_ip ) { return; } // 设置各个协议数据长度 udp_len = len + sizeof(*udph); ip_len = eth_len = udp_len + sizeof(*iph); total_len = eth_len + ETH_HLEN + NET_IP_ALIGN; header_len = total_len - len; // 分配skb skb = alloc_skb( total_len + LL_MAX_HEADER, GFP_ATOMIC ); if ( !skb ) { dbg_err( "alloc_skb fail./n" ); return; } // 预先保留skb的协议首部长度大小 skb_reserve( skb, LL_MAX_HEADER + header_len ); // 拷贝负载数据 skb_copy_to_linear_data(skb, msg, len); skb->len += len; // skb->data 移动到udp首部 skb_push(skb, sizeof(*udph)); skb_reset_transport_header(skb); udph = udp_hdr(skb); udph->source = htons(local_port); udph->dest = htons(remote_port); udph->len = htons(udp_len); udph->check = 0; udph->check = csum_tcpudp_magic(htonl(local_ip), htonl(remote_ip), udp_len, IPPROTO_UDP, csum_partial(udph, udp_len, 0)); if (udph->check == 0) udph->check = CSUM_MANGLED_0; // skb->data 移动到ip首部 skb_push(skb, sizeof(*iph)); skb_reset_network_header(skb); iph = ip_hdr(skb); /* iph->version = 4; iph->ihl = 5; */ put_unaligned(0x45, (unsigned char *)iph); iph->tos = 0; put_unaligned(htons(ip_len), &(iph->tot_len)); iph->id = 0; iph->frag_off = 0; iph->ttl = 64; iph->protocol = IPPROTO_UDP; iph->check = 0; put_unaligned(htonl(local_ip), &(iph->saddr)); put_unaligned(htonl(remote_ip), &(iph->daddr)); iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); /* // skb->data 移动到eth首部 eth = (struct ethhdr *) skb_push(skb, ETH_HLEN); skb_reset_mac_header(skb); skb->protocol = eth->h_proto = htons(ETH_P_IP); memcpy(eth->h_source, dev_addr, ETH_ALEN); memcpy(eth->h_dest, remote_mac, ETH_ALEN); */ skb->dev = odev; // 直接发送 //dev_queue_xmit( skb ); // 获取output rtable if ( ip_route_out( skb, iph ) != 0 ) { goto free_skb; } // 通过系统决定发送 ip_local_out(skb); return; free_skb: trace( "free skb./n" ); kfree_skb(skb); return ; }

ip_route_out 函数查找路由路径, 获取output rtable .

int ip_route_out( struct sk_buff *skb, struct iphdr *iph ) { int err = -1; struct flowi fl = {}; struct rtable *rt = NULL; fl.nl_u.ip4_u.daddr = iph->daddr; if (ip_route_output_key( &init_net, &rt, &fl) != 0) { dbg_err( "ip_route_output_key call fail./n" ); goto _out; } trace( "rt_dst="NIPQUAD_FMT " rt_gw=" NIPQUAD_FMT "/n", NIPQUAD( rt->rt_dst ), NIPQUAD( rt->rt_gateway ) ); trace( "route output dev=%s/n", rt->u.dst.dev->name ); //skb->dst = &rt->u.dst; skb->rtable = rt; err = 0; _out: return err; }

在内核中构造一个UDP 数据相关推荐

  1. Linux内核网络协议栈:udp数据包发送(源码解读)

    <监视和调整Linux网络协议栈:接收数据> <监控和调整Linux网络协议栈的图解指南:接收数据> <Linux网络 - 数据包的接收过程> <Linux网 ...

  2. linux添加以太网头部函数,linux – 在内核模块中创建一个以太网数据包并发送它...

    我需要创建一个以太网数据包并在我的内核模块中发送它.有人可以帮我这样做吗? 我想我需要使用dev_alloc_skb创建一个skb,然后我需要编写mac_ethernet,插入数据并使用dev_que ...

  3. 黑客使用一个UDP数据包可以打开任何HID门禁控制器

    趋势科技研究人员发现在HID门禁控制器存在一个严重的漏洞,它允许黑客发送一个恶意的UDP请求到门禁控制器,自动解锁和/或关闭门禁警报功能.HID是一家门禁控制器公司,它出品的产品可以让用户使用感应卡靠 ...

  4. python链表中删除一个节点数据_python实现单链表中删除倒数第K个节点的方法

    本文实例为大家分享了python实现单链表中删除倒数第K个节点的具体代码,供大家参考,具体内容如下 题目: 给定一个链表,删除其中倒数第k个节点. 代码: class LinkedListAlgori ...

  5. java 中append()_调用append()方法在Java中构造一个StringBuffer对象

    StringBufferappend()方法将特定参数的String表示形式附加到序列中.它是java.lang.StringBuffer类的方法.此方法返回对该对象的引用. 该方法更改方法中调用的对 ...

  6. 操作系统作业:向内核中添加一个系统调用

    本文主要突出操作中遇到的问题及解决方案,关于详细过程不做过多展示,大家可以参考 https://blog.csdn.net/qq_41175905/article/details/80529245 h ...

  7. 编写一个python程序,利用scapy数据库构造一个icmp数据包,使其能实现ip扫描

    下面是一个使用 scapy 库来构造 ICMP 数据包并进行 IP 扫描的 Python 程序的示例: from scapy.all import *# 设置源 IP 地址和目的 IP 地址 src_ ...

  8. java中引用一个文件数据_JAVA-基础-引用数据类型(类)

    引用数据类型分类 我们可以把类的类型为两种: l 第一种,Java为我们提供好的类,如Scanner类,Random类等,这些已存在的类中包含了很多的方法与属性,可供我们使用. l  第二种,我们自己 ...

  9. linux函数嵌套,gcc内嵌函数__builtin_types_compatible_p 在内核中的一个实例...

    在include/linux/kernel.h中有一个定义: #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_a ...

  10. 从二进制数据流中构造GDAL可以读取的图像数据(C#)

    在上一篇博客中,讲了一下使用GDAL从文件流中构造一个GDAL可以识别的数据来进行处理.原以为这个接口在C#中没有,仔细看了下GDAL库中源码,发现C#版本也有类似的函数,下面是GDAL库中的一个C# ...

最新文章

  1. Windows+Git+TortoiseGit+COPSSH 安装图文教程
  2. windows 检查cuda安装_Windows环境CUDA 4.0:安装与验证
  3. Serverless 实战 —— Funcraft OSS ROS 进行 CI/CD
  4. 此计算机支持多个rdp侦听程序,远程桌面侦听器证书配置
  5. int arr 13 java,java学习13 - 数组的定义、操作、异常、二维数组
  6. 使用EasyMock
  7. java parseint(12.0),Java中parseInt()和valueOf(),toString()的区别
  8. matlab chirp函数模糊函数,8个OFDM-Chirp波形的时频域图及自(互)模糊函数图
  9. python2.7下使用logging模块记录日志到终端显示乱码问题解决
  10. 重置Winsock失败,在NSHHTTP.DLL中初始化函数InitHelperDll启动失败,错误代码为10107的解决方法
  11. 微信人脸SDK集成踩坑
  12. ABP理论学习之EntityFramework集成
  13. java课程设计体会_javaweb课程设计心得体会.doc
  14. iphone live photo没有声音
  15. 你不知道的京东数据库运维自动化体系建设之路
  16. 开发一个多用户商城系统多少钱
  17. Appium+夜神模拟器模拟人为操作
  18. 使用稿定设计如何给制作好的视频加音乐?
  19. python统计字符串字符出现次数
  20. 13.计算机基础之多媒体技术与多媒体计算机系统

热门文章

  1. HolderView vs ViewHolder实例
  2. CF1041A Heist
  3. [网络流24题] 软件补丁问题
  4. 同时安装python2和python3
  5. groupmod 修改用户组信息
  6. 市民卡怎么登录显示服务器繁忙,2分钟办理一笔业务 杭州网记者体验最具人气的“市民卡”窗口服务...
  7. leancloud 怎么绑定域名_云引擎支持绑定加速域名 | LeanCloud 八月变化
  8. c# opencv车牌识别_牛逼plus的springboot+maven车牌识别开源系统
  9. 图书管理系统软件测试报告_软件测试新手入门小知识点,一定要牢记
  10. Linux与git库建立连接,Linux 下建立 Git 与 GitHub 的连接