Raw-Socket-Linux-senden/empfangen ein Paket

Haben einige Probleme beim empfangen von Paketen.
Ich kann empfangen und Lesen eingehende Pakete, aber ich denke, dass ich nicht bekommen, ein handshake mit dem host.
Ich will nur ein Paket zu senden, um eine remote-computer mit einem offenen port auf eine Antwort zu bekommen, um zu sehen, wie die TTL(time-to-live) und die Größe des Fensters.
Hat jemand eine Idee, wo die Fehler sind? (ich habe nicht sehr Tiefe Kenntnisse in C-Programmierung)

CODE:

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <errno.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <net/ethernet.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>

struct pseudohdr {
    u_int32_t src_addr;
    u_int32_t dst_addr;
    u_int8_t padding;
    u_int8_t proto;
    u_int16_t length;
};

struct data_4_checksum {
    struct pseudohdr pshd;
    struct tcphdr tcphdr;
    char payload[1024];
};
unsigned short comp_chksum(unsigned short *addr, int len) {
    long sum = 0;

    while (len > 1) {
        sum += *(addr++);
        len -= 2;
    }

    if (len > 0)
        sum += *addr;

    while (sum >> 16)
        sum = ((sum & 0xffff) + (sum >> 16));

    sum = ~sum;

    return ((u_short) sum);

}

int main(int argc, char *argv[]) {

    int sock, bytes, on = 1;
    char buffer[1024];
    struct iphdr *ip;
    struct tcphdr *tcp;
    struct sockaddr_in to;
    struct pseudohdr pseudoheader;
    struct data_4_checksum tcp_chk_construct;

    if (argc != 2) {
        fprintf(stderr, "Usage: %s ", argv[0]);
        fprintf(stderr, "<dest-addr>\n");
        return 1;
    }

    sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
    if (sock == -1) {
        perror("socket() failed");
        return 1;
    }else{
        printf("socket() ok\n");
    }

    if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) == -1) {
        perror("setsockopt() failed");
        return 2;
    }else{
        printf("setsockopt() ok\n");
    }

    ip = (struct iphdr*) buffer;
    tcp = (struct tcphdr*) (buffer + sizeof(struct tcphdr));

    int iphdrlen = sizeof(struct iphdr);
    int tcphdrlen = sizeof(struct tcphdr);
    int datalen = 0;
    printf("Typecasting ok\n");

    ip->frag_off = 0;
    ip->version = 4;
    ip->ihl = 5;
    ip->tot_len = htons(iphdrlen + tcphdrlen);
    ip->id = 0;
    ip->ttl = 40;
    ip->protocol = IPPROTO_TCP;
    ip->saddr = inet_addr("192.168.165.135");
    ip->daddr = inet_addr(argv[1]);
    ip->check = 0;

    tcp->source     = htons(12345);
    tcp->dest       = htons(80);
    tcp->seq        = random();
    tcp->doff       = 5;
    tcp->ack        = 0;
    tcp->psh        = 0;
    tcp->rst        = 0;
    tcp->urg        = 0;
    tcp->syn        = 1;
    tcp->fin        = 0;
    tcp->window     = htons(65535);

    pseudoheader.src_addr = ip->saddr;
    pseudoheader.dst_addr = ip->daddr;
    pseudoheader.padding = 0;
    pseudoheader.proto = ip->protocol;
    pseudoheader.length = htons(tcphdrlen + datalen);

    tcp_chk_construct.pshd = pseudoheader;
    tcp_chk_construct.tcphdr = *tcp;

    int checksum = comp_chksum((unsigned short*) &tcp_chk_construct,
            sizeof(struct pseudohdr) + tcphdrlen + datalen);

    tcp->check = checksum;

    printf("TCP Checksum: %i\n", checksum);
    printf("Destination : %i\n", ntohs(tcp->dest));
    printf("Source: %i\n", ntohs(tcp->source));

    to.sin_addr.s_addr = ip->daddr;
    to.sin_family = AF_INET;
    to.sin_port = tcp->dest;

    bytes = sendto(sock, buffer, ntohs(ip->tot_len), 0, (struct sockaddr*) &to,
            sizeof(to));

    if (bytes == -1) {
        perror("sendto() failed");
        return 1;
    }

    recv(sock, buffer, sizeof(buffer), 0);
    printf("TTL= %d\n", ip->ttl);
    printf("Window= %d\n", tcp->window);
    printf("ACK= %d\n", tcp->ack);
    printf("%s:%d\t --> \t%s:%d \tSeq: %d \tAck: %d\n",
                    inet_ntoa(*(struct in_addr*) &ip->saddr), ntohs(tcp->source),
                    inet_ntoa(*(struct in_addr *) &ip->daddr), ntohs(tcp->dest),
                    ntohl(tcp->seq), ntohl(tcp->ack_seq));

    return 0;
}
  • mit eingehende Pakete, die ich meine, gibt es andere eingehende von überall, aber nicht aus ich brauche
  • warum analysiert das Paket? ich habe versucht, einige Antwort auf eine saubere unix-Maschine unter vmware. wenn ich verschickte ein Paket manuell, ich habe, was ich brauche. aber wenn ich einfach warte, passiert nichts. unter realen system gibt es Pakete herein. diese sind aber von woanders.
  • Ich habe gerade wieder gebucht, meine Kommentare als eine tatsächliche Antwort. Ich hoffe, Sie nicht mind.
  • Layer-2 => Daten-Link? Ich dachte für layer-2-es gibt packet-sockets. In meinem code benutze ich festgelegten Zugriff auf den Puffer in der richtigen Weise. Und Sie bekommen nicht mein problem. Mein problem ist, dass ich bin empfangen von Paketen. Programm funktioniert, aber ich bin nicht eine Antwort auf mein Paket ich habe senden.
  • root@***:/********# ./OS_Sniffer 141.28.78.142
  • socket() ok setsockopt() ok Typecasting ok TCP-Prüfsumme: 350 Ziel : 80 Quelle: 12345 TTL= 52 Fenster= 31232 ACK= 1 67.228.168.221:80 --> 67.228.168.221:60806 Seq: -1525233884 Ack: -46020552
  • sorry, Tippfehler. Es ist Layer 3.
  • kein prob. bitte betrachten Sie die Ausgabe. es funktioniert, aber falsch 🙂
  • Ich sehe nicht, was falsch ist mit Ihrem Ausgang. Die negativen Werte? Drucken Sie mit dem unsigned-format-Bezeichner %u. Andere als die, könnte Sie hervorheben?
  • 67.228.168.221:80 --> 67.228.168.221:60806, Aber ich brauche etwas von 141.28.78.142
  • Ich bin das arbeiten mit C nur für wenige Wochen. Deshalb ist es etwas schwierig für mich
  • Verständlich, aber du machst das toll. Bitte, werfen Sie einen Blick auf Punkt 4 in meiner Antwort.

InformationsquelleAutor x4k3p | 2012-12-30
Schreibe einen Kommentar