QNX系统上用Berkeley Packet Filter直接进行原始数据的收发

本文介绍了如何在QNX系统上通过Berkeley Packet Filter(BPF)直接操作网络数据链路层,从而绕过TCP/IP收发自定义协议的数据包。内容包括打开BPF设备、使用ioctl绑定接口、构建及发送数据包的过程。QNX官方推荐使用BPF接口而非raw_socket来访问数据链路层。
摘要由CSDN通过智能技术生成

这次我们讲的是在QNX系统上直接操作网络的数据链路层进行原始数据包收发的过程,即通过Berkeley Packet Filter我们可以绕过TCP/IP并且收发自己定义的协议。
在QNX系统的帮助文档上,很明确的写到:这里写图片描述
即伯克利包过滤语言通过网络接口提供数据链路层的数据的访问通道,具体实现步骤为:
1、打开 BPF 设备(即向系统声明使用BPF设备)

/* using BPF device */
char bpfname[16] = {"/dev/bpf\0"};
int i=0;

/* opening autocloning BFP device */
bpf = open(bpfname, O_RDWR);

在这里由于避免因各种原因打开设备失败,所以后面紧接一个迭代函数再次尝试打开设备,因为/dev/bpf是一个可以多次重复打开的设备,所以可以这样实现。

if (bpf < 0){
    /* no autocloning BPF found: fall back to iteration */
    for(i=0; i<128; i++){
        snprintf(bpfname, sizeof(bpfname), "/dev/bpf%d", i);
        bpf = open(bpfname, O_RDWR);

        if(bpf != -1)
            break;
    }

2.使用ioctl()函数来控制设备的操作
首先使用BIOCSETIF ioctl() 命令来绑定bpf和一个真正的网络接口,接口是在结构体ifreq中定义的。

const char* ifname = "wm0";
struct ifreq iface;
strncpy(iface.ifr_name, ifname, sizeof(ifname));
if( ioctl(bpf, BIOCSETIF, &iface) > 0){
    printf("Could not bind %s to BPF\n", ifname);
}
printf("Associated with \"%s\"\n", ifname);

在这步骤之后,可以根据自己的需求来设定网卡的操作模式和接收数据包的方式等。具体可以参考QNX系统的帮助文档里的ioctl()函数解释。
3、在做好以后上述两个步骤之后在第三步里就可以构建自己所要传输的数据包了。
即:目的地址+原地址+

        dst_mac[0] = 0x10;//设置目的网卡地址
        dst_mac[1] = 0x78;
        dst_mac[2] = 0xd2;
        dst_mac[3] = 0xc6;
        dst_mac[4] = 0x2f;
        dst_mac[5] = 0x89;

//—————————————————————————————————

        src_mac[0] = 0x11;//设置目的网卡地址
        src_mac[1] = 0x78;
        src_mac[2] = 0xd2;
        src_mac[3] = 0xc6;
        src_mac[4] = 0x2f;
        src_mac[5] = 0x89;

//——————————————————————————————-

          datalen = 12;
          data[0] = 'h';
          data[1] = 'e';
          data[2] = 'l';
          data[3] = 'l';
          data[4] = 'o';
          data[5] = ' ';
          data[6] = 'w';
          data[7] = 'o';
          data[8] = 'r';
          data[9] = 'l';
          data[10] = 'd';
          data[11] = '!';

//——————————————————————————————————-

       frame_length = 6 + 6 + 2   + datalen;
       memcpy (ether_frame, dst_mac, 6);
       memcpy (ether_frame + 6, src_mac, 6);

       ether_frame[12] = ETH / 256;
       ether_frame[13] = ETH % 256;

 // data  package
       memcpy (ether_frame + 14 , data, datalen);

4、在组建好数据包

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值