如何使用以太网拖车发送数据报?

发布于 2024-09-13 16:18:14 字数 68 浏览 1 评论 0原文

如何使用以太网拖车发送数据报?如果我使用 SocketType.Raw,我将必须发送整个 IP 标头,但我不知道该怎么做。

How can I send a datagram with an Ethernet trailer? If I use SocketType.Raw, I'll have to send the whole IP header and I have no idea how to do that.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

清晰传感 2024-09-20 16:18:14

也许是这样的?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <unistd.h>

#include <sys/socket.h>
#include <linux/if_packet.h>
#include <linux/if_ether.h>
#include <linux/if_arp.h>

#include <sys/ioctl.h>

int s;

unsigned char buffer[513];

struct sockaddr_ll socket_address;

int main ( void )
{
    unsigned char seq;
    unsigned int ra;
    int length;
    struct ifreq ifr;

    s = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
    if (s == -1)
    {
        printf("error creating socket\n");
        return(1);
    }

    memset(&ifr,0, sizeof(struct ifreq));
    strncpy(ifr.ifr_name,"eth0",IFNAMSIZ);
    if(ioctl(s, SIOCGIFINDEX, &ifr) < 0)
    {
        perror("ioctl SIOCGIFINDEX");
        exit(1);
    }

    printf("index %d\n",ifr.ifr_ifindex);


    printf("socket created\n");

    memset(&socket_address,0,sizeof(socket_address));

    socket_address.sll_family = PF_PACKET;
    socket_address.sll_protocol = htons(ETH_P_ALL);
    socket_address.sll_ifindex = ifr.ifr_ifindex;

    if (bind(s, (struct sockaddr *)(&socket_address), sizeof(socket_address)) < 0)
    {
        perror("bind error");
        exit(1);
    }

    printf("bound\n");

    length=27;

    memset(buffer,0,sizeof(buffer));
//destination
    buffer[ 0]=0xFF;
    buffer[ 1]=0xFF;
    buffer[ 2]=0xFF;
    buffer[ 3]=0xFF;
    buffer[ 4]=0xFF;
    buffer[ 5]=0xFF;
//source
    buffer[ 6]=0x00;
    buffer[ 7]=0x19;
    buffer[ 8]=0xd1;
    buffer[ 9]=0x02;
    buffer[10]=0xdc;
    buffer[11]=0xb3;
//length
    buffer[12]=((length-14)>>8)&0xFF;
    buffer[13]=((length-14)>>0)&0xFF;
//payload
    buffer[14]=0x12;
    buffer[15]=0x34;

    for(ra=0;ra<20;ra++)
    {
        buffer[16]=ra;
        if(send(s,buffer,length,0) < 0 )
        {
            printf("sendto failed\n");
            break;
        }
        else
        {
            printf("sent\n");
        }
    }

    close(s);
    return(1);

}

这应该会给出一个原始数据包,您可以在wireshark上看到它。如果您想要 ip eader,或者将其设为 udp 或类似的东西,您可以使用此方法并自己构建标头(查看 rfc 很简单,或者只需使用wireshark 查看一堆其他数据包标头) 。请注意,对于 udp,您不必计算校验和 0x0000 是应该传递的有效校验和。

如果您想要的只是一个末尾带有零的 udp 数据包,该数据包有点相同,可能更容易,请告诉我。

Something like this perhaps?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <unistd.h>

#include <sys/socket.h>
#include <linux/if_packet.h>
#include <linux/if_ether.h>
#include <linux/if_arp.h>

#include <sys/ioctl.h>

int s;

unsigned char buffer[513];

struct sockaddr_ll socket_address;

int main ( void )
{
    unsigned char seq;
    unsigned int ra;
    int length;
    struct ifreq ifr;

    s = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
    if (s == -1)
    {
        printf("error creating socket\n");
        return(1);
    }

    memset(&ifr,0, sizeof(struct ifreq));
    strncpy(ifr.ifr_name,"eth0",IFNAMSIZ);
    if(ioctl(s, SIOCGIFINDEX, &ifr) < 0)
    {
        perror("ioctl SIOCGIFINDEX");
        exit(1);
    }

    printf("index %d\n",ifr.ifr_ifindex);


    printf("socket created\n");

    memset(&socket_address,0,sizeof(socket_address));

    socket_address.sll_family = PF_PACKET;
    socket_address.sll_protocol = htons(ETH_P_ALL);
    socket_address.sll_ifindex = ifr.ifr_ifindex;

    if (bind(s, (struct sockaddr *)(&socket_address), sizeof(socket_address)) < 0)
    {
        perror("bind error");
        exit(1);
    }

    printf("bound\n");

    length=27;

    memset(buffer,0,sizeof(buffer));
//destination
    buffer[ 0]=0xFF;
    buffer[ 1]=0xFF;
    buffer[ 2]=0xFF;
    buffer[ 3]=0xFF;
    buffer[ 4]=0xFF;
    buffer[ 5]=0xFF;
//source
    buffer[ 6]=0x00;
    buffer[ 7]=0x19;
    buffer[ 8]=0xd1;
    buffer[ 9]=0x02;
    buffer[10]=0xdc;
    buffer[11]=0xb3;
//length
    buffer[12]=((length-14)>>8)&0xFF;
    buffer[13]=((length-14)>>0)&0xFF;
//payload
    buffer[14]=0x12;
    buffer[15]=0x34;

    for(ra=0;ra<20;ra++)
    {
        buffer[16]=ra;
        if(send(s,buffer,length,0) < 0 )
        {
            printf("sendto failed\n");
            break;
        }
        else
        {
            printf("sent\n");
        }
    }

    close(s);
    return(1);

}

That should give a raw packet that you can see on wireshark. if you want to have the ip eader, or make it a udp or something like that you can use this method and build the header yourself (it is trivial look at the rfcs or just use wireshark to look at a bunch of other packet headers). Note that for udp you do not have to compute a checksum 0x0000 is a valid checksum that is supposed to pass on through.

If all you want is a udp packet with zeros at the end that is somewhat the same, probably easier, let me know.

玩世 2024-09-20 16:18:14

该尾部用于将以太网帧填充到其最小长度(46 字节的有效负载)。因此发送一个小的 UDP 数据包 - 小于 18 字节(因为 IP + UDP 通常为 28 字节)

That trailer is used to pad ethernet frames to their minimum length (46 bytes of payload). So send a small UDP packet - smaller than 18 bytes (as IP + UDP is normally 28 bytes)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文