Search code examples
csocketsethernetraw-ethernet

raw socket send two packets on a virtual Network


I've a problem with my sendto function in my code, when I try to send a raw ethernet packet.

I use a Ubuntu 12.04.01 LTS, with two tap devices connected over two vde_switches and a dpipe

Example:

my send programm create the packet like below, the programm is binded by the socket from tap0 and send the packet to tap1. On tap1 one receiver wait for all packets on socket.

My raw ethernet packet looks so:

destination Addr ____source Addr _________ type/length ___data

00:00:01:00:00:00___00:00:01:00:00:01____ length in Byte__some data

Example packet to send:

00:00:01:00:00:00 00:00:01:00:00:01 (length in byte) (Message)test

but my programm generate two packets, when I look in wireshark:

first packet is an IPX packet and [Malformed Packet] and looks like in hex (data = test)

00 04 00 01 00 06 00 00 01 00 00 01 00 00 00 01 74 65 73 74 00

Linux cooked capture

Packet type: sent by us (4)

Link-layer address type: 1

Link-layer address length: 6

Source: 00:00:01:00:00:01

Protocol: Raw 802.3 (0x0001)

[Malformed Packet: IPX]

second packet unknown protocol

00 00 00 01 00 06 00 00 01 00 00 01 00 00 31 00 74 65 73 74 00

Linux cooked capture

Packet type: Unicast to us (0)

Link-layer address type: 1

Link-layer address length: 6

Source: 00:00:01:00:00:01

Protocol: Unknown (0x3100)

Data

Data: 7465737400

[Length: 5]

outcut from my source code

sock_desc = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));


/*struct for sending*/
    sock_addr.sll_family = AF_PACKET;
    sock_addr.sll_protocol = htons(ETH_P_802_3);
    sock_addr.sll_ifindex = if_nametoindex(argv[1]);
    sock_addr.sll_hatype = ARPHRD_ETHER; //Ethernet 10Mbps
    sock_addr.sll_pkttype = PACKET_HOST; // Paket zu irgendjemand
    sock_addr.sll_halen = ETH_ALEN; //6 Oktets in einer ethernet addr
    /*MAC Length 8 Oktets*/
    sock_addr.sll_addr[0] = frame.src_mac[0];
    sock_addr.sll_addr[1] = frame.src_mac[1];
    sock_addr.sll_addr[2] = frame.src_mac[2];
    sock_addr.sll_addr[3] = frame.src_mac[3];
    sock_addr.sll_addr[4] = frame.src_mac[4];
    sock_addr.sll_addr[5] = frame.src_mac[5];
    /*not in use*/  
    sock_addr.sll_addr[6] = 0x00;
    sock_addr.sll_addr[7] = 0x00;

    memset(buffer, '0', sizeof(char)*ETH_FRAME_LEN);
    /*set the frame header*/

    /*build RAW Ethernet packet*/
    buffer[0] = frame.dest_mac[0];
    buffer[1] = frame.dest_mac[1];
    buffer[2] = frame.dest_mac[2];
    buffer[3] = frame.dest_mac[3];
    buffer[4] = frame.dest_mac[4];
    buffer[5] = frame.dest_mac[5];

    buffer[6] = frame.src_mac[0];
    buffer[7] = frame.src_mac[1];
    buffer[8] = frame.src_mac[2];
    buffer[9] = frame.src_mac[3];
    buffer[10] = frame.src_mac[4];
    buffer[11] = frame.src_mac[5];

    while(frame.data[0] != '*'){
      printf("Input: ");
      scanf("%s", frame.data);

      tempLength = 0;
      while(frame.data[tempLength] != '\0'){
      tempLength++;
      }
      input = 0;
      for(sendLen = 14;sendLen <= (14+tempLength);sendLen++){
          buffer[sendLen] = frame.data[input];
          input++;
      }

      sprintf(convLen,"%x", (14 + input));
      buffer[12] = convLen[0];
      buffer[13] = convLen[1];

      length_in_byte = sendto(sock_desc, buffer, 14+input,0,(struct sockaddr*) &sock_addr,sizeof(struct sockaddr_ll));
      if(length_in_byte <= 0){
        printf("Error beim Senden");
      }else{
            printf("\n");
            printf("src: %02x:%02x:%02x:%02x:%02x:%02x\t->\tdest: %02x:%02x:%02x:%02x:%02x:%02x\n",frame.src_mac[0],frame.src_mac[1],frame.src_mac[2],frame.src_mac[3],frame.src_mac[4],frame.src_mac[5],frame.dest_mac[0],frame.dest_mac[1],frame.dest_mac[2],frame.dest_mac[3],frame.dest_mac[4],frame.dest_mac[5]);
            printf("Data: %s\n", frame.data);
      }
  }

please i need some help to find my mistake.

Thank you forward.


Solution

  • OK I see why my receiver receiv two packets. The first packet ist the send by us packet and the second is the Unicast to us. The problem I don't need the first packet to receive. I have test my code and have one capture with the two packets as example.

    First frame in hex code from Wireshark:

    0004 0001 0006 0000010000020000 0060 the message
    

    Second frame:

    0000 0001 0006 0000010000020000 1234 the message
    

    This is Linux cooked capture an means:

    2 Bytes packet typ // 0 = To us; 1 = Broadcast; 2 = Multicast; 3 = from somebody to somebody; 4 = sent by us
    
    2 Bytes LINUX ARPHDR_ value
    2 Bytes Link layer addr. lenght
    8 Bytes source address
    2 Bytes Ethernet protocol //e.g. 1 Novell 802.3 without 802.2 header; 4 frames with 802.2 header
    

    My questions:

    First is it possible to filter or ignore the first packet?

    Second why contains the first packet the protocol typ from the send structur and the second packet the protocol typ from buffer?

    Example:

    For the first packet

    sock_addr.sll_family = AF_PACKET;
    sock_addr.sll_protocol = htons(0x0060);
    sock_addr.sll_ifindex = 3;
    sock_addr.sll_hatype = ARPHRD_ETHER;
    sock_addr.sll_pkttype = PACKET_HOST;
    sock_addr.sll_halen = ETH_ALEN; 
    /*MAC Length 8 Oktets*/
    sock_addr.sll_addr[0] = 0x00;
    sock_addr.sll_addr[1] = 0x00;
    sock_addr.sll_addr[2] = 0x01
    sock_addr.sll_addr[3] = 0x00;
    sock_addr.sll_addr[4] = 0x00;
    sock_addr.sll_addr[5] = 0x02;
    /*not in use*/  
    sock_addr.sll_addr[6] = 0x00;
    sock_addr.sll_addr[7] = 0x00;
    

    for second packet the buffer like 802.3 frame

    buffer[0-5] = 0x00 0x00 0x01 0x00 0x00 0x03 // Destination address
    buffer[6-11] = 0x00 0x00 0x01 0x00 0x00 0x02 // Source address
    buffer[12-13] = 0x12 0x34 // Protocol dummy typ
    

    My receiver can capture the first packet without a connection between two vde_switches and when I connect the switches with dpipe and vde_plug can I capture the second packet too.