- Timestamping management added - Errors due to reading uninitialized data in ARP fixed - EthInterface reworked, incoming packet notification and payload readout separated (through which fixing concurrent access problems) - RX and TX offloads added - Capability to add a packet sieve layer without prior registration of specific packet class added (this makes it possible to register arbitrary EtherType connection blocks, for example)
62 lines
2.4 KiB
C
62 lines
2.4 KiB
C
#include <stdbool.h>
|
|
#include "udp_packet.h"
|
|
#include "../../utils.h"
|
|
#include "ipv4_packet.h"
|
|
#include "ethernet_frame.h"
|
|
|
|
#include "tcp_udp_common.h"
|
|
#include "etherlib/eth_interface.h"
|
|
|
|
#define ETH_UDP_HEADER_SIZE (8)
|
|
|
|
static bool check_udp_validity(const uint8_t * hdr, const PcktHeaderElement *pcktHdrLe) {
|
|
const UdpProps *udpProps = HEADER_FETCH_PROPS(UdpProps, pcktHdrLe);
|
|
const IPv4Props *ipProps = (IPv4Props *) &pcktHdrLe->prev->props;
|
|
IPv4PseudoHeader ph = {ipProps->SourceIPAddr, ipProps->DestIPAddr, 0, ETH_UDP_PACKET_CLASS, htons(udpProps->Length)};
|
|
uint16_t chkSum = ~tcp_udp_checksum(&ph, hdr, udpProps->Length);
|
|
bool valid = chkSum == 0;
|
|
return valid;
|
|
}
|
|
|
|
int parse_udp(const uint8_t *hdr, uint32_t size, PcktHeaderElement *pcktHdrLe, struct EthInterface_ *intf, PcktProcFnPassbackData *pb) {
|
|
const uint8_t * hdrBegin = hdr;
|
|
UdpProps *udpProps = HEADER_FETCH_PROPS(UdpProps, pcktHdrLe);
|
|
FETCH_WORD_H2N_ADVANCE(&udpProps->SourcePort, hdr);
|
|
FETCH_WORD_H2N_ADVANCE(&udpProps->DestinationPort, hdr);
|
|
FETCH_WORD_H2N_ADVANCE(&udpProps->Length, hdr);
|
|
FETCH_WORD_H2N_ADVANCE(&udpProps->Checksum, hdr);
|
|
|
|
// common fields...
|
|
udpProps->headerSize = ETH_UDP_HEADER_SIZE;
|
|
if (!(intf->capabilities & ETHINF_CAP_RX_TCPUDPCHKSUM_OFFLOAD)) {
|
|
udpProps->validityOK = check_udp_validity(hdrBegin, pcktHdrLe);
|
|
} else {
|
|
udpProps->validityOK = true;
|
|
}
|
|
udpProps->containedPacketClass = 0;
|
|
|
|
return udpProps->validityOK ? PROC_FN_RET_OK : PROC_FN_RET_ABORT;
|
|
}
|
|
|
|
void insert_udp_header(uint8_t *hdr, const PcktHeaderElement *headers, EthInterface *intf) {
|
|
uint8_t *hdrBegin = hdr;
|
|
UdpProps *udpProps = (UdpProps *) &headers->props;
|
|
FILL_WORD_H2N_ADVANCE(hdr, udpProps->SourcePort);
|
|
FILL_WORD_H2N_ADVANCE(hdr, udpProps->DestinationPort);
|
|
FILL_WORD_H2N_ADVANCE(hdr, udpProps->Length);
|
|
uint8_t *ChkSumPtr = hdr;
|
|
udpProps->Checksum = 0;
|
|
FILL_WORD_H2N_ADVANCE(hdr, udpProps->Checksum);
|
|
|
|
// calculate checksum if needed
|
|
if (!(intf->capabilities & ETHINF_CAP_TX_TCPUDPCHKSUM_OFFLOAD)) {
|
|
const IPv4Props *ipProps = (IPv4Props *) &headers->prev->props;
|
|
IPv4PseudoHeader ph = {ipProps->SourceIPAddr, ipProps->DestIPAddr, 0, ETH_UDP_PACKET_CLASS, htons(udpProps->Length)};
|
|
udpProps->Checksum = tcp_udp_checksum(&ph, hdrBegin, udpProps->Length);
|
|
memcpy(ChkSumPtr, &udpProps->Checksum, 2);
|
|
}
|
|
}
|
|
|
|
|
|
|