如何使用以太网预告片发送数据报?

时间:2010-08-07 12:03:41

标签: networking ethernet

如何使用以太网预告片发送数据报?如果我使用SocketType.Raw,我将不得不发送整个IP头,我不知道该怎么做。

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:2)

或许这样的事情?

#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或类似的东西,你可以使用这个方法并自己构建头文件(这很简单看一下rfcs或者只是使用wireshark查看一堆其他的包头) 。请注意,对于udp,您不必计算校验和0x0000是一个应该传递的有效校验和。

如果你想要的只是一个udp数据包,最后的零点有点相同,可能更容易,请告诉我。