linux内核构造skb发包-----raw、tcp网络编程
1. 内核raw发包
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/moduleparam.h>
#include <linux/ip.h>
#include <linux/version.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/netfilter_bridge.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <net/ip.h>
#include <linux/rculist.h>
#include <linux/spinlock.h>
#include <linux/times.h>
#include <linux/slab.h>
#include <asm/unaligned.h>
#include <linux/atomic.h>
#include <linux/jhash.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/if_ether.h>
struct sk_buff *skb;
int _send_raw_skb(unsigned char *mac1) {
struct net_device * mdev = NULL;
struct ethhdr *eth;
unsigned char *data;
int dlen, i;
unsigned char mac[10]={'1','2','3','a','b','c'};
/*
* Allocate a buffer
*/
dlen = 6+sizeof(struct ethhdr);
skb = alloc_skb(dlen, GFP_ATOMIC);
if (skb == NULL)
return -1;
skb_reserve(skb, dlen);
mdev = dev_get_by_name(&init_net, "ens33");
if(mdev == NULL)
{
printk("get dev error\n");
return -1;
}
skb->dev = mdev;
skb->protocol = htons(ETH_P_PAE);
memcpy(skb_push(skb,6),mac,6);
skb_push(skb,sizeof(struct ethhdr));
eth = (struct ethhdr *)skb->data;
memcpy(eth->h_source, skb->dev->dev_addr, 6);
memset(eth->h_dest, 0xff, 6);
eth->h_proto = htons(ETH_P_PAE);
dev_queue_xmit(skb);
return 0;
}
static int test_init(void) {
printk("%s\n", __FUNCTION__);
_send_raw_skb(NULL);
return 0;
}
static void test_exit(void) {
printk("%s\n", __FUNCTION__);
dev_put(skb->dev);
}
module_init(test_init);
module_exit(test_exit);
MODULE_LICENSE("GPL");
2. tcp发包(以client端为例,测试时可以用nc -l -p 8888做为server)
#include<linux/in.h>
#include<linux/inet.h>
#include<linux/socket.h>
#include<net/sock.h>
#include<linux/init.h>
#include<linux/module.h>
#define BUFFER_SIZE 1024
int connect_send_recv(void){
struct socket *sock;
struct sockaddr_in s_addr;
unsigned short port_num = 8888;
int ret = 0;
char *send_buf = NULL;
char *recv_buf = NULL;
struct kvec send_vec, recv_vec;
struct msghdr send_msg, recv_msg;
/* kmalloc a send buffer*/
send_buf = kmalloc(BUFFER_SIZE, GFP_KERNEL);
if (send_buf == NULL) {
printk("client: send_buf kmalloc error!\n");
return -1;
}
/* kmalloc a receive buffer*/
recv_buf = kmalloc(BUFFER_SIZE, GFP_KERNEL);
if(recv_buf == NULL){
printk("client: recv_buf kmalloc error!\n");
return -1;
}
memset(&s_addr, 0, sizeof(s_addr));
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(port_num);
s_addr.sin_addr.s_addr = in_aton("192.168.12.129");
sock = (struct socket *)kmalloc(sizeof(struct socket), GFP_KERNEL);
// 创建一个sock, &init_net是默认网络命名空间
ret = sock_create_kern(&init_net, AF_INET, SOCK_STREAM, IPPROTO_TCP, &sock);
if (ret < 0) {
printk("client:socket create error!\n");
return ret;
}
printk("client: socket create ok!\n");
//连接
ret = sock->ops->connect(sock, (struct sockaddr *)&s_addr, sizeof(s_addr), 0);
if (ret != 0) {
printk("client: connect error!\n");
return ret;
}
printk("client: connect ok!\n");
memset(send_buf, 'a', BUFFER_SIZE);
memset(&send_msg, 0, sizeof(send_msg));
memset(&send_vec, 0, sizeof(send_vec));
send_vec.iov_base = send_buf;
send_vec.iov_len = BUFFER_SIZE;
// 发送数据
ret = kernel_sendmsg(sock, &send_msg, &send_vec, 1, BUFFER_SIZE);
if (ret < 0) {
printk("client: kernel_sendmsg error!\n");
return ret;
} else if(ret != BUFFER_SIZE){
printk("client: ret!=BUFFER_SIZE");
}
printk("client: send ok!\n");
memset(recv_buf, 0, BUFFER_SIZE);
memset(&recv_vec, 0, sizeof(recv_vec));
memset(&recv_msg, 0, sizeof(recv_msg));
recv_vec.iov_base = recv_buf;
recv_vec.iov_len = BUFFER_SIZE;
// 接收数据
ret = kernel_recvmsg(sock, &recv_msg, &recv_vec, 1, BUFFER_SIZE, 0);
printk("client: received message:\n %s\n", recv_buf);
// 关闭连接
kernel_sock_shutdown(sock, SHUT_RDWR);
sock_release(sock);
return 0;
}
static int client_example_init(void){
printk("client: init\n");
connect_send_recv();
return 0;
}
static void client_example_exit(void){
printk("client: exit!\n");
}
module_init(client_example_init);
module_exit(client_example_exit);
MODULE_LICENSE("GPL");
linux内核构造skb发包-----raw、tcp网络编程的更多相关文章
- 【Linux网络编程】TCP网络编程中connect()、listen()和accept()三者之间的关系
[Linux网络编程]TCP网络编程中connect().listen()和accept()三者之间的关系 基于 TCP 的网络编程开发分为服务器端和客户端两部分,常见的核心步骤和流程如下: conn ...
- Linux下TCP网络编程与基于Windows下C#socket编程间通信
一.linux下TCP网络编程基础,需要了解相关函数 Socket():用于套接字初始化. Bind():将 socket 与本机上的一个端口绑定,就可以在该端口监听服务请求. Listen():使s ...
- JAVA TCP网络编程学习笔记
一.JAVA网络编程概述 网络应用程序,就是在已实现网络互联的不同计算机上运行的应用程序,这些程序之间可以相互交换数据.JAVA是优秀的网络编程语言,Java网络编程的类库位于java.net包中.J ...
- 简述TCP网络编程本质
基于事件的非阻塞网络编程是编写高性能并发网络服务程序的主流模式,头一次使用这种模式编程需要转换思维模式 .把原来的"主动调用recv()来接收数据,主动调用accept()来接受连接,主动调 ...
- TCP网络编程
TCP网络编程 与UDP不同的是TCP是通过客服端和服务端的方式来传输数据的.客服端:public class TCPClient { /** * @param args * @th ...
- Java - TCP网络编程
Java - TCP网络编程 Server 逻辑思路: 创建ServerSocket(port),然后服务器的socket就启动了 循环中调用accept(),此方法会堵塞程序,直到发现用户请求,返回 ...
- 8-2udp和tcp网络编程以及粘包和解决粘包的方法
一 tcp网络编程 server 端 import socket sk=socket.socket() #实例化一个对象 sk.setsockopt(socket.SOL_SOCKET,socket ...
- Tomcat 调优之从 Linux 内核源码层面看 Tcp backlog
前两天看到一群里在讨论 Tomcat 参数调优,看到不止一个人说通过 accept-count 来配置线程池大小,我笑了笑,看来其实很多人并不太了解我们用的最多的 WebServer Tomcat,这 ...
- 【Linux 网络编程】TCP网络编程中connect()、listen()和accept()三者之间的关系
基于 TCP 的网络编程开发分为服务器端和客户端两部分,常见的核心步骤和流程如下: connect()函数:对于客户端的 connect() 函数,该函数的功能为客户端主动连接服务器,建立连接是通过三 ...
随机推荐
- Django model中的save后的return
先给结论吧:在Django model的操作函数中,obj.save()后再执行return obj会返回obj的ID. 看例子: ... def create_session(self,bind_h ...
- windows7 + iis7 + fastcgi + php5 + netbeans + xdebug 调试 php
Xdebug是一个开放源代码的PHP程序调试器(即一个Debug工具),可以用来跟踪,调试和分析PHP程序的运行状况. windows7 + iis7 + fastcgi + php5 + netbe ...
- jquery 单击选中 再次选中取消选中
html: <div id="full" class='weui-popup__container' style="background: #fff"&g ...
- 前端研究CSS之内联元素块级化/区域大小/文字和图标的位置
做了一天的小按钮基本都是文字+小图标的组合,问题挺多处理的不好,现在总结一下做个了断. //页面结构 <span class="b"> <a href=" ...
- STM32驱动模数转换芯片ADS1120(基础知识篇)第1篇
1. 先看下ADS1120的结构图,ADS1120是个比较奇葩的ADC模数转换器,因为比较适用于热电阻之类的温度采集器.看下图,有个MUX多路复用器,应该是选择两个差分信号去测试,通过输入多路复用器 ...
- mysql的HA及openstack和k8s区别
数据库HA(Hight Availability) mysql自身支持主主/主备部署,多主(>2),一主多备 galera mariadb集群:多主相互备份 修改容器的启动配置 修改Docker ...
- 2019年Java面试题基础系列228道(5)
21.存在两个类,B 继承 A,C 继承 B,我们能将 B 转换为C 么?如 C = (C) B: 这属于强制类型转换,如果被转换的B实例不是C类型,会有异常 比如你的ABC分别对应动物,猫,黑猫. ...
- Django 之验证和授权
一.验证和授权概述 Django有一个内置的授权系统.他用来处理用户.分组.权限以及基于cookie的会话系统.Django的授权系统包括验证和授权两个部分.验证是验证这个用户是否是他声称的人(比如用 ...
- ROS初探--意义、基本模块
顾虑就使我们都变成了懦夫,使得那果断的本色蒙上了一层思虑的惨白的容颜,本来可以做出伟大的事业,由于思虑就化为乌有了,丧失了行动的能力.-----哈姆雷特 ROS: Robot Operating Sy ...
- HTTP权威指南-URL与资源
URL与资源 URL是URI的子集 方案(http),主机(www.baidu.com),路径(/home/logo.png) 方案,其实有很多,HTTP.HTTPS.FTP,SMTP等等. http ...