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
extern crate pnet;

use std::io::{Error, ErrorKind};
use std::net::{Ipv4Addr};
use pnet::packet::ipv4::{MutableIpv4Packet};
use pnet::packet::udp::MutableUdpPacket;
use pnet::packet::ip::{IpNextHeaderProtocols};
use pnet::packet::{MutablePacket};

//testing
use pnet::transport::transport_channel;
use pnet::transport::TransportChannelType::Layer3;
use std::net::IpAddr;

/// This is the packet to be crafted and sent
pub struct CraftedUdp {
    pub source_ip: Ipv4Addr,
    pub dest_ip: Ipv4Addr,
    pub source_port: u16,
    pub dest_port: u16,
    pub data: Vec<u8>,
}
impl CraftedUdp {
    /// Sends the packet
    pub fn send_packet(&self) -> Result<(), std::io::Error> {
        let protocol = Layer3(IpNextHeaderProtocols::Udp);
        //create a channel
        let (mut tx, _) = transport_channel(4096, protocol)?;
        //create UDP datagram
        let mut udpbuffer = [0u8;1024];
        let mut udppacket = match MutableUdpPacket::new(&mut udpbuffer) {
            Some(p) => p,
            None => {
                return Err(Error::new(ErrorKind::Other, "Couldn't create UDP packet"));
            }
        };
        //setup UDP packet
        udppacket.set_source(self.source_port);
        udppacket.set_destination(self.dest_port);
        udppacket.set_length((8 + self.data.len()) as u16);
        udppacket.set_checksum(0);
        udppacket.set_payload(&self.data);
        //create IP packet
        let mut ipv4buffer = [0u8; 1024];
        let mut ipv4packet = MutableIpv4Packet::new(&mut ipv4buffer).unwrap();
        //set source and dest
        ipv4packet.set_source(self.source_ip);
        ipv4packet.set_destination(self.dest_ip);
        //set len
        let totallen = (20 + 8 + self.data.len()) as u16;
        ipv4packet.set_total_length(totallen);
        //other fields
        ipv4packet.set_version(4);
        ipv4packet.set_header_length(5);
        ipv4packet.set_dscp(0);
        ipv4packet.set_ecn(0);
        ipv4packet.set_identification(0x1234);
        ipv4packet.set_flags(0);
        ipv4packet.set_fragment_offset(0);
        ipv4packet.set_ttl(64);
        ipv4packet.set_next_level_protocol(IpNextHeaderProtocols::Udp);
        //set udp packet to payload of ipv4 packet
        let udplen = udppacket.get_length() as usize;
        let udppacketmut = udppacket.packet_mut();
        ipv4packet.set_payload(&udppacketmut[0..udplen]);
        //send the packet
        match tx.send_to(ipv4packet, IpAddr::V4(self.dest_ip)) {
            Err(e) => Err(e),
            _ => Ok(())
        }
    }
}