syn segmento protocolo c tcp packet packet-capture packet-sniffers

segmento - tcp syn



AnĂ¡lisis de datos de un paquete TCP (1)

Estoy tratando de analizar un paquete tcp y luego asignarle un puntero al inicio de la carga útil.

Estoy usando C y este es mi código hasta ahora:

void dump(const unsigned char *data, int length) { //*data contains the raw packet data unsigned int i; static unsigned long pcount = 0; // Decode Packet Header struct ether_header *eth_header = (struct ether_header *) data; printf("/n/n === PACKET %ld HEADER ===/n", pcount); printf("/nSource MAC: "); for (i = 0; i < 6; ++i) { printf("%02x", eth_header->ether_shost[i]); //? Why don''t i use nthos here? if (i < 5) printf(":"); } unsigned short ethernet_type = ntohs(eth_header->ether_type); printf("/nType: %hu/n", ethernet_type); if (ethernet_type == ETHERTYPE_IP) { //IP Header printf("/n == IP HEADER ==/n"); struct ip *ip_hdr = (struct ip*) data + sizeof(struct ether_header); unsigned int size_ip = ip_hdr->ip_hl * 4; printf("/nIP Version: %u", ip_hdr->ip_v); //? Nthos or no nthos printf("/nHeader Length: %u", ip_hdr->ip_hl); //? Nthos or no nthos printf("/nTotal Length: %hu", ntohs(ip_hdr->ip_len)); //? Nthos or no nthos // TCP Header printf("/n== TCP HEADER ==/n"); struct tcphdr *tcp_hdr = (struct tcphdr*) data + sizeof(struct ether_header) + size_ip; printf("/n Source Port: %" PRIu16, nthos(tcp_hdr->th_sport)); printf("/n Destination Port: %" PRIu16, nthos(tcp_hdr->th_dport)); printf("/n fin: %" PRIu16, tcp_hdr->fin); printf("/n urg: %" PRIu16, tcp_hdr->urg); printf("/n ack_seq: %" PRIu32, ntohl(tcp_hdr->ack_seq)); //Transport payload! i.e. rest of the data const unsigned char *payload = data + ETH_HLEN + size_ip + sizeof(struct tcphdr) + tcp_hdr->doff; }

Estoy seguro de que hay errores en este código porque los números de los puertos son raros. Ni uno solo se asigna a 80. La versión de Ip emitida también puede ser realmente extraña (como la versión 11) también. ¿Qué estoy haciendo mal? ¡Gracias!

Además, no estoy seguro de cuándo usar nthos y cuándo no. Sé que nthos es un entero sin signo de 16 bits y sé que nthol es para enteros sin signo de 32 bits, pero soy consciente de que no pretendes usarlos para todo en esos paquetes (como: tcp_hdr-> fin). ¿Por qué ciertas cosas y no ellas?

¡MUCHAS GRACIAS!

EDITAR:

Gracias Art por arreglar la mayoría de los problemas. ¡Edité mi tcp_hdr y ip_hdr para que los corchetes ahora sean correctos!

Todavía tengo 2 problemas:

  • Los primeros 10 bytes de la carga tienen símbolos extraños (así que creo que no he asignado la carga útil correctamente).
  • Todavía no estoy seguro de cuándo usar nthos / nthol. Sé que u_int16_t es ntohs y u_int32_t es ntohl. Pero, ¿qué pasa con las cosas que están firmadas int o unisgned short int? Por ejemplo, no usé ntohs o nthol para que ip_v funcione. Por qué no? Es "ip_hdr-> ip_hl" nthol? etc ...

EDIT2

He solucionado el motivo por el que mi carga útil no se enviaba correctamente (es porque calculé incorrectamente el tamaño de la cabecera TCP).

Aunque todavía estoy confundido acerca de cuándo usar nthos, lo plantearé como una pregunta separada, ¡ya que creo que hice demasiadas preguntas sobre esta 1 publicación!

¿Cuándo usar ntohs y ntohl en C?


Lo más probable es que su problema esté aquí:

struct ip *ip_hdr = (struct ip*) data + sizeof(struct ether_header); struct tcphdr *tcp_hdr = (struct tcphdr*) data + sizeof(struct ether_header) + size_ip;

Hacer (struct ip*) data + sizeof(struct ether_header) primero arroja datos a struct ip * , luego agrega sizeof(struct ether_header) a él, lo que sabemos por puntero arithmetics no hará lo que espera que haga.

Si el problema aún no está claro, aquí hay un programa simple que debe orientarlo en la dirección correcta:

#include <stdio.h> struct foo { int a, b; }; int main(int argc, char **argv) { char *x = NULL; printf("%p/n", x); printf("%p/n", (struct foo *)x + 4); printf("%p/n", (struct foo *)(x + 4)); return 0; }