use n::packet::*;
use n::ip;
extract_field!(extract_vtf, ipv6, 4, vtf);
fill_field!(fill_vtf, ipv6, 4, vtf);
extract_field!(extract_source, ipv6, 16, source);
fill_field!(fill_source, ipv6, 16, source);
extract_field!(extract_destination, ipv6, 16, destination);
fill_field!(fill_destination, ipv6, 16, destination);
alias_protocol!(extract_total_length, ipv6, ip, total_length);
alias_protocol!(fill_total_length, ipv6, ip, total_length);
alias_protocol!(extract_total_length_u16, ipv6, ip, total_length, total_length_u16);
alias_protocol!(apply_total_length, ipv6, ip, total_length, total_length_u16);
alias_protocol!(extract_hop_limit, ipv6, ip, hop_limit);
alias_protocol!(fill_hop_limit, ipv6, ip, hop_limit);
alias_protocol!(extract_hop_limit_u8, ipv6, ip, hop_limit, hop_limit_u8);
alias_protocol!(apply_hop_limit, ipv6, ip, hop_limit, hop_limit_u8);
alias_protocol!(extract_protocol, ipv6, ip, protocol);
alias_protocol!(fill_protocol, ipv6, ip, protocol);
alias_protocol!(extract_protocol_u8, ipv6, ip, protocol, protocol_u8);
alias_protocol!(apply_protocol, ipv6, ip, protocol, protocol_u8);
#[millefeuille]
pub fn extract_source_u64(packet: Packet) -> Packet {
let mut packet = packet;
let first_8;
let later_8;
{
let field = packet.context.get_field("ipv6::source");
first_8 = field.read_u64(0);
later_8 = field.read_u64(8);
}
packet.context.set_u64("ipv6::source0_u64", first_8);
packet.context.set_u64("ipv6::source1_u64", later_8);
packet
}
#[millefeuille]
pub fn extract_destination_u64(packet: Packet) -> Packet {
let mut packet = packet;
let first_8;
let later_8;
{
let field = packet.context.get_field("ipv6::destination");
first_8 = field.read_u64(0);
later_8 = field.read_u64(8);
}
packet.context.set_u64("ipv6::destination0_u64", first_8);
packet.context.set_u64("ipv6::destination1_u64", later_8);
packet
}
#[millefeuille]
pub fn apply_source(packet: Packet) -> Packet {
let mut packet = packet;
let mut field = packet.context.take_field("ipv6::source");
let value0 = packet.context.get_u64("ipv6::source0_u64");
let value1 = packet.context.get_u64("ipv6::source1_u64");
field.write_u64(0, value0);
field.write_u64(8, value1);
packet.context.set_field("ipv6::source", field);
packet
}
#[millefeuille]
pub fn apply_destination(packet: Packet) -> Packet {
let mut packet = packet;
let mut field = packet.context.take_field("ipv6::destination");
let value0 = packet.context.get_u64("ipv6::destination0_u64");
let value1 = packet.context.get_u64("ipv6::destination1_u64");
field.write_u64(0, value0);
field.write_u64(8, value1);
packet.context.set_field("ipv6::destination", field);
packet
}
#[millefeuille]
pub fn extract_version_u8(packet: Packet) -> Packet {
let mut packet = packet;
let vtf;
{
let field = packet.context.get_field("ipv6::vtf");
vtf = field.read_u8(0);
}
packet.context.set_u8("ipv6::version_u8", (vtf >> 4) & 0x0F);
packet
}
#[millefeuille]
pub fn apply_version(packet: Packet) -> Packet {
let mut packet = packet;
let mut field = packet.context.take_field("ipv6::vtf");
let value = packet.context.get_u8("ipv6::version_u8");
let value = value << 4;
let value = value | (field.read_u8(0) & 0x0F);
field.write_u8(0, value);
packet.context.set_field("ipv6::vtf", field);
packet
}
#[millefeuille]
pub fn extract_dscp_u8(packet: Packet) -> Packet {
let mut packet = packet;
let vtf;
{
let field = packet.context.get_field("ipv6::vtf");
vtf = field.read_u16(0);
}
let dscp_ecn = ((vtf >> 4) & 0xFF) as u8;
packet.context.set_u8("ipv6::dscp_u8", (dscp_ecn >> 2) & 0x3F);
packet.context.set_alias("ip::dscp_u8", "ipv6::dscp_u8");
packet
}
pub fn apply_dscp(packet: Packet) -> Packet {
let mut packet = packet;
let mut field = packet.context.take_field("ipv6::vtf");
let value = packet.context.get_u8("ipv6::dscp_u8");
let value = value << 2;
let value = (value as u16) << 4;
let value = value | (field.read_u16(0) & 0xF03F);
field.write_u16(0, value);
packet.context.set_field("ipv6::vtf", field);
packet
}
#[millefeuille]
pub fn extract_ecn_u8(packet: Packet) -> Packet {
let mut packet = packet;
let vtf;
{
let field = packet.context.get_field("ipv6::vtf");
vtf = field.read_u16(0);
}
let dscp_ecn = ((vtf >> 4) & 0xFF) as u8;
packet.context.set_u8("ipv6::ecn_u8", dscp_ecn & 0x03);
packet.context.set_alias("ip::ecn_u8", "ipv6::ecn_u8");
packet
}
pub fn apply_ecn(packet: Packet) -> Packet {
let mut packet = packet;
let mut field = packet.context.take_field("ipv6::vtf");
let value = packet.context.get_u8("ipv6::ecn_u8");
let value = value & 0x03;
let value = (value as u16) << 4;
let value = value | (field.read_u16(0) & 0xFFCF);
field.write_u16(0, value);
packet.context.set_field("ipv6::vtf", field);
packet
}
#[millefeuille]
pub fn extract_flow_u32(packet: Packet) -> Packet {
let mut packet = packet;
let vtf;
{
let field = packet.context.get_field("ipv6::vtf");
vtf = field.read_u32(0);
}
packet.context.set_u32("ipv6::flow_u32", vtf & 0x000FFFFF);
packet
}
pub fn apply_flow(packet: Packet) -> Packet {
let mut packet = packet;
let mut field = packet.context.take_field("ipv6::vtf");
let value = packet.context.get_u32("ipv6::flow_u32");
let value = value & 0x000FFFFF;
let value = value | (field.read_u32(0) & 0xFFF00000);
field.write_u32(0, value);
packet.context.set_field("ipv6::vtf", field);
packet
}
#[millefeuille]
pub fn prepare_pseudo_header_u16(packet: Packet) -> Packet {
let mut sum: u32;
let ipv6_body;
{
let ipv6_src = packet.context.get_field("ipv6::source");
let ipv6_dst = packet.context.get_field("ipv6::destination");
let ipv6_proto = packet.context.get_field("ipv6::protocol").read_u8(0);
let ipv6_hlen = packet.context.get_u32("ipv6::header_length_u32");
let ipv6_tlen = packet.context.get_u32("ipv6::total_length_u32");
ipv6_body = ipv6_tlen - ipv6_hlen;
sum = (ipv6_body & 0x0000FFFF) + (ipv6_body >> 16);
sum = sum + ipv6_proto as u32;
sum = sum + ipv6_src.ones_complement_sum_u16(ipv6_src.len()) as u32;
sum = sum + ipv6_dst.ones_complement_sum_u16(ipv6_dst.len()) as u32;
while (sum & 0xFFFF0000) > 0 {
sum = (sum >> 16) + (sum & 0x0000FFFF);
}
}
let mut packet = packet;
packet.context.set_u16("ipv6::pseudo_csum_u16", sum as u16);
packet.context.set_alias("ip::pseudo_csum_u16", "ipv6::pseudo_csum_u16");
packet.context.set_u32("ipv6::payload_length_u32", ipv6_body);
packet.context.set_alias("ip::payload_length_u32", "ipv6::payload_length_u32");
packet
}
#[millefeuille]
pub fn has_more_options(packet: Packet) -> Packet {
let has_next = match packet.context.get_field("ip::protocol").read_u8(0) {
0x00 |
0x2B |
0x2C |
0x3C |
0x33 |
0x32 => true,
_ => false,
};
let mut packet = packet;
packet.context.set_bool_released("ipv6::more_options_bool", has_next);
packet
}
#[millefeuille]
pub fn prepare_option_parsing(packet: Packet) -> Packet {
let mut packet = packet;
let ipv6_hlen = match packet.context.get_u32_released("ipv6::header_length_u32") {
Some(x) => x,
_ => 0, };
let ipv6_tlen = match packet.context.get_u32_released("ipv6::total_length_u32") {
Some(x) => x,
_ => packet.context.get_field("ipv6::total_length").read_u16(0) as u32,
};
packet.context.set_u32_released("ipv6::header_length_u32", ipv6_hlen);
packet.context.set_u32_released("ipv6::total_length_u32", ipv6_tlen);
packet
}
#[millefeuille]
pub fn extract_current_option(packet: Packet) -> Packet {
let ipv6_hlen = packet.context.get_u32("ipv6::header_length_u32");
let (packet, next_header) = packet.right_packet(1);
let (packet, ext_len) = packet.right_packet(1);
let ext_len = ext_len.read_u8(0) << 3; let mut packet = packet.right_strip(6);
packet.context.set_field_released("ipv6::protocol", next_header);
packet.context.set_u32_released("ipv6::header_length_u32", ipv6_hlen + 8 + ext_len as u32);
packet.right_strip(ext_len as usize)
}
#[millefeuille]
pub fn extract(packet: Packet) -> Packet {
let packet = extract_vtf(packet);
let packet = extract_total_length(packet);
let packet = extract_protocol(packet);
let packet = extract_hop_limit(packet);
let packet = extract_source(packet);
let packet = extract_destination(packet);
let packet = prepare_option_parsing(packet);
let mut packet = packet;
loop {
packet = has_more_options(packet);
if !packet.context.get_bool("ipv6::more_options_bool") {
break;
}
packet = extract_current_option(packet);
}
packet = prepare_pseudo_header_u16(packet);
packet
}
#[millefeuille]
pub fn fill(packet: Packet) -> Packet {
let packet = fill_destination(packet);
let packet = fill_source(packet);
let packet = fill_hop_limit(packet);
let packet = fill_protocol(packet);
let packet = fill_total_length(packet);
let packet = fill_vtf(packet);
packet
}