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};
use pnet::transport::transport_channel;
use pnet::transport::TransportChannelType::Layer3;
use std::net::IpAddr;
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 {
pub fn send_packet(&self) -> Result<(), std::io::Error> {
let protocol = Layer3(IpNextHeaderProtocols::Udp);
let (mut tx, _) = transport_channel(4096, protocol)?;
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"));
}
};
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);
let mut ipv4buffer = [0u8; 1024];
let mut ipv4packet = MutableIpv4Packet::new(&mut ipv4buffer).unwrap();
ipv4packet.set_source(self.source_ip);
ipv4packet.set_destination(self.dest_ip);
let totallen = (20 + 8 + self.data.len()) as u16;
ipv4packet.set_total_length(totallen);
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);
let udplen = udppacket.get_length() as usize;
let udppacketmut = udppacket.packet_mut();
ipv4packet.set_payload(&udppacketmut[0..udplen]);
match tx.send_to(ipv4packet, IpAddr::V4(self.dest_ip)) {
Err(e) => Err(e),
_ => Ok(())
}
}
}