Class: IPFrag::Generator

Inherits:
Object
  • Object
show all
Defined in:
lib/ip_frag/generator.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(size, mtu) ⇒ Generator

Returns a new instance of Generator.



3
4
5
6
7
# File 'lib/ip_frag/generator.rb', line 3

def initialize(size, mtu)
  @size = size
  @mtu = mtu
  check_size_mtu
end

Instance Attribute Details

#dst_ipObject



114
115
116
# File 'lib/ip_frag/generator.rb', line 114

def dst_ip
  @dst_ip ||= '200.200.200.2'
end

#dst_macObject



122
123
124
# File 'lib/ip_frag/generator.rb', line 122

def dst_mac
  @dst_mac ||= '00:00:00:00:00:02'
end

#dst_portObject



130
131
132
# File 'lib/ip_frag/generator.rb', line 130

def dst_port
  @dst_port ||= 2000
end

#src_ipObject



110
111
112
# File 'lib/ip_frag/generator.rb', line 110

def src_ip
  @src_ip ||= '200.200.200.1'
end

#src_macObject



118
119
120
# File 'lib/ip_frag/generator.rb', line 118

def src_mac
  @src_mac ||= '00:00:00:00:00:01'
end

#src_portObject



126
127
128
# File 'lib/ip_frag/generator.rb', line 126

def src_port
  @src_port ||= 1000
end

Instance Method Details

#check_size_mtuObject



99
100
101
102
103
104
105
106
107
108
# File 'lib/ip_frag/generator.rb', line 99

def check_size_mtu
  
  if @size <= @mtu
    raise "Size #{@size} MUST be big than Mtu #{@mtu}."
  end
  
  if @mtu <= 0
    raise "Mtu MUST be an integer big than ZERO"
  end
end

#contant(size, ip) ⇒ Object

生成特定长度的 UDP 报文



148
149
150
151
152
153
154
155
156
# File 'lib/ip_frag/generator.rb', line 148

def contant(size, ip)
  return @udp_packet if @udp_packet
  udp = Mu::Pcap::UDP.new(src_port, dst_port)
  udp.payload = 'a' * size
  udp_packet_str = StringIO.new
  udp.write(udp_packet_str, ip)
  udp_packet_str.rewind
  @udp_packet ||= udp_packet_str.read
end

#make_ether_packet {|packet| ... } ⇒ Object

Yields:

  • (packet)


82
83
84
85
86
87
# File 'lib/ip_frag/generator.rb', line 82

def make_ether_packet
  packet = Mu::Pcap::Ethernet.new(src_mac, dst_mac)
  packet.type = Mu::Pcap::Ethernet::ETHERTYPE_IP
  yield packet
  packet
end

#make_ip_packet(size) {|ip| ... } ⇒ Object

Yields:

  • (ip)


75
76
77
78
79
80
# File 'lib/ip_frag/generator.rb', line 75

def make_ip_packet(size)
  ip = Mu::Pcap::IPv4.new(src_ip, dst_ip)
  ip.proto = Mu::Pcap::IP::IPPROTO_UDP
  yield ip if block_given?
  ip
end

#make_offset(offset, last = false) ⇒ Object



89
90
91
92
93
94
95
96
97
# File 'lib/ip_frag/generator.rb', line 89

def make_offset(offset, last = false)
  offset = offset >> 3
  
  flag = 1
  if last
    flag = 0
  end
  ( flag << 13) | offset
end

#packet_countObject

Get total packet size, it depends on @size and @mtu



57
58
59
60
61
62
63
# File 'lib/ip_frag/generator.rb', line 57

def packet_count
  count, left = @size.divmod(packet_offset)
  if left != 0
    count += 1
  end
  count
end

#packet_leftObject



69
70
71
72
73
# File 'lib/ip_frag/generator.rb', line 69

def packet_left
  left = @size % packet_offset
  left = packet_offset if left == 0
  left
end

#packet_offsetObject



65
66
67
# File 'lib/ip_frag/generator.rb', line 65

def packet_offset
  @mtu & (~7)
end

#split_to_ethernet_packetObject



35
36
37
38
39
40
41
42
43
# File 'lib/ip_frag/generator.rb', line 35

def split_to_ethernet_packet
  ip_packets = split_to_ip_packet
  ip_packets.map do |ip_packet|
    make_ether_packet do |e|
      e.payload = ip_packet
      e.type
    end
  end
end

#split_to_ip_packetObject



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
# File 'lib/ip_frag/generator.rb', line 9

def split_to_ip_packet
  ret = []

  offset = 0
  ret << make_ip_packet(packet_offset) do |p|
    p.offset = make_offset(offset)
    p.payload = udp_offset( contant(udp_size_from(@size), p), 1)
  end
  offset += packet_offset
  
  (packet_count - 2).times do |i|
    ret << make_ip_packet(packet_offset) do |p|
      p.offset = make_offset(offset)
      p.payload = udp_offset( contant(udp_size_from(@size), p), i+2)
    end
    offset += packet_offset
  end
  
  ret << make_ip_packet(packet_left) do |p|
    p.offset = make_offset(offset, true)
    p.payload = udp_offset( contant(udp_size_from(@size), p), packet_count)
  end
  
  ret
end

#udp_offset(udp, packet_num) ⇒ Object



137
138
139
140
# File 'lib/ip_frag/generator.rb', line 137

def udp_offset( udp, packet_num)
  size = @mtu
  udp[(packet_num-1)*size..packet_num*size -1 ]
end

#udp_size_from(ip_size) ⇒ Object



142
143
144
# File 'lib/ip_frag/generator.rb', line 142

def udp_size_from(ip_size)
  ip_size - 8
end

#write_dat(path = '.') ⇒ Object



45
46
47
48
49
50
51
52
# File 'lib/ip_frag/generator.rb', line 45

def write_dat(path = '.')
  split_to_ethernet_packet.each_with_index do |p, i|
    file_name = "#{i+1}.dat"
    file = File.open( File.join(path, file_name), 'wb') do |f|
      p.write(f)
    end
  end
end