不用libnet 发送接收自定义以太网帧

/*
 * =====================================================================================
 *
 *       Filename:  sendraw.c
 *
 *    Description:  test
 *
 *        Version:  1.0
 *        Created:  2013年09月27日 12时54分57秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  YOUR NAME (), 
 *        Company:  
 *
 * =====================================================================================
 */


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/if_ether.h>
#include <net/if_arp.h>
#include <net/if.h>
#include <net/ethernet.h>
#include <netpacket/packet.h>


#define  BUFLEN  512 


char senddata[] = {0x21,0x01,0x01,0x42,0x00,0x00,0x1a,0x3a,0x06,0x04,0x03,0x00,0x0e,0xfb,0x14,0xda,0xe9,0x74,0x9c,0x3c,0xc0,0xa8,0x64,0x3b,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};


static void dataFilter(char *buffer, int len);


static int sendData(int argc, char *argv[])
{
    int skfd, n;
    char buf[BUFLEN] = {0,};
    struct ether_header *eth = NULL;
    struct sockaddr_ll toaddr;
    struct ifreq ifr;
        
    unsigned char src_mac[ETH_ALEN] = {0};
    unsigned char dst_mac[ETH_ALEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
    if(3 != argc)
    {
        printf("Usage: %s netdevName \n", argv[0]);
        exit(1);
    }


    if((skfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0)
    {
        perror("create error !");
        exit(1);
    }


    bzero(&toaddr, sizeof(toaddr));
    bzero(&ifr, sizeof(ifr));
    strcpy(ifr.ifr_name, argv[1]);


    //获取接口索引
    if(-1 == ioctl(skfd, SIOCGIFINDEX, &ifr))
    {
        perror("get dev index error ");
        exit(1);
    }


    toaddr.sll_ifindex = ifr.ifr_ifindex;
    printf("interface index:%d\n", ifr.ifr_ifindex);


    //获取接口的mac地址
    if(-1 == ioctl(skfd, SIOCGIFHWADDR, &ifr))
    {
        perror("get dev MAC addr error:");
        exit(1);
    }


    memcpy(src_mac, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
    printf("MAC : %02x-%02x-%02x-%02x-%02x-%02x\n", src_mac[0], src_mac[1], src_mac[2], src_mac[3], src_mac[4], src_mac[5]);


    //开始填充,构造以太头部
    eth = (struct ether_header *)buf;
    memcpy(eth->ether_dhost, dst_mac, ETH_ALEN);


    memcpy(eth->ether_shost, src_mac, ETH_ALEN);
    eth->ether_type = htons(0x8036);


    memcpy((buf+sizeof(struct ether_header)), senddata, sizeof(senddata));


    int len = sizeof(struct ether_header)+sizeof(senddata);


    toaddr.sll_family = PF_PACKET;
    toaddr.sll_protocol = htons(ETH_P_ALL);


    n = sendto(skfd, buf, len, 0, (struct sockaddr *)&toaddr, sizeof(toaddr));


    char buffer[2048] = {0,};


    while(1)
    {
        n = recvfrom(skfd, buffer, 2048, 0, NULL, NULL);
        /*printf("%d bytes read \n", n);*/


        dataFilter(buffer, n);
    }


    close(skfd);


    return 0;
}


static void dataFilter(char *buffer, int len)
{
    //recv data head of 6 bytes is dest mac, along with if 6 source mac
    struct ether_header *eth;


    eth = (struct ether_header *)buffer;
    if(eth->ether_type == htons(0x8033))
    {
        printf("===========================len = %d===========================\n", len);
        printf("dest mac addr:%02x:%02x:%02x:%02x:%02x:%02x\n", \
            eth->ether_dhost[0], eth->ether_dhost[1], eth->ether_dhost[2], eth->ether_dhost[3], eth->ether_dhost[4], eth->ether_dhost[5]);


        printf("source mac addr:%02x:%02x:%02x:%02x:%02x:%02x\n", \
            eth->ether_shost[0], eth->ether_shost[1], eth->ether_shost[2], eth->ether_shost[3], eth->ether_shost[4], eth->ether_shost[5]);
    }


}


int main(int argc, char *argv[])
{
    sendData(argc, argv);


    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前进的蜗牛啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值