selbst gebastelte IP-Pakete versenden.



  • Hallo!

    Ich schreibe gerade eine TCP/IP-Stack für einen Mikrocontroller (in C). Da ich den der Einfachheit halber auf meinem PC testen möchte, würde ich gerne wissen wie ich meine selbst gebastelte IP-Pakete versende. Geht das überhaupt?

    Danke im Voraus.



  • Raw-sockets ist glaube ich das was Du suchst. So spontan hat google das ausgespuckt: http://linux.sys-con.com/read/34589_1.htm. Ansonsten ist Linux open-source. Da lohnt ein Blick in den Source von entsprechenden Programmen wie z. B. hping.

    Tntnet



  • Vielen Dank für den Tipp! Es funktioniert!



  • Doch nicht. 😞
    Das Versenden von Paketen klappt zwar wunderbar, aber beim Empfang bleibt er bei read hängen:

    #include <stdio.h> /* printf */
    #include <stdlib.h> /* malloc, realloc */
    #include <sys/socket.h> /* socket, setsockopt, sendto */
    #include <arpa/inet.h> /* IPPROTO_RAW IP_HDRINCL */
    #include <unistd.h> /* read, write */
    #include "ip.h" /* MY_IP */
    #include "test.h"
    
    int sd;
    struct sockaddr_in sa;
    
    void test_init()
    {
      const int one = 1;
    
      sd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
      if(sd < 0)
        {
          perror("socket");
          exit(1);
        }
    
      if(setsockopt(sd, IPPROTO_IP, IP_HDRINCL, (char*)&one, sizeof(one)) < 0)
        {
          perror("setsockopt");
          exit(1);
        }
    
      sa.sin_family = AF_INET;
      sa.sin_addr.s_addr = MY_IP;
    }
    
    void test_clear()
    {
      close(sd);
    }
    
    void test_send(struct packet_t *packet)
    {
      if(sendto(sd, packet->contents, packet->length, 0,
    	    (struct sockaddr *) &sa, sizeof (sa)) < 0)
        {
          perror("sendto");
          exit(1);
        }
    }
    
    struct packet_t *test_receive()
    {
      struct packet_t *packet = malloc(sizeof(struct packet_t));
      packet->length = 32768;
      packet->contents = malloc(packet->length);
      packet->length = read(sd, packet->contents, packet->length); /* <- hier */
      packet->contents = realloc(packet->contents, packet->length);
      return packet;
    }
    


  • recvfrom?



  • Mit recvfrom kann ich auch nichts empfangen:

    #include <stdio.h> /* perror */
    #include <stdlib.h> /* malloc, realloc */
    #include <sys/socket.h> /* socket, setsockopt, sendto */
    #include <arpa/inet.h> /* IPPROTO_* IP_HDRINCL */
    #include <unistd.h> /* close */
    #include "test.h"
    
    int sd;
    struct sockaddr_in host;
    struct sockaddr_in remote;
    socklen_t rlen = sizeof(struct sockaddr_in);
    
    void test_init()
    {
      const int one = 1;
    
      sd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
      if(sd < 0)
        {
          perror("socket");
          exit(1);
        }
    
      if(setsockopt(sd, IPPROTO_IP, IP_HDRINCL, (char*)&one, sizeof(one)) < 0)
        {
          perror("setsockopt");
          exit(1);
        }
    }
    
    void test_clear()
    {
      close(sd);
    }
    
    void test_send(struct packet_t *packet)
    {
      if(sendto(sd, packet->contents, packet->length, 0,
            (struct sockaddr *) &host, sizeof (host)) < 0)
        {
          perror("sendto");
          exit(1);
        }
    }
    
    struct packet_t *test_receive()
    {
      struct packet_t *packet = malloc(sizeof(struct packet_t));
      packet->length = 32768;
      packet->contents = malloc(packet->length);
      packet->length = recvfrom(sd, packet->contents, packet->length, 0,
    			    (struct sockaddr *) &remote, &rlen);
      packet->contents = realloc(packet->contents, packet->length);
      return packet;
    }
    

    Aber es geht wenn ich socket das verwendete Protokoll mitteile, also z.B. so:

    socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
    

    Dann kann ich aber nichts anderes mehr empfangen.

    Wieso kann ich mit IPPROTO_RAW nichts empfangen? Senden funktioniert doch bestens. 😕



  • Üser schrieb:

    Wieso kann ich mit IPPROTO_RAW nichts empfangen?

    man 7 raw schrieb:

    When a packet is received, it is passed to any raw sockets which have been bound to its protocol before it is passed to other protocol handlers (e.g. kernel protocol modules).

    Vielleicht bist du mit einem tap-device besser dran: https://cccac.de/cgi-bin/wiki.pl?TapDeviceBeispiel


Anmelden zum Antworten