Calculating the checksum of a UDP packet
Posted: Mon Mar 25, 2024 1:05 pm
In an ESP32C6 project I am sending UDP packets over ethernet to another device. I am trying to calculate the checksum of the UDP packet I have to send.
To do this I have:
I know that the result of the checksum of the UDP header is "ec 16" but the result I get is "13 e9".
Can someone tell me what I have wrong?
To do this I have:
- static void convert_hex_to_uint8(const char *data_hex)
- {
- unsigned int temp;
- for (size_t i = 0; i < sizeof(mensajeUDP); i++) {
- sscanf(&data_hex[i*3], "%02x", &temp);
- mensajeUDP[i] = temp;
- }
- }
- static void enviarConfiguracionABalanza(void)
- {
- uint8_t src_mac[] = {0x00, 0x08, 0xef, 0x00, 0x01, 0x37};
- uint8_t dest_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
- uint32_t src_ip = 0xc0a80a98;
- uint32_t dest_ip = 0xc0a80aff;
- uint16_t src_port = 6000;
- uint16_t dest_port = 6000;
- int msg_len;
- if (enviarRespuestaUDP == false)
- return;
- else
- enviarRespuestaUDP = false;
- const char *data_hex = "44 50 48 00 04 01 00 ff 00 00 00 00 02 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 01 4d 41 53 00 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2b 2b 2b 2b 2b 2b 2b 2b 2b 00 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 98 0a a8 c0 0e 00 00 00 31 31 37 00 20 20 45 00 00 00 00 00 01 00 00 00 46 00 00 00 30 2e 31 37 00 00 00 00 00 00 00 05 30 00 00 03 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ff ff 00 00 01 00 00 00 00 00";
- msg_len = strlen(data_hex);
- printf ("%d",msg_len);
- convert_hex_to_uint8(data_hex);
- ethernet_header_t *eth_header = (ethernet_header_t *)bufferUDP;
- ip_header_t *ip_header = (ip_header_t *)(bufferUDP + sizeof(ethernet_header_t));
- udp_header_t *udp_header = (udp_header_t *)(bufferUDP + sizeof(ethernet_header_t) + sizeof(ip_header_t));
- memcpy(eth_header->src_mac, src_mac, 6);
- memcpy(eth_header->dest_mac, dest_mac, 6);
- eth_header->ethertype = htons(0x0800); // IP
- ip_header->version_ihl = 0x45;
- ip_header->type_of_service = 0;
- ip_header->total_length = 0x2001;
- ip_header->identification = 0x2900;
- ip_header->flags_fragment_offset = 0;
- ip_header->ttl = 128;
- ip_header->header_checksum = 0;
- ip_header->protocol = 17; // UDP
- ip_header->src_ip = htonl(src_ip);
- ip_header->dest_ip = htonl(dest_ip);
- ip_header->header_checksum = calculate_ip_checksum(ip_header);
- udp_header->src_port = htons(src_port);
- udp_header->dest_port = htons(dest_port);
- udp_header->checksum = 0;
- udp_header->length = 0x0c01;
- udp_header->checksum = calculate_udp_checksum(ip_header, udp_header, mensajeUDP, 260);
- memcpy(bufferUDP + sizeof(ethernet_header_t) + sizeof(ip_header_t) + sizeof(udp_header_t), mensajeUDP, 260);
- if (esp_eth_transmit(s_eth_handle[0], bufferUDP, 302) != ESP_OK)
- ESP_LOGE(TAG, "Error");
- }
- static uint16_t calculate_checksum(uint16_t *buffer, int length)
- {
- uint32_t sum = 0;
- while (length > 1) {
- sum += *buffer++;
- length -= 2;
- }
- if (length > 0) {
- sum += *(uint8_t *)buffer;
- }
- while (sum >> 16) {
- sum = (sum & 0xffff) + (sum >> 16);
- }
- return (uint16_t)~sum;
- }
- static uint16_t calculate_ip_checksum(ip_header_t *ip_header)
- {
- ip_header->header_checksum = 0;
- return (calculate_checksum((uint16_t *)ip_header, sizeof(ip_header_t)));
- }
- static uint16_t calculate_udp_checksum(ip_header_t *ip_header, udp_header_t *udp_header, uint8_t *data, uint16_t data_len)
- {
- uint16_t total_length = sizeof(udp_header_t) + data_len;
- uint8_t pseudo_header_buffer[sizeof(pseudo_header_t) + sizeof(udp_header_t)];
- pseudo_header_t *pseudo_header = (pseudo_header_t *)pseudo_header_buffer;
- pseudo_header->src_ip = ip_header->src_ip;
- pseudo_header->dest_ip = ip_header->dest_ip;
- pseudo_header->zero = 0;
- pseudo_header->protocol = ip_header->protocol;
- pseudo_header->udp_length = htons(total_length);
- uint32_t sum = 0;
- sum += calculate_checksum((uint16_t *)pseudo_header, sizeof(pseudo_header_t));
- sum += calculate_checksum((uint16_t *)udp_header, sizeof(udp_header_t));
- sum += calculate_checksum((uint16_t *)data, data_len);
- while (sum >> 16) {
- sum = (sum & 0xffff) + (sum >> 16);
- }
- return (uint16_t)~sum;
- }
Can someone tell me what I have wrong?