AF_PACKET发送以太网帧(IP)

13 篇文章 0 订阅

基于SylixOS,在linux需要替换部分头文件

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <time.h>
#include <unistd.h>
#include <sys/socket.h>
#include <net/if_ether.h>
#include <netpacket/packet.h>
#include <network/lwip/prot/tcp.h>
#include <network/lwip/prot/udp.h>
#include <network/lwip/prot/dns.h>
#include <network/lwip/prot/etharp.h>
#include <network/lwip/prot/icmp.h>
#include <network/lwip/prot/ip4.h>
#include <network/lwip/prot/igmp.h>
#include <netinet/ip.h>
#include <netinet6/ip6.h>
#include <net/if_arp.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <sys/mman.h>
#include <netdb.h>
#include <poll.h>
#include <errno.h>
#include <sys/ioctl.h>
/*
  用户自定义数据类型
*/
struct my_p_hdr {
    u_short     type;
    uint8_t     num;
    int         len;
    int         dataoff;
} __attribute__((__packed__));

#define     BUFSIZE        1489
#define     ETH_P_USER      0x0700
static  char        content[BUFSIZE + 25];

int main (int argc, char *argv[])
{
    int                  sockfd, ret;
    char                *buff = NULL;
    struct ifreq         ireq;
    struct sockaddr_ll   sockaddr;
    struct ethhdr       *ethheader;
    struct my_p_hdr     *myhdr;
    char                *pmac;
    uint8_t              dstmac[ETH_ALEN];
    int                  i;

    if (argc < 2) {
        fprintf(stderr, "./packet_client [MAC ADDR (00:11:22:33:44:55)]\n");
        return  (-1);
    }

    pmac = argv[1];

    sscanf(pmac, "%02x:%02x:%02x:%02x:%02x:%02x",
                 &dstmac[0], &dstmac[1], &dstmac[2],
                 &dstmac[3], &dstmac[4], &dstmac[5]);

    sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_USER));
    if (sockfd < 0) {
        perror("socket");
        goto exit2;
    }

    memcpy(ireq.ifr_name, "en1", 3);



    ret = ioctl(sockfd, SIOCGIFINDEX, &ireq);
    if (ret < 0) {
        perror("ioctl");
        goto exit2;
    }

    ret = ioctl(sockfd, SIOCGIFHWADDR, &ireq);
    if (ret < 0) {
        perror("ioctl");
        goto exit2;
    }

    printf("ifindex : en%d\n", ireq.ifr_ifindex);

    bzero(&sockaddr, sizeof(sockaddr));
    sockaddr.sll_family     = AF_PACKET;
    sockaddr.sll_protocol   = htons(ETH_P_USER);
    sockaddr.sll_ifindex    = ireq.ifr_ifindex;
    sockaddr.sll_hatype     = ARPHRD_ETHER;
    sockaddr.sll_halen      = ETH_ALEN;
    sockaddr.sll_len        = sizeof(struct sockaddr_ll);

    buff = content;

    ethheader = (struct ethhdr *)buff;

    memcpy(ethheader->h_dest, dstmac, ETH_ALEN);

    for (i = 0; i < ETH_ALEN; ++i) {
        ethheader->h_source[i] = ireq.ifr_hwaddr.sa_data[i];
    }

    ethheader->h_proto = htons(ETH_P_USER);

    myhdr = (struct my_p_hdr *)((char *)buff + sizeof(struct ethhdr));

    myhdr->type = htons(ETH_P_USER);
    myhdr->num  = 10;
    myhdr->len  = BUFSIZE;
    myhdr->dataoff = htons(14 + 11);

    for (i = 0; i < BUFSIZE; ++i) {
        buff[i + 14 + 11] = 'a' + (i % 10);
    }

    while (1) {
        ret = sendto(sockfd, buff, BUFSIZE + 25, 0, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
        if (ret < 0) {
            perror("Send error");
            goto exit2;
        } else {
            printf("sendto data successfully\n");
        }
        sleep(2);
    }

exit2:
    close(sockfd);

    return  (0);
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值