1use capsules_core::virtualizers::virtual_alarm::{MuxAlarm, VirtualMuxAlarm};
36use capsules_extra::ieee802154::device::{MacDevice, TxClient};
37use capsules_extra::net::ieee802154::MacAddress;
38use capsules_extra::net::ipv6::ip_utils::{ip6_nh, IPAddr};
39use capsules_extra::net::ipv6::{IP6Header, IP6Packet, IPPayload, TransportHeader};
40use capsules_extra::net::sixlowpan::sixlowpan_compression;
41use capsules_extra::net::sixlowpan::sixlowpan_state::{
42 RxState, Sixlowpan, SixlowpanRxClient, SixlowpanState, TxState,
43};
44use capsules_extra::net::udp::UDPHeader;
45use core::cell::Cell;
46use core::ptr::addr_of_mut;
47use core::sync::atomic::{AtomicUsize, Ordering};
48use kernel::debug;
49use kernel::hil::radio;
50use kernel::hil::time::{self, Alarm, ConvertTicks};
51use kernel::static_init;
52use kernel::ErrorCode;
53
54pub const MLP: [u8; 8] = [0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7];
55
56pub const SRC_ADDR: IPAddr = IPAddr([
57 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
58]);
59pub const DST_ADDR: IPAddr = IPAddr([
60 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
61]);
62pub const SRC_MAC_ADDR: MacAddress =
63 MacAddress::Long([0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17]);
64pub const DST_MAC_ADDR: MacAddress = MacAddress::Short(57326);
65pub const IP6_HDR_SIZE: usize = 40;
67pub const UDP_HDR_SIZE: usize = 8;
68pub const PAYLOAD_LEN: usize = 200;
69pub static mut RF233_BUF: [u8; radio::MAX_BUF_SIZE] = [0_u8; radio::MAX_BUF_SIZE];
70
71const DEFAULT_CTX_PREFIX_LEN: u8 = 8;
73static DEFAULT_CTX_PREFIX: [u8; 16] = [0x0_u8; 16];
74static mut RX_STATE_BUF: [u8; 1280] = [0x0; 1280];
75
76#[derive(Copy, Clone, Debug, PartialEq)]
77enum TF {
78 Inline = 0b00,
79 Traffic = 0b01,
80 Flow = 0b10,
81 TrafficFlow = 0b11,
82}
83
84#[derive(Copy, Clone, Debug)]
85enum SAC {
86 Inline,
87 LLP64,
88 LLP16,
89 LLPIID,
90 Unspecified,
91 Ctx64,
92 Ctx16,
93 CtxIID,
94}
95
96#[derive(Copy, Clone, Debug)]
97enum DAC {
98 Inline,
99 LLP64,
100 LLP16,
101 LLPIID,
102 Ctx64,
103 Ctx16,
104 CtxIID,
105 McastInline,
106 Mcast48,
107 Mcast32,
108 Mcast8,
109 McastCtx,
110}
111
112pub const TEST_DELAY_MS: u32 = 10000;
113pub const TEST_LOOP: bool = false;
114static SUCCESS_COUNT: AtomicUsize = AtomicUsize::new(0);
115static mut UDP_DGRAM: [u8; PAYLOAD_LEN - UDP_HDR_SIZE] = [0; PAYLOAD_LEN - UDP_HDR_SIZE]; static mut IP6_DG_OPT: Option<IP6Packet> = None;
122type Rf233 = capsules_extra::rf233::RF233<
125 'static,
126 capsules_core::virtualizers::virtual_spi::VirtualSpiMasterDevice<
127 'static,
128 sam4l::spi::SpiHw<'static>,
129 >,
130>;
131type Ieee802154MacDevice =
132 components::ieee802154::Ieee802154ComponentMacDeviceType<Rf233, sam4l::aes::Aes<'static>>;
133
134pub struct LowpanTest<'a, A: time::Alarm<'a>> {
135 alarm: &'a A,
136 sixlowpan_tx: TxState<'a>,
137 radio: &'a dyn MacDevice<'a>,
138 test_counter: Cell<usize>,
139}
140
141pub unsafe fn initialize_all(
142 mux_mac: &'static capsules_extra::ieee802154::virtual_mac::MuxMac<'static, Ieee802154MacDevice>,
143 mux_alarm: &'static MuxAlarm<'static, sam4l::ast::Ast>,
144) -> &'static LowpanTest<
145 'static,
146 capsules_core::virtualizers::virtual_alarm::VirtualMuxAlarm<'static, sam4l::ast::Ast<'static>>,
147> {
148 let radio_mac = static_init!(
149 capsules_extra::ieee802154::virtual_mac::MacUser<'static, Ieee802154MacDevice>,
150 capsules_extra::ieee802154::virtual_mac::MacUser::new(mux_mac)
151 );
152 mux_mac.add_user(radio_mac);
153 let default_rx_state = static_init!(
154 RxState<'static>,
155 RxState::new(&mut *addr_of_mut!(RX_STATE_BUF))
156 );
157
158 let sixlo_alarm = static_init!(
159 VirtualMuxAlarm<sam4l::ast::Ast>,
160 VirtualMuxAlarm::new(mux_alarm)
161 );
162 sixlo_alarm.setup();
163
164 let sixlowpan = static_init!(
165 Sixlowpan<
166 'static,
167 VirtualMuxAlarm<sam4l::ast::Ast<'static>>,
168 sixlowpan_compression::Context,
169 >,
170 Sixlowpan::new(
171 sixlowpan_compression::Context {
172 prefix: DEFAULT_CTX_PREFIX,
173 prefix_len: DEFAULT_CTX_PREFIX_LEN,
174 id: 0,
175 compress: false,
176 },
177 sixlo_alarm
178 )
179 );
180
181 let sixlowpan_state = sixlowpan as &dyn SixlowpanState;
182 let sixlowpan_tx = TxState::new(sixlowpan_state);
183
184 let _ = sixlowpan_tx.init(SRC_MAC_ADDR, DST_MAC_ADDR, radio_mac.get_pan(), None);
185
186 let alarm = static_init!(
187 VirtualMuxAlarm<'static, sam4l::ast::Ast>,
188 VirtualMuxAlarm::new(mux_alarm)
189 );
190 alarm.setup();
191
192 let lowpan_frag_test = static_init!(
193 LowpanTest<'static, VirtualMuxAlarm<'static, sam4l::ast::Ast>>,
194 LowpanTest::new(sixlowpan_tx, radio_mac, alarm)
195 );
196
197 sixlowpan_state.add_rx_state(default_rx_state);
198 sixlowpan_state.set_rx_client(lowpan_frag_test);
199 lowpan_frag_test.alarm.set_alarm_client(lowpan_frag_test);
200
201 radio_mac.set_receive_client(sixlowpan);
202
203 let mut udp_hdr: UDPHeader = UDPHeader::new();
205 udp_hdr.set_src_port(12345);
206 udp_hdr.set_dst_port(54321);
207 udp_hdr.set_len(PAYLOAD_LEN as u16);
208 let mut ip6_hdr: IP6Header = IP6Header::new();
211 ip6_hdr.set_next_header(ip6_nh::UDP);
212 ip6_hdr.set_payload_len(PAYLOAD_LEN as u16);
213 ip6_hdr.src_addr = SRC_ADDR;
214 ip6_hdr.dst_addr = DST_ADDR;
215
216 let tr_hdr: TransportHeader = TransportHeader::UDP(udp_hdr);
217
218 let ip_pyld: IPPayload = IPPayload {
219 header: tr_hdr,
220 payload: &mut *addr_of_mut!(UDP_DGRAM),
221 };
222
223 let mut ip6_dg: IP6Packet = IP6Packet {
224 header: ip6_hdr,
225 payload: ip_pyld,
226 };
227
228 ip6_dg.set_transport_checksum(); IP6_DG_OPT = Some(ip6_dg);
231 radio_mac.set_transmit_client(lowpan_frag_test);
235 lowpan_frag_test
236}
237
238impl<'a, A: time::Alarm<'a>> LowpanTest<'a, A> {
239 pub fn new(
240 sixlowpan_tx: TxState<'a>,
241 radio: &'a dyn MacDevice<'a>,
242 alarm: &'a A,
243 ) -> LowpanTest<'a, A> {
244 LowpanTest {
245 alarm,
246 sixlowpan_tx,
247 radio,
248 test_counter: Cell::new(0),
249 }
250 }
251
252 pub fn start(&self) {
253 self.schedule_next();
255 }
256
257 fn schedule_next(&self) {
258 let delay = self.alarm.ticks_from_ms(TEST_DELAY_MS);
259 let now = self.alarm.now();
260 self.alarm.set_alarm(now, delay);
261 }
262
263 fn run_test_and_increment(&self) {
264 let test_counter = self.test_counter.get();
265 self.run_test(test_counter);
266 match TEST_LOOP {
267 true => self.test_counter.set((test_counter + 1) % self.num_tests()),
268 false => self.test_counter.set(test_counter + 1),
269 }
270 }
271
272 fn num_tests(&self) -> usize {
273 28
274 }
275
276 fn run_test(&self, test_id: usize) {
277 debug!("Running test {}:", test_id);
278 match test_id {
279 0 => self.ipv6_send_packet_test(TF::Inline, 255, SAC::Inline, DAC::Inline),
281 1 => self.ipv6_send_packet_test(TF::Traffic, 255, SAC::Inline, DAC::Inline),
282 2 => self.ipv6_send_packet_test(TF::Flow, 255, SAC::Inline, DAC::Inline),
283 3 => self.ipv6_send_packet_test(TF::TrafficFlow, 255, SAC::Inline, DAC::Inline),
284
285 4 => self.ipv6_send_packet_test(TF::TrafficFlow, 255, SAC::Inline, DAC::Inline),
287 5 => self.ipv6_send_packet_test(TF::TrafficFlow, 64, SAC::Inline, DAC::Inline),
288 6 => self.ipv6_send_packet_test(TF::TrafficFlow, 1, SAC::Inline, DAC::Inline),
289 7 => self.ipv6_send_packet_test(TF::TrafficFlow, 42, SAC::Inline, DAC::Inline),
290
291 8 => self.ipv6_send_packet_test(TF::TrafficFlow, 42, SAC::Inline, DAC::Inline),
293 9 => self.ipv6_send_packet_test(TF::TrafficFlow, 42, SAC::LLP64, DAC::Inline),
294 10 => self.ipv6_send_packet_test(TF::TrafficFlow, 42, SAC::LLP16, DAC::Inline),
295 11 => self.ipv6_send_packet_test(TF::TrafficFlow, 42, SAC::LLPIID, DAC::Inline),
296 12 => self.ipv6_send_packet_test(TF::TrafficFlow, 42, SAC::Unspecified, DAC::Inline),
297 13 => self.ipv6_send_packet_test(TF::TrafficFlow, 42, SAC::Ctx64, DAC::Inline),
298 14 => self.ipv6_send_packet_test(TF::TrafficFlow, 42, SAC::Ctx16, DAC::Inline),
299 15 => self.ipv6_send_packet_test(TF::TrafficFlow, 42, SAC::CtxIID, DAC::Inline),
300
301 16 => self.ipv6_send_packet_test(TF::TrafficFlow, 42, SAC::CtxIID, DAC::Inline),
303 17 => self.ipv6_send_packet_test(TF::TrafficFlow, 42, SAC::CtxIID, DAC::LLP64),
304 18 => self.ipv6_send_packet_test(TF::TrafficFlow, 42, SAC::CtxIID, DAC::LLP16),
305 19 => self.ipv6_send_packet_test(TF::TrafficFlow, 42, SAC::CtxIID, DAC::LLPIID),
306 20 => self.ipv6_send_packet_test(TF::TrafficFlow, 42, SAC::CtxIID, DAC::Ctx64),
307 21 => self.ipv6_send_packet_test(TF::TrafficFlow, 42, SAC::CtxIID, DAC::Ctx16),
308 22 => self.ipv6_send_packet_test(TF::TrafficFlow, 42, SAC::CtxIID, DAC::CtxIID),
309 23 => self.ipv6_send_packet_test(TF::TrafficFlow, 42, SAC::CtxIID, DAC::McastInline),
310 24 => self.ipv6_send_packet_test(TF::TrafficFlow, 42, SAC::CtxIID, DAC::Mcast48),
311 25 => self.ipv6_send_packet_test(TF::TrafficFlow, 42, SAC::CtxIID, DAC::Mcast32),
312 26 => self.ipv6_send_packet_test(TF::TrafficFlow, 42, SAC::CtxIID, DAC::Mcast8),
313 27 => self.ipv6_send_packet_test(TF::TrafficFlow, 42, SAC::CtxIID, DAC::McastCtx),
314
315 _ => {}
316 }
317 }
318
319 fn run_check_test(&self, test_id: usize, buf: &[u8], len: usize) {
320 debug!("Running test {}:", test_id);
321 let success = match test_id {
322 0 => ipv6_check_receive_packet(TF::Inline, 255, SAC::Inline, DAC::Inline, buf, len),
324 1 => ipv6_check_receive_packet(TF::Traffic, 255, SAC::Inline, DAC::Inline, buf, len),
325 2 => ipv6_check_receive_packet(TF::Flow, 255, SAC::Inline, DAC::Inline, buf, len),
326 3 => {
327 ipv6_check_receive_packet(TF::TrafficFlow, 255, SAC::Inline, DAC::Inline, buf, len)
328 }
329
330 4 => {
332 ipv6_check_receive_packet(TF::TrafficFlow, 255, SAC::Inline, DAC::Inline, buf, len)
333 }
334 5 => ipv6_check_receive_packet(TF::TrafficFlow, 64, SAC::Inline, DAC::Inline, buf, len),
335 6 => ipv6_check_receive_packet(TF::TrafficFlow, 1, SAC::Inline, DAC::Inline, buf, len),
336 7 => ipv6_check_receive_packet(TF::TrafficFlow, 42, SAC::Inline, DAC::Inline, buf, len),
337
338 8 => ipv6_check_receive_packet(TF::TrafficFlow, 42, SAC::Inline, DAC::Inline, buf, len),
340 9 => ipv6_check_receive_packet(TF::TrafficFlow, 42, SAC::LLP64, DAC::Inline, buf, len),
341 10 => ipv6_check_receive_packet(TF::TrafficFlow, 42, SAC::LLP16, DAC::Inline, buf, len),
342 11 => {
343 ipv6_check_receive_packet(TF::TrafficFlow, 42, SAC::LLPIID, DAC::Inline, buf, len)
344 }
345 12 => ipv6_check_receive_packet(
346 TF::TrafficFlow,
347 42,
348 SAC::Unspecified,
349 DAC::Inline,
350 buf,
351 len,
352 ),
353 13 => ipv6_check_receive_packet(TF::TrafficFlow, 42, SAC::Ctx64, DAC::Inline, buf, len),
354 14 => ipv6_check_receive_packet(TF::TrafficFlow, 42, SAC::Ctx16, DAC::Inline, buf, len),
355 15 => {
356 ipv6_check_receive_packet(TF::TrafficFlow, 42, SAC::CtxIID, DAC::Inline, buf, len)
357 }
358
359 16 => {
361 ipv6_check_receive_packet(TF::TrafficFlow, 42, SAC::CtxIID, DAC::Inline, buf, len)
362 }
363 17 => ipv6_check_receive_packet(TF::TrafficFlow, 42, SAC::CtxIID, DAC::LLP64, buf, len),
364 18 => ipv6_check_receive_packet(TF::TrafficFlow, 42, SAC::CtxIID, DAC::LLP16, buf, len),
365 19 => {
366 ipv6_check_receive_packet(TF::TrafficFlow, 42, SAC::CtxIID, DAC::LLPIID, buf, len)
367 }
368 20 => ipv6_check_receive_packet(TF::TrafficFlow, 42, SAC::CtxIID, DAC::Ctx64, buf, len),
369 21 => ipv6_check_receive_packet(TF::TrafficFlow, 42, SAC::CtxIID, DAC::Ctx16, buf, len),
370 22 => {
371 ipv6_check_receive_packet(TF::TrafficFlow, 42, SAC::CtxIID, DAC::CtxIID, buf, len)
372 }
373 23 => ipv6_check_receive_packet(
374 TF::TrafficFlow,
375 42,
376 SAC::CtxIID,
377 DAC::McastInline,
378 buf,
379 len,
380 ),
381 24 => {
382 ipv6_check_receive_packet(TF::TrafficFlow, 42, SAC::CtxIID, DAC::Mcast48, buf, len)
383 }
384 25 => {
385 ipv6_check_receive_packet(TF::TrafficFlow, 42, SAC::CtxIID, DAC::Mcast32, buf, len)
386 }
387 26 => {
388 ipv6_check_receive_packet(TF::TrafficFlow, 42, SAC::CtxIID, DAC::Mcast8, buf, len)
389 }
390 27 => {
391 ipv6_check_receive_packet(TF::TrafficFlow, 42, SAC::CtxIID, DAC::McastCtx, buf, len)
392 }
393
394 _ => {
395 debug!("Finished tests");
396 false
397 }
398 };
399 if success {
400 SUCCESS_COUNT.fetch_add(1, Ordering::SeqCst);
401 }
402 if test_id == self.num_tests() - 1 {
403 let success_count = SUCCESS_COUNT.load(Ordering::SeqCst);
404 if success_count == self.num_tests() {
405 debug!("All Tests completed successfully!");
406 } else {
407 debug!(
408 "Successfully completed {:?}/{:?} tests",
409 success_count,
410 self.num_tests()
411 );
412 }
413 }
414 }
415 fn ipv6_send_packet_test(&self, tf: TF, hop_limit: u8, sac: SAC, dac: DAC) {
416 ipv6_prepare_packet(tf, hop_limit, sac, dac);
417 unsafe {
418 self.send_ipv6_packet(&MLP);
419 }
420 }
421
422 unsafe fn send_ipv6_packet(&self, _: &[u8]) {
423 self.send_next(&mut *addr_of_mut!(RF233_BUF));
424 }
425
426 fn send_next(&self, tx_buf: &'static mut [u8]) {
427 unsafe {
428 match IP6_DG_OPT {
429 Some(ref ip6_packet) => {
430 match self
431 .sixlowpan_tx
432 .next_fragment(ip6_packet, tx_buf, self.radio)
433 {
434 Ok((is_done, frame)) => {
435 if is_done {
437 self.schedule_next();
438 } else {
439 let _ = self
441 .radio
442 .transmit(frame)
443 .map_err(|_| debug!("Error in radio transmit"));
444 }
445 }
446 Err((retcode, _buf)) => {
447 debug!("ERROR!: {:?}", retcode);
448 }
449 }
450 }
451 None => debug!("Error! tried to send uninitialized IP6Packet"),
452 }
453 }
454 }
455}
456
457impl<'a, A: time::Alarm<'a>> time::AlarmClient for LowpanTest<'a, A> {
458 fn alarm(&self) {
459 self.run_test_and_increment();
460 }
461}
462
463impl<'a, A: time::Alarm<'a>> SixlowpanRxClient for LowpanTest<'a, A> {
464 fn receive(&self, buf: &[u8], len: usize, retcode: Result<(), ErrorCode>) {
465 debug!("Receive completed: {:?}", retcode);
466 let test_num = self.test_counter.get();
467 self.test_counter.set((test_num + 1) % self.num_tests());
468 self.run_check_test(test_num, buf, len)
469 }
470}
471
472static mut ARRAY: [u8; 100] = [0x0; 100]; impl<'a, A: time::Alarm<'a>> TxClient for LowpanTest<'a, A> {
474 fn send_done(&self, tx_buf: &'static mut [u8], _acked: bool, result: Result<(), ErrorCode>) {
475 match result {
476 Ok(()) => {}
477 _ => debug!("sendDone indicates error"),
478 }
479 unsafe {
480 let mut i = 0;
484 while i < 4000000 {
485 ARRAY[i % 100] = (i % 100) as u8;
486 i += 1;
487 if i % 1000000 == 0 {
488 i += 2;
489 }
490 }
491 }
492 self.send_next(tx_buf);
493 }
494}
495
496fn ipv6_check_receive_packet(
497 tf: TF,
498 hop_limit: u8,
499 sac: SAC,
500 dac: DAC,
501 recv_packet: &[u8],
502 len: usize,
503) -> bool {
504 ipv6_prepare_packet(tf, hop_limit, sac, dac);
505 let mut test_success = true;
506 unsafe {
507 match IP6Header::decode(recv_packet).done() {
513 Some((offset, rcvip6hdr)) => {
514 match UDPHeader::decode(&recv_packet[offset..len]).done() {
515 Some((_offset, rcvudphdr)) => {
516 match IP6_DG_OPT {
519 Some(ref ip6_packet) => {
520 if rcvip6hdr.get_version() != ip6_packet.header.get_version() {
522 test_success = false;
523 debug!("Mismatched IP ver");
524 }
525
526 if rcvip6hdr.get_traffic_class()
527 != ip6_packet.header.get_traffic_class()
528 {
529 debug!("Mismatched tc");
530 test_success = false;
531 }
532 if rcvip6hdr.get_dscp() != ip6_packet.header.get_dscp() {
533 debug!("Mismatched dcsp");
534 test_success = false;
535 }
536 if rcvip6hdr.get_ecn() != ip6_packet.header.get_ecn() {
537 debug!("Mismatched ecn");
538 test_success = false;
539 }
540 if rcvip6hdr.get_payload_len()
541 != ip6_packet.header.get_payload_len()
542 {
543 debug!("Mismatched IP len");
544 test_success = false;
545 }
546 if rcvip6hdr.get_next_header()
547 != ip6_packet.header.get_next_header()
548 {
549 debug!(
550 "Mismatched next hdr. Rcvd is: {:?}, expctd is: {:?}",
551 rcvip6hdr.get_next_header(),
552 ip6_packet.header.get_next_header()
553 );
554 test_success = false;
555 }
556 if rcvip6hdr.get_hop_limit() != ip6_packet.header.get_hop_limit() {
557 debug!("Mismatched hop limit");
558 test_success = false;
559 }
560
561 match ip6_packet.payload.header {
564 TransportHeader::UDP(ref sent_udp_pkt) => {
565 if rcvudphdr.get_src_port() != sent_udp_pkt.get_src_port() {
566 debug!(
567 "Mismatched src_port. Rcvd is: {:?}, expctd is: {:?}",
568 rcvudphdr.get_src_port(),
569 sent_udp_pkt.get_src_port()
570 );
571 test_success = false;
572 }
573
574 if rcvudphdr.get_dst_port() != sent_udp_pkt.get_dst_port() {
575 debug!(
576 "Mismatched dst_port. Rcvd is: {:?}, expctd is: {:?}",
577 rcvudphdr.get_dst_port(),
578 sent_udp_pkt.get_dst_port()
579 );
580 test_success = false;
581 }
582
583 if rcvudphdr.get_len() != sent_udp_pkt.get_len() {
584 debug!(
585 "Mismatched udp_len. Rcvd is: {:?}, expctd is: {:?}",
586 rcvudphdr.get_len(),
587 sent_udp_pkt.get_len()
588 );
589 test_success = false;
590 }
591
592 if rcvudphdr.get_cksum() != sent_udp_pkt.get_cksum() {
593 debug!(
594 "Mismatched cksum. Rcvd is: {:?}, expctd is: {:?}",
595 rcvudphdr.get_cksum(),
596 sent_udp_pkt.get_cksum()
597 );
598 test_success = false;
599 }
600 }
601 _ => {
602 debug!(
603 "Error: For some reason prepare packet is not
604 preparing a UDP payload"
605 );
606 }
607 }
608 }
609 None => debug!("Error! tried to read uninitialized IP6Packet"),
610 }
611
612 let mut payload_success = true;
614 for i in (IP6_HDR_SIZE + UDP_HDR_SIZE)..len {
615 if recv_packet[i] != UDP_DGRAM[i - (IP6_HDR_SIZE + UDP_HDR_SIZE)] {
616 test_success = false;
617 payload_success = false;
618 debug!(
619 "Packets differ at idx: {} where recv = {}, ref = {}",
620 i - (IP6_HDR_SIZE + UDP_HDR_SIZE),
621 recv_packet[i],
622 UDP_DGRAM[i - (IP6_HDR_SIZE + UDP_HDR_SIZE)]
623 );
624 }
626 }
627 if !payload_success {
628 debug!("Packet payload did not match.");
629 }
630 }
631 None => {
632 debug!("Failed to decode UDP Header");
633 test_success = false;
634 }
635 }
636 }
637 None => {
638 debug!("Failed to decode IPv6 Header");
639 test_success = false;
640 }
641 }
642
643 debug!("Individual Test success is: {}", test_success);
644 test_success
645 }
646}
647
648fn ipv6_prepare_packet(tf: TF, hop_limit: u8, sac: SAC, dac: DAC) {
650 {
651 let payload = unsafe { &mut UDP_DGRAM[0..] };
652 for i in 0..(PAYLOAD_LEN - UDP_HDR_SIZE) {
653 payload[i] = i as u8;
654 }
655 }
656 unsafe {
657 match IP6_DG_OPT {
660 Some(ref mut ip6_packet) => {
661 {
662 let ip6_header: &mut IP6Header = &mut ip6_packet.header;
663 ip6_header.set_payload_len(PAYLOAD_LEN as u16);
664
665 if tf != TF::TrafficFlow {
666 ip6_header.set_ecn(0b01);
667 }
668 if (tf as u8) & (TF::Traffic as u8) != 0 {
669 ip6_header.set_dscp(0b000000);
670 } else {
671 ip6_header.set_dscp(0b101010);
672 }
673
674 if (tf as u8) & (TF::Flow as u8) != 0 {
675 ip6_header.set_flow_label(0);
676 } else {
677 ip6_header.set_flow_label(0xABCDE);
678 }
679
680 ip6_header.set_next_header(ip6_nh::UDP);
681
682 ip6_header.set_hop_limit(hop_limit);
683
684 match sac {
685 SAC::Inline => {
686 ip6_header.src_addr = SRC_ADDR;
687 }
688 SAC::LLP64 => {
689 ip6_header.src_addr.set_unicast_link_local();
691 ip6_header.src_addr.0[8..16].copy_from_slice(&SRC_ADDR.0[8..16]);
692 }
693 SAC::LLP16 => {
694 ip6_header.src_addr.set_unicast_link_local();
696 ip6_header.src_addr.0[11] = 0xff;
698 ip6_header.src_addr.0[12] = 0xfe;
699 ip6_header.src_addr.0[14..16].copy_from_slice(&SRC_ADDR.0[14..16]);
700 }
701 SAC::LLPIID => {
702 ip6_header.src_addr.set_unicast_link_local();
704 ip6_header.src_addr.0[8..16].copy_from_slice(
705 &sixlowpan_compression::compute_iid(&SRC_MAC_ADDR),
706 );
707 }
708 SAC::Unspecified => {}
709 SAC::Ctx64 => {
710 ip6_header.src_addr.set_prefix(&MLP, 64);
712 ip6_header.src_addr.0[8..16].copy_from_slice(&SRC_ADDR.0[8..16]);
713 }
714 SAC::Ctx16 => {
715 ip6_header.src_addr.set_prefix(&MLP, 64);
717 ip6_header.src_addr.0[11] = 0xff;
719 ip6_header.src_addr.0[12] = 0xfe;
720 ip6_header.src_addr.0[14..16].copy_from_slice(&SRC_ADDR.0[14..16]);
721 }
722 SAC::CtxIID => {
723 ip6_header.src_addr.set_prefix(&MLP, 64);
725 ip6_header.src_addr.0[8..16].copy_from_slice(
726 &sixlowpan_compression::compute_iid(&SRC_MAC_ADDR),
727 );
728 }
729 }
730
731 match dac {
732 DAC::Inline => {
733 ip6_header.dst_addr = DST_ADDR;
734 }
735 DAC::LLP64 => {
736 ip6_header.dst_addr.set_unicast_link_local();
738 ip6_header.dst_addr.0[8..16].copy_from_slice(&DST_ADDR.0[8..16]);
739 }
740 DAC::LLP16 => {
741 ip6_header.dst_addr.set_unicast_link_local();
743 ip6_header.dst_addr.0[11] = 0xff;
745 ip6_header.dst_addr.0[12] = 0xfe;
746 ip6_header.dst_addr.0[14..16].copy_from_slice(&SRC_ADDR.0[14..16]);
747 }
748 DAC::LLPIID => {
749 ip6_header.dst_addr.set_unicast_link_local();
751 ip6_header.dst_addr.0[8..16].copy_from_slice(
752 &sixlowpan_compression::compute_iid(&DST_MAC_ADDR),
753 );
754 }
755 DAC::Ctx64 => {
756 ip6_header.dst_addr.set_prefix(&MLP, 64);
758 ip6_header.dst_addr.0[8..16].copy_from_slice(&SRC_ADDR.0[8..16]);
759 }
760 DAC::Ctx16 => {
761 ip6_header.dst_addr.set_prefix(&MLP, 64);
763 ip6_header.dst_addr.0[11] = 0xff;
765 ip6_header.dst_addr.0[12] = 0xfe;
766 ip6_header.dst_addr.0[14..16].copy_from_slice(&SRC_ADDR.0[14..16]);
767 }
768 DAC::CtxIID => {
769 ip6_header.dst_addr.set_prefix(&MLP, 64);
771 ip6_header.dst_addr.0[8..16].copy_from_slice(
772 &sixlowpan_compression::compute_iid(&DST_MAC_ADDR),
773 );
774 }
775 DAC::McastInline => {
776 ip6_header.dst_addr = DST_ADDR;
778 ip6_header.dst_addr.0[0] = 0xff;
779 }
780 DAC::Mcast48 => {
781 ip6_header.dst_addr.0[0] = 0xff;
783 ip6_header.dst_addr.0[1] = DST_ADDR.0[1];
784 ip6_header.dst_addr.0[11..16].copy_from_slice(&DST_ADDR.0[11..16]);
785 }
786 DAC::Mcast32 => {
787 ip6_header.dst_addr.0[0] = 0xff;
789 ip6_header.dst_addr.0[1] = DST_ADDR.0[1];
790 ip6_header.dst_addr.0[13..16].copy_from_slice(&DST_ADDR.0[13..16]);
791 }
792 DAC::Mcast8 => {
793 ip6_header.dst_addr.0[0] = 0xff;
795 ip6_header.dst_addr.0[1] = DST_ADDR.0[1];
796 ip6_header.dst_addr.0[15] = DST_ADDR.0[15];
797 }
798 DAC::McastCtx => {
799 ip6_header.dst_addr.0[0] = 0xff;
801 ip6_header.dst_addr.0[1] = DST_ADDR.0[1];
802 ip6_header.dst_addr.0[2] = DST_ADDR.0[2];
803 ip6_header.dst_addr.0[3] = 64_u8;
804 ip6_header.dst_addr.0[4..12].copy_from_slice(&MLP);
805 ip6_header.dst_addr.0[12..16].copy_from_slice(&DST_ADDR.0[12..16]);
806 }
807 }
808 } ip6_packet.set_transport_checksum(); }
812 None => debug!("Error! tried to prepare uninitialized IP6Packet"),
813 }
814 }
815
816 debug!(
817 "Packet with tf={:?} hl={} sac={:?} dac={:?}",
818 tf, hop_limit, sac, dac
819 );
820}