FPS 0.0.3

Flow processing system (under construction).
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
}