Código con el que traté de implementarlo por mi cuenta:
Código
//http://www.arcesio.net/checksum/checksumTCP.html u_char* tcp_checksum(u_char* datos, int tamaño) { u_char checksum[2]; uint16_t sumando = 0, sumanda = 0; bitset<17> total; for (int i = 26; i < 33; i++)//del 26 al 33 ip origen y destino se suman { sumanda = (uint16_t)((datos[i] << 8) + datos[i + 1]); total = sumando + sumanda; sumando += sumanda; if (total[16] == 1)//al sumar sumanda a sumando acarrea bit. sumando++; i++; } sumanda = (uint16_t)(0x06);//sumamos el tipo paquete tcp total = sumando + sumanda; sumando += sumanda; if (total[16] == 1)//al sumar sumanda a sumando acarrea bit. sumando++; sumanda = (uint16_t)(tamaño - 34);// ((datos[38] << 8) + datos[39]);//sumamos el tamaño del paquete. //sumanda = (uint16_t)((datos[38] << 8) + datos[39]);//sumamos el tamaño del paquete. total = sumando + sumanda; sumando += sumanda; if (total[16] == 1)//al sumar sumanda a sumando acarrea bit. sumando++; //YA TENEMOS CALCULADO EL PSEUDO HEADER. for (int i = 34; i < 40; i++)//del 34 al 41, 3 campos tcp header. { sumanda = (uint16_t)((datos[i] << 8) + datos[i + 1]); total = sumando + sumanda; sumando += sumanda; if (total[16] == 1)//al sumar sumanda a sumando acarrea bit. sumando++; i++; } for (int i = 42; i < tamaño; i++)//sumamos resto. { sumanda = (uint16_t)((datos[i] << 8) + datos[i + 1]); total = sumando + sumanda; sumando += sumanda; if (total[16] == 1)//al sumar sumanda a sumando acarrea bit. sumando++; i++; } sumando = sumando & 0xFFFF; sumando = ~sumando; checksum[0] = (sumando >> 8) & 0x00FF; checksum[1] = sumando & 0x00FF; return checksum; }
Lo saqué de aqui como hacerlo:
http://www.arcesio.net/checksum/checksumTCP.html
Pero no funciona, pues al comparar mis tcp checksums con los de wireshark no coinciden, ¿alguna ayuda?. ¿que tengo mal?.
Gracias.
He estado mirando y tengo mal en la linea que hago la suma del tamaño del paquete, ese no es su tamaño. Pero aun asi sigue fallando.
¿en la línea 20 que habría que poner?.
Edito: Haber sumo primero la ip origen y destino, el numero de protocolo 0x06 (pasandolo a u_short como todos los sumandos), y luego le sumo la linea en duda del tamaño del tcp header y sus datos.
Luego a eso le tengo que sumarla suma del campo tcp header de u_short en u_short e igual con el payload, ¿pero porque no funciona?.
Ejemplo salida:
Código
if (pkt_data[23] == 0x06){ u_char origen[4]; u_char destino[4]; memcpy(origen, const_cast<u_char*>(pkt_data + 26), sizeof(u_char)* 4); memcpy(destino, const_cast<u_char*>(pkt_data + 30), sizeof(u_char)* 4); in_addr a; in_addr b; a.S_un.S_addr = inet_addr((char*)origen); b.S_un.S_addr = inet_addr((char*)destino); printf("%x%x==", pkt_data[50], pkt_data[51]); printf("%x%x==", tcp_check(const_cast<u_char*>(pkt_data), header->caplen, inet_addr((char*)origen), inet_addr((char*)destino))[0], tcp_check(const_cast<u_char*>(pkt_data), header->caplen, inet_addr((char*)origen), inet_addr((char*)destino))[1]); printf("%x%x", tcp_checksum(const_cast<u_char*>(pkt_data), header->caplen)[0], tcp_checksum(const_cast<u_char*>(pkt_data), header->caplen)[1]); cout << endl; }
Citar
bee==d4f9==014
4eb4==d4f9==014
675a==d4f9==014
4eb4==d4f9==014
675a==d4f9==014
Me sale el checksum siempre 014 ???
Por cierto la otra funcion que pruebo, que no es mía tampoco funciona es:
Código
u_char* tcp_check(u_char *buff, size_t len, u_long src_addr, u_long dest_addr) { uint16_t *buf = (uint16_t*)buff; uint16_t ip_src = (uint16_t)src_addr, ip_dst = (uint16_t)dest_addr; uint32_t sum; size_t length = len; // Calculate the sum // sum = 0; while (len > 1) { sum += *buf++; if (sum & 0x80000000) sum = (sum & 0xFFFF) + (sum >> 16); len -= 2; } if (len & 1) // Add the padding if the packet lenght is odd // sum += *((uint8_t *)buf); // Add the pseudo-header // sum += (ip_src++); sum += ip_src; sum += (ip_dst++); sum += ip_dst; sum += htons(IPPROTO_TCP); sum += htons(length); // Add the carries // while (sum >> 16) sum = (sum & 0xFFFF) + (sum >> 16); u_char ret[2]; // Return the one's complement of sum ret[0] = ((uint16_t)(~sum) >> 8) & 0x00FF; ret[1] = (uint16_t)(~sum) & 0x00FF;// // return ((uint16_t)(~sum)); return ret; } //http://minirighi.sourceforge.net/html/tcp_8c-source.html