Bonjour à tous,

Je viens vous voir aujourd'hui pour un petit problème au niveau de mon envoie de packet en C.

En suivant un exemple sur internet j'ai pu envoyer une trame EthernetII avec dans sont payload: "hello world".
Je veux maintenant envoyer une requête ARP mais je ne sais pas comment encapsuler l'ARP dans l'ethernetII, faut-il juste le mettre dans le payload?

Je précise que je ne peut pas utiliser une lib qui permet de créer des requête ARP car le but final de mon programme est d'avoir un forgeur de trame pour a peut près tous les protocole (même protocole de routage)

mon cote actuel:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>    /* Must precede if*.h */
#include <linux/if.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <unistd.h>
 
union ethframe
{
  struct
  {
    struct ethhdr    header;
    unsigned char    data[ETH_DATA_LEN];
  } field;
  unsigned char    buffer[ETH_FRAME_LEN];
};
 
int main(int argc, char **argv) {
  char *iface = "wlan0";
  unsigned char dest[ETH_ALEN]
           = { 0x62, 0xF1, 0x89, 0x75, 0x36, 0xEA }; // 62:F1:89:75:36:EA
  unsigned short proto = 0x0806;
  //unsigned char *data = "hello world";
  //unsigned short data_len = strlen(data);
 
 
  int s;
  if ((s = socket(AF_PACKET, SOCK_RAW, htons(proto))) < 0) {
    printf("Error: could not open socket\n");
    return -1;
  }
 
  struct ifreq buffer;
  int ifindex;
  memset(&buffer, 0x00, sizeof(buffer));
  strncpy(buffer.ifr_name, iface, IFNAMSIZ);
  if (ioctl(s, SIOCGIFINDEX, &buffer) < 0) {
    printf("Error: could not get interface index\n");
    close(s);
    return -1;
  }
  ifindex = buffer.ifr_ifindex;
 
  unsigned char source[ETH_ALEN];
  if (ioctl(s, SIOCGIFHWADDR, &buffer) < 0) {
    printf("Error: could not get interface address\n");
    close(s);
    return -1;
  }
  memcpy((void*)source, (void*)(buffer.ifr_hwaddr.sa_data),
         ETH_ALEN);
 
  union ethframe frame;
  memcpy(frame.field.header.h_dest, dest, ETH_ALEN);
  memcpy(frame.field.header.h_source, source, ETH_ALEN);
  frame.field.header.h_proto = htons(proto);
  //memcpy(frame.field.data, data, data_len);
 
  unsigned short ARP_data = 0x0001;
  unsigned short ARP_data1 = 0x0800;
  unsigned char ARP_data2 = 0x06;
  unsigned char ARP_data3 = 0x04;
  unsigned short ARP_data4 = 0x0001;
 
  unsigned char *ARP_srcMAC = {0xf0, 0x82, 0x61, 0xee, 0x9e, 0x44};
  unsigned char *ARP_srcIP = {0xc0, 0xa8, 0x01, 0x01};
  unsigned char *ARP_dstMAC = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  unsigned char *ARP_dstIP = {0xc0, 0xa8, 0x01, 0x0b};
 
  unsigned char *ARP_fullData = (char *) malloc(sizeof(char) * 28);
 
 
  memcpy(ARP_fullData, &ARP_data, 2);
  memcpy(ARP_fullData+2, &ARP_data1, 2);
  memcpy(ARP_fullData+4, &ARP_data2, 1);
  memcpy(ARP_fullData+5, &ARP_data3, 1);
  memcpy(ARP_fullData+6, &ARP_data4, 2);
  memcpy(ARP_fullData+8, &ARP_srcMAC, 6);
  memcpy(ARP_fullData+14, &ARP_srcIP, 4);
  memcpy(ARP_fullData+18, &ARP_dstMAC, 6);
  memcpy(ARP_fullData+24, &ARP_dstIP, 4);
 
 
  for(int i=0; i< 25; i++)
  {
	  printf("%02X ", ARP_fullData[i]);
  }
 
 
  unsigned int frame_len = ETH_HLEN + 28;
 
  struct sockaddr_ll saddrll;
  memset((void*)&saddrll, 0, sizeof(saddrll));
  saddrll.sll_family = PF_PACKET;   
  saddrll.sll_ifindex = ifindex;
  saddrll.sll_halen = ETH_ALEN;
  memcpy((void*)(saddrll.sll_addr), (void*)dest, ETH_ALEN);
 
  if (sendto(s, frame.buffer, frame_len, 0,
             (struct sockaddr*)&saddrll, sizeof(saddrll)) > 0)
    printf("Success!\n");
  else
    printf("Error, could not send\n");
 
  close(s);
 
  return 0;
}
Avec ce code, je me retrouve avec un malformed packet sur Wireshark, de plus la sortie console du printf n'a pas le résultat escompté: 01 00 00 08 06 04 01 00 F0 00 00 00 00 00 C0 00 00 00 00 00 00 00 00 00 C0

Si vous avez une idée concernant mes différente question je vous en remercie par avance