use n::packet::*;
use n::l4;
use std::cmp::min;
alias_protocol!(extract_source, udp, l4, source);
alias_protocol!(fill_source, udp, l4, source);
alias_protocol!(extract_source_u16, udp, l4, source, source_u16);
alias_protocol!(apply_source, udp, l4, source, source_u16);
alias_protocol!(extract_destination, udp, l4, destination);
alias_protocol!(fill_destination, udp, l4, destination);
alias_protocol!(extract_destination_u16, udp, l4, destination, destination_u16);
alias_protocol!(apply_destination, udp, l4, destination, destination_u16);
extract_field!(extract_length, udp, 2, length);
fill_field!(fill_length, udp, 2, length);
extract_field_value!(extract_length_u16, udp, length, u16);
apply_field_value!(apply_length, udp, length, u16);
extract_field!(extract_checksum, udp, 2, checksum);
fill_field!(fill_checksum, udp, 2, checksum);
extract_field_value!(extract_checksum_u16, udp, checksum, u16);
apply_field_value!(apply_checksum, udp, checksum, u16);
#[millefeuille]
pub fn verify_header_checksum(packet: Packet) -> Packet {
let mut packet = packet;
let payload_length = min(packet.len(),
packet.context.get_u32("ip::payload_length_u32") as usize);
let mut sum = packet.ones_complement_sum_u16(payload_length) as u32;
sum = sum + packet.context.get_u16("ip::pseudo_csum_u16") as u32;
sum = (sum >> 16) + (sum & 0x0000FFFF);
let result = sum as u16;
packet.context.set_u16("udp::current_csum_u16", result);
packet.context.set_bool("udp::correct_csum_bool",
(result == 0xFFFF) || (result == 0x0000));
packet
}
#[millefeuille]
pub fn apply_current_checksum(packet: Packet) -> Packet {
let mut packet = packet;
let mut field = packet.context.take_field("udp::checksum");
let current = packet.context.get_u16("udp::current_csum_u16");
let csum = field.read_u16(0);
let current = (!csum) as u32 + current as u32;
let current = ((current >> 16) + (current & 0xFFFF)) as u16;
field.write_u16(0, !current);
packet.context.set_bool_released("udp::correct_csum_bool", true);
packet.context.set_u16_released("udp::current_csum_u16", 0);
packet.context.set_field("udp::checksum", field);
packet
}
#[millefeuille]
pub fn extract(packet: Packet) -> Packet {
let packet = verify_header_checksum(packet);
let packet = extract_source(packet);
let packet = extract_destination(packet);
let packet = extract_length(packet);
let packet = extract_checksum(packet);
packet
}
#[millefeuille]
pub fn fill(packet: Packet) -> Packet {
let packet = fill_checksum(packet);
let packet = fill_length(packet);
let packet = fill_destination(packet);
let packet = fill_source(packet);
packet
}