udp协议栈

使用netmap接收网卡数据,对接收的数据进行解析。
下一步,对网卡驱动进行分析,研究网卡是如何进行数据的发送和接收的。

#include<stdio.h>
#include<unistd.h>
#include<sys/poll.h>


#define NETMAP_WITH_LIBS
#include<net/netmap_user.h>

#pragma pack(1)
struct udphdr {
 unsigned short source;
 unsigned short dest;
 unsigned short len;
 unsigned short check;
};

struct iphdr {

 unsigned char version:4;
 unsigned char   ihl:4;
 unsigned char tos;
 unsigned short tot_len;
 unsigned short id;
 unsigned short frag_off;
 unsigned char ttl;
 unsigned char protocol;
 unsigned short check;
 unsigned int saddr;
 unsigned int daddr;
};

#define ETH_ALEN 6
#define PROTO_IP 0x0800
#define PROTO_UDP 17
struct ethhdr {
 unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
 unsigned char h_source[ETH_ALEN]; /* source ether addr */
 unsigned short  h_proto;  /* packet type ID field */
};

// 字节对齐问题
struct udppkt
{
    struct ethhdr eh;
    struct iphdr ip;
    struct udphdr udp;
    unsigned char data[]; //柔性数组,或者写成data[0]
            // 特性:可以data[1] = 'a',不会越界      sizeof()一直为0
};

/**
 * 1:协议栈的数据封装如上,结构体原型参考资料上的结构
 * 2:如何抓取网络原始数据
 *      1) raw socket
 *      2) pf_ring
 *      3) netmap
 *      4) dpdk
 * 本次sample code 以netmap为例
 *
 * data--->网卡---dma/其他方式--->内存
 * 对内存中的相应的地址进行操作就是对网卡中的
 * 数据进行操作
*/
int main()
{
    // 测试柔性数组代码
    // unsigned char data[0];
    // printf("len :%d\n", sizeof(data));
    // data[1] = 100;
    // printf("len :%d\n", sizeof(data));

    struct nm_desc* nmr = nm_open("netmap:eth0", NULL, 0, NULL);
    if(nmr == NULL)
        return 0;

    struct pollfd pfd = {0};
    pfd.fd = nmr->fd;    // fd标识网卡信息,可以监控网卡中是否有数据
    pfd.events = POLLIN;

    struct nm_pkthdr h;


    while (1)
    {
       int ret = poll(&pfd, 1, -1);
       if(ret < 0)
        continue;

        if(pfd.eventd& POLLIN)
        {
            char* stream = nm_nextpkt(nmr, &h);
            printf("stream: %s\n",stream);

            struct  ethhdr* eh = (struct  ethhdr*)stream;
            if(ntohs(eh->h_proto) == PROTO_IP)
            {
                struct udppkt* udp = (struct udppkt*)stream;
                if(udp->ip.protocol == PROTO_UDP)
                {
                    int udp_length = ntohs(udp->udp.len);
                    udp->data[udp->udp.len] ='\0';
                    printf("udp->%s\n", udp->data);
                }
            }

        }
    }

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值