C – Linux – module de kernel – en-tête TCP

J’essaie de créer un module de kernel Linux, qui inspectera les paquets entrants. Pour le moment, je suis en train d’extraire l’en-tête TCP du paquet et de lire le port source et le port de destination -> Cependant, je reçois des valeurs incorrectes. J’ai une fonction de crochet:

unsigned int hook_func(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { struct iphdr *ipp = (struct iphdr *)skb_network_header(skb); struct tcphdr *hdr; /* Using this to filter data from another machine */ unsigned long ok_ip = 2396891328; /* Some problem, empty network packet. Stop it now. */ if (!skb) return NF_ACCEPT; /* Just to track only packets coming from 1 IP */ if (ipp->saddr != ok_ip) return NF_ACCEPT; /* Incomming packet is TCP */ if (ipp->protocol == IPPROTO_TCP) { hdr = (struct tcphdr *) skb_transport_header(skb); printk(" TCP ports: source: %d, dest: %d .\n", ntohs(hdr->source), ntohs(hdr->dest)); } } 

Maintenant, quand j’essaye de mettre le port 21 telnet (je n’écoute pas, je reçois):

 [ 4252.961912] TCP ports: source: 17664, dest: 52 . [ 4253.453978] TCP ports: source: 17664, dest: 52 . [ 4253.953204] TCP ports: source: 17664, dest: 48 . 

Et quand je telnet le port 22 – SSH Deamon écoute là:

 [ 4299.239940] TCP ports: source: 17664, dest: 52 . [ 4299.240527] TCP ports: source: 17664, dest: 40 . [ 4299.552566] TCP ports: source: 17664, dest: 40 . 

Comme on peut le voir d’après les résultats, les résultats sont très étranges. Quelqu’un a-t-il une idée de l’origine du problème? lorsque je comstack le module, je n’ai aucune erreur / avertissement. Version du kernel (en-têtes): 3.7.10. Ne pas utiliser SELinux ou similaire.

J’ai eu le même problème en écrivant un petit pare-feu pour une classe de réseautage, je viens de découvrir le problème que je rencontrais. Je jetais mal l’en-tête TCP. Essayez de lancer tcp, puis accédez au port.

Voici un extrait de code de son fonctionnement

 struct iphdr *ip_header; // ip header struct struct tcphdr *tcp_header; // tcp header struct struct udphdr *udp_header; // udp header struct struct sk_buff *sock_buff; unsigned int sport , dport; sock_buff = skb; if (!sock_buff) return NF_ACCEPT; ip_header = (struct iphdr *)skb_network_header(sock_buff); if (!ip_header) return NF_ACCEPT; //if TCP PACKET if(ip_header->protocol==IPPROTO_TCP) { //tcp_header = (struct tcphdr *)skb_transport_header(sock_buff); //doing the cast this way gave me the same problem tcp_header= (struct tcphdr *)((__u32 *)ip_header+ ip_header->ihl); //this fixed the problem sport = htons((unsigned short int) tcp_header->source); //sport now has the source port dport = htons((unsigned short int) tcp_header->dest); //dport now has the dest port } 

Pour obtenir l’en-tête IP ou TCP à partir d’un tampon de socket ( skb ), appliquez simplement les fonctions ip_hdr(skb) et tcp_hdr(skb) .