File: test-ip.rs

package info (click to toggle)
rust-libslirp 4.3.2-1
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 260 kB
  • sloc: python: 447; makefile: 16
file content (119 lines) | stat: -rw-r--r-- 3,304 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
use etherparse::{PacketBuilder, TcpOptionElement};
use libslirp;
use std::io;
use std::os::unix::io::RawFd;
use std::time::Instant;
use structopt::StructOpt;

impl libslirp::Handler for App {
    type Timer = usize;

    fn clock_get_ns(&mut self) -> i64 {
        const NANOS_PER_SEC: u64 = 1_000_000_000;
        let d = self.start.elapsed();
        (d.as_secs() * NANOS_PER_SEC + d.subsec_nanos() as u64) as i64
    }

    fn timer_new(&mut self, _func: Box<dyn FnMut()>) -> Box<Self::Timer> {
        Box::new(0)
    }

    fn timer_mod(&mut self, _timer: &mut Box<Self::Timer>, _expire_time: i64) {}

    fn timer_free(&mut self, timer: Box<Self::Timer>) {
        drop(timer);
    }

    fn send_packet(&mut self, buf: &[u8]) -> io::Result<usize> {
        //self.stream.send(buf).unwrap() as isize
        Ok(buf.len())
    }

    fn guest_error(&mut self, msg: &str) {
        eprintln!("guest error: {}", msg);
    }

    fn register_poll_fd(&mut self, fd: RawFd) {
        println!("register_poll_fd: fd={:?}", fd);
    }

    fn unregister_poll_fd(&mut self, fd: RawFd) {
        println!("unregister_poll_fd: fd={:?}", fd);
    }

    fn notify(&mut self) {
        println!("notify");
    }
}

struct App {
    start: Instant,
}

#[test]
fn ip() {
    let opt = libslirp::Opt::from_args();
    let app = App {
        start: Instant::now(),
    };
    let ctxt = libslirp::Context::new_with_opt(&opt, app);

    {
        let builder = PacketBuilder::ethernet2(
            [1, 2, 3, 4, 5, 6],    //source mac
            [7, 8, 9, 10, 11, 12], //destination mac
        )
        .ipv4(
            [192, 168, 1, 1], //source ip
            [192, 168, 1, 2], //desitination ip
            20,               //time to life
        )
        .udp(
            21,   //source port
            1234, //desitnation port
        );

        //payload of the udp packet
        let payload = [1, 2, 3, 4, 5, 6, 7, 8];
        let mut buffer = Vec::<u8>::with_capacity(builder.size(payload.len()));
        builder.write(&mut buffer, &payload).unwrap();

        ctxt.input(&buffer);
    }

    {
        let builder = PacketBuilder::ethernet2(
            [1, 2, 3, 4, 5, 6],    //source mac
            [7, 8, 9, 10, 11, 12], //destionation mac
        )
        .ipv4(
            [192, 168, 1, 1], //source ip
            [192, 168, 1, 2], //desitionation ip
            20,               //time to life
        )
        .tcp(
            21,    //source port
            1234,  //desitnation port
            1,     //sequence number
            26180, //window size
        )
        //set additional tcp header fields
        .ns() //set the ns flag
        //supported flags: ns(), fin(), syn(), rst(), psh(), ece(), cwr()
        .ack(123) //ack flag + the ack number
        .urg(23) //urg flag + urgent pointer
        //tcp header options
        .options(&[
            TcpOptionElement::Noop,
            TcpOptionElement::MaximumSegmentSize(1234),
        ])
        .unwrap();

        //payload of the tcp packet
        let payload = [1, 2, 3, 4, 5, 6, 7, 8];
        //get some memory to store the result
        let mut buffer = Vec::<u8>::with_capacity(builder.size(payload.len()));
        builder.write(&mut buffer, &payload).unwrap();
        ctxt.input(&buffer);
    }
}