• 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 ");
    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 ", __FUNCTION__);
    _send_raw_skb(NULL);
    return 0;
    }

    static void test_exit(void) {
    printk("%s ", __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! ");
    return -1;
    }
    /* kmalloc a receive buffer*/
    recv_buf = kmalloc(BUFFER_SIZE, GFP_KERNEL);
    if(recv_buf == NULL){
    printk("client: recv_buf kmalloc error! ");
    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! ");
    return ret;
    }
    printk("client: socket create ok! ");
    //连接
    ret = sock->ops->connect(sock, (struct sockaddr *)&s_addr, sizeof(s_addr), 0);
    if (ret != 0) {
    printk("client: connect error! ");
    return ret;
    }
    printk("client: connect ok! ");
    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! ");
    return ret;
    } else if(ret != BUFFER_SIZE){
    printk("client: ret!=BUFFER_SIZE");
    }
    printk("client: send ok! ");
    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: %s ", recv_buf);
    // 关闭连接
    kernel_sock_shutdown(sock, SHUT_RDWR);
    sock_release(sock);
    return 0;
    }
    static int client_example_init(void){
    printk("client: init ");
    connect_send_recv();
    return 0;
    }
    static void client_example_exit(void){
    printk("client: exit! ");
    }
    module_init(client_example_init);
    module_exit(client_example_exit);
    MODULE_LICENSE("GPL");

  • 相关阅读:
    css学习之 display:inline-block;
    java重写
    PDF在线阅读 FlexPaper 惰性加载 ;
    js两种生成对象模式(公有成员和成员私有)
    js 设计模式-接口
    聊聊 elasticsearch 之分词器配置 (IK+pinyin)
    nexus 批量上传jar到私有仓库内
    Java IDEA 根据mybatis-generator-core自动生成代码支持sqlserver获取备注(二)
    Elasticsearch实现搜索推荐词
    Java IDEA根据database以及脚本代码自动生成DO,DAO,SqlMapper文件(一)
  • 原文地址:https://www.cnblogs.com/newjiang/p/10989308.html
Copyright © 2020-2023  润新知