使用PF_PACKET发送自定义type以太网数据包

本文介绍如何使用PF_PACKET和SOCK_RAW创建套接字发送自定义以太网帧,包括设置MAC地址、构造帧数据及发送过程。适用于实现特定以太网协议或进行网络测试。

目标

  • 利用PF_PACKET 和SOCK_RAW创建套接字发送一个任意的以太网帧

背景

  • 以太网是一个链路层协议。大多数网络程序员关注网络栈的传输层及以上,所以不需要直接处理以太网帧,但是某些场景下关注传输层以下也是有必要的。如:

    1)实现网络协议栈里面没有内置的以太网协议类型
    2)为测试目的,产生一个畸形或者其它非常规帧

使用场景

  • 已知发送方和接收方的mac地址,就可以使用这个以太网协议发送接收数据。

编程

  1. 使用PF_PACKET 和SOCK_RAW创建套接字
    注:用这个套接字的打开需要用户有root权限
	if((fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0){
   
   
		perror("socket create failed");
		exit (EXIT_FAILURE);
	} 
参数1:PF_PACKET,该参数是从MAC层直接收发原始数据。
参数2:SOCK_RAW,使用该参数需要自己构造以太网数据包。
			SOCK_DGRAM,填这个参数是以太网头已经构造好了。
参数3:ETH_P_ALL自身定义于  /usr/include/linux/if_ether.h中,使用它是包含所有协议类型。

2.将网络接口赋值给原始套接字地址结构

    memset(&device, 0, sizeof(device));
	strncpy(req.ifr_name, interface, IFNAMSIZ);	//指定网卡名称
	//赋值以太网接口的索引值
	ioctl(fd, SIOCGIFINDEX, &req);
	bzero(&device, sizeof(device));
	device.sll_ifindex = req.ifr_ifindex;
	
	dst_mac[0] = 0x00;
	dst_mac[1] = 0x50;		
	dst_mac[2] = 0x90;				
	dst_mac[3] = 0xb0;
	dst_mac[4] = 0xb0;		
	dst_mac[5] = 0xb0;
     //Fill out sockaddr_ll.
    device.sll_family = AF_PACKET;
    memcpy(device.sll_addr, dst_mac, 6);
    device.sll_halen = htons(6);
	device.sll_protocol = htons(ETH_P_ALL);
里面除了以太网接口的索引值,其他赋值都是可以不用的,因为你下面自己会构造以太网包,目标mac会你构造的包中的mac为准。

3.构造协议包

    char org_buf[60] = {
   
   		
			0x00, 0x50, 0x90, 0xb0, 0xb0, 0xb0,  // 目的mac
			0x00, 0x50, 0x90, 0xcc, 0xcc, 0xcc,  // 源mac
            0x80, 0x01,	//以太网协议type
            0, 1, 0, 42,
            1, 4, 0, 0,
            2, 4, 0, 0,
            3, 4, 0, 0,
            4, 4, 0, 0,
            5, 4, 0, 0,
            6, 4, 0, 0,
            7, 4, 0, 0,
            
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值