Как я могу отправить дейтаграмму с трейлером Ethernet? - PullRequest
6 голосов
/ 07 августа 2010

Как я могу отправить дейтаграмму с трейлером Ethernet? Если я использую SocketType.Raw, мне нужно будет отправить весь заголовок IP, и я не знаю, как это сделать.

Ответы [ 2 ]

2 голосов
/ 13 августа 2010

Возможно, что-то подобное?

#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 с нулями в конце, который несколько совпадает,наверное проще, дай мне знать.

2 голосов
/ 11 августа 2010

Этот трейлер используется для дополнения кадров Ethernet до их минимальной длины (46 байт полезной нагрузки). Поэтому отправьте небольшой пакет UDP - размером менее 18 байтов (поскольку IP + UDP обычно составляет 28 байтов)

...