Freezedevil
Lieutenant
- Registriert
- Mai 2011
- Beiträge
- 640
Hi,
wie der Titel schon sagt habe ich ein kleines Problem beim lesen aus einem Raw Socket. Woher weiß ich denn wie groß das Paket ist, sodass ich weiß wie groß ich den Buffer wählen muss in den ich das Paket lese.
Ich hab mir das eigentlich so vorgestellt:
Ich lese den IP und und TCP Header ein. Dem IP Header kann ich dem tot_len Feld die Größe des Paket entnehmen. So weiß ich wie viel ich noch lesen muss.
Leider funktioniert das so nicht wie ich mir das vorstelle. Was muss ich denn ändern um das Paket korrekt einzulesen.
Beim Senden habe ich als Nutzlast einfach nen unsigned int drangehangen, weshalb ich hier einfach 4 Byte zusätzlich lese.
Kann man, wenn wir einmal dabei sind, die Überprüfung der IP Adresse noch etwas eleganter gestalten?
Edit: OS ist Ubuntu, falls das noch von Relevanz ist.
wie der Titel schon sagt habe ich ein kleines Problem beim lesen aus einem Raw Socket. Woher weiß ich denn wie groß das Paket ist, sodass ich weiß wie groß ich den Buffer wählen muss in den ich das Paket lese.
Ich hab mir das eigentlich so vorgestellt:
Ich lese den IP und und TCP Header ein. Dem IP Header kann ich dem tot_len Feld die Größe des Paket entnehmen. So weiß ich wie viel ich noch lesen muss.
Leider funktioniert das so nicht wie ich mir das vorstelle. Was muss ich denn ändern um das Paket korrekt einzulesen.
Beim Senden habe ich als Nutzlast einfach nen unsigned int drangehangen, weshalb ich hier einfach 4 Byte zusätzlich lese.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
int main(void) {
int sock, uid;
unsigned int hdrsize = sizeof(struct iphdr) + sizeof(struct tcphdr);
unsigned char packet[hdrsize+4];
struct iphdr* ip = (struct iphdr*)packet;
struct tcphdr* tcp = (struct tcphdr*)(packet + sizeof(struct iphdr));
unsigned int* payload = (unsigned int*)(packet + hdrsize);
int one = 1;
uid = getuid();
if (uid) {
printf("You must be root!\n");
exit(1);
}
if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) == -1) {
perror("socket");
exit(1);
}
if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &one, sizeof(one)) == -1) {
perror("setsockopt");
exit(1);
}
while(1) {
// Das funktioniert wunderbar, allerdings muss ich vorher wissen wie gross
// das Paket ist
/*
read(sock,packet,hdrsize+4);
if (strcmp(inet_ntoa(*(struct in_addr *)&ip->daddr), "127.0.0.1")==0
&& ntohs(tcp->dest)==23) {
printf("syn: %d\tack: %d\tpayload: %d\n", tcp->syn, tcp->ack, *payload);
}
*/
// Das funktioniert leider nicht. Wie muss ich den Code anpassen, damit das
// so laeuft wie ich mir das vorstelle?
read(sock,ip,hdrsize);
if (strcmp(inet_ntoa(*(struct in_addr *)&ip->daddr), "127.0.0.1")==0
&& ntohs(tcp->dest)==23) {
printf("syn: %d\tack: %d\n", tcp->syn, tcp->ack);
read(sock,payload,4);
printf("payload:%u\n", *payload);
}
}
return 0;
}
Kann man, wenn wir einmal dabei sind, die Überprüfung der IP Adresse noch etwas eleganter gestalten?
Edit: OS ist Ubuntu, falls das noch von Relevanz ist.
Zuletzt bearbeitet: