Sockets bruts sur les systèmes d’exploitation BSD

J’ai écrit un code de socket en C. J’ai besoin de modifier les en-têtes de paquet et de contrôler la façon dont ils sont envoyés. J’ai donc adopté l’approche des sockets brutes. Cependant, le code que j’ai écrit ne sera pas compilé sur les systèmes BSD (Mac OS X / Darwin, FreeBSD, etc.)

J’ai effectué de nombreuses recherches à ce sujet et constaté que les systèmes BSD ne peuvent pas gérer les sockets bruts comme Linux (ou même Windows). D’après ce que j’ai lu, il semble que j’ai besoin d’utiliser bpf (filtre de paquets berkley), mais je ne peux pas comprendre comment fonctionne bpf ni comment l’utiliser avec des sockets bruts.

Si quelqu’un pouvait faire la lumière sur celui-ci, je serais très excité: D

PS: je serai même satisfait de certains codes source montrant comment les sockets bruts sont gérés dans un environnement BSD. Cela n’a pas besoin d’être un guide ou une explication. Je veux juste voir comment ça marche.

Utiliser des sockets raw n’est pas difficile, mais ce n’est pas entièrement portable. Par exemple, sous BSD et sous Linux, vous pouvez envoyer ce que vous voulez, mais sous BSD, vous ne pouvez rien recevoir avec un gestionnaire (comme TCP et UDP ).

Voici un exemple de programme qui envoie un SYN .

 #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  int main(int argc, char *argv[]) { int s, rc; struct protoent *p; struct sockaddr_in sin; struct tcphdr tcp; if (argc != 2) errx(EX_USAGE, "%s addr", argv[0]); memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = 0; /* Parse command line address. */ if (inet_pton(AF_INET, argv[1], &sin.sin_addr) <= 0) err(EX_USAGE, "Parse address"); /* Look up tcp although it's 6. */ p = getprotobyname("tcp"); if (p == NULL) err(EX_UNAVAILABLE, "getprotobyname"); /* Make a new shiny (Firefly) socket. */ s = socket(AF_INET, SOCK_RAW, p->p_proto); if (s < 0) err(EX_OSERR, "socket"); memset(&tcp, 0, sizeof(tcp)); /* Fill in some random stuff. */ tcp.th_sport = htons(4567); tcp.th_dport = htons(80); tcp.th_seq = 4; /* Chosen by fair dice roll. */ tcp.th_ack = 0; tcp.th_off = 5; tcp.th_flags = TH_SYN; tcp.th_win = htonl(65535); rc = sendto(s, &tcp, sizeof(tcp), 0, (struct sockaddr *)&sin, sizeof(sin)); printf("Wrote %d bytes\n", rc); return 0; } 

Bien entendu, davantage de solutions spécifiques à BSD sont disponibles. Par exemple, vous pouvez utiliser divert(4) pour intercepter les paquets lorsqu'ils traversent votre système et les modifier.