dhcp 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 974a171b1f2ae83482f680e59dac9fe86dea5aa5
4
- data.tar.gz: 9c40210dad0d88e8b5fcfd6b387778d347a2ff62
3
+ metadata.gz: ff27859168efaca20656a202f252e830519f8fc1
4
+ data.tar.gz: 8491c7a8772ac71b6fd6e37ca96f58b320fa1c2c
5
5
  SHA512:
6
- metadata.gz: 2792b2a2355d67f79e6494befabe1237c683555c92e4126f5c47a83b02326676f271f823460ccb319e8fb8ca89542f4894f294d4d290f635f7cd9d5b7652690d
7
- data.tar.gz: 1d80d02bcc3c24614083d027415732a02635de52d96ded420e9f3522ea0c506ab372055fa7672e266bf48e4fc1d981d52cdd0fa0fe4bc56b8be97308ded3962c
6
+ metadata.gz: 7b47973dfb41fb5839a987d5c35ac2aa779258db03496a25c2f3a4be7f12d0be67e81253d6fe122345ea80803257d787b095183ba7975ba40361279e8eea740b
7
+ data.tar.gz: 186e766fcb5b3e7134fee72dae11666b556560e0b460233008b22b39c74ec2ddbeee608cbbc13768b36b8f11f3231f5999bcc6c18ce4819512fd18962c6be97f
data/lib/dhcp/s.rb ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative 'server'
4
+ require 'syslog'
5
+ #Syslog.open('dhcp-server')
6
+ s = DHCP::Server.new(:ip => '209.33.249.130', :debug => true, :log => Class.new do ; def err(x) ; STDERR.puts x ; end ; def info(x) ; STDERR.puts x ; end ; def warn(x) ; STDERR.puts x ; end ; def debug(x) ; STDERR.puts x ; end ; end.new)
7
+ s.run
data/lib/dhcp/server.rb CHANGED
@@ -1,34 +1,72 @@
1
1
  #!/usr/bin/env ruby
2
2
  # encoding: ASCII-8BIT
3
3
 
4
+ require 'socket'
5
+ require 'syslog'
4
6
  require_relative 'packet'
5
7
 
6
8
  module DHCP # :nodoc:
7
9
  class Server
10
+ ZERO_IP = IPAddress('0.0.0.0')
11
+
8
12
  def initialize(opt={})
9
- @socket = nil ## UDP server socket
10
- @interval = opt[:interval] || 0.5 ## Sleep interval
13
+ @interval = opt[:interval] || 0.5 ## Sleep (seconds) if no data
14
+ @log = opt[:log] || Syslog ## Logging object (should be open already)
15
+ @server_ip = opt[:ip] || '0.0.0.0' ## Listen on this IP
16
+ @server_port = opt[:port] || 67 ## Listen on this UDP port
17
+ @debug = opt[:debug] || false
18
+
19
+ ## Bind to UDP server port:
20
+ @log.info("Starting DHCP on [#{@server_ip}]:#{@server_port} server at #{Time.now}")
21
+ @sock = UDPSocket.new
22
+ @sock.do_not_reverse_lookup = true
23
+ @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true) ## Permit sending to broadcast address
24
+ unless @sock.bind(@server_ip, 67)
25
+ raise "Failed to bind"
26
+ end
11
27
  end
12
- attr_reader :socket
13
28
 
14
- ## Main server event loop (non-blocking):
29
+ ## Main server event single-iteration function (non-blocking):
15
30
  def run_once
31
+ r,w,e = IO.select([@sock], nil, [@sock], 0)
32
+ if !r.nil? && r.size == 1
33
+ data, src = @sock.recvfrom_nonblock(1500)
34
+ if data.bytesize < 300
35
+ @log.debug("Ignoring packet smaller than BOOTP minimum size") if @debug
36
+ else
37
+ dispatch_packet(data, src[3], src[1])
38
+ end
39
+ return true
40
+ end
41
+ if !e.nil? && e.size == 1
42
+ ## TODO: Handle errors...
43
+ raise "Unhandled error on socket"
44
+ end
45
+ return false
16
46
  end
17
47
 
18
48
  ## Main server event loop (blocking):
19
49
  def run
20
50
  loop do
21
- resut = run_once
51
+ result = run_once
22
52
  sleep @interval if !result ## Sleep if no data was received and no errors occured
23
53
  end
24
54
  end
25
55
 
56
+ def show_packet(pk)
57
+ @log.debug(">>> PACKET: #{pk.type} '#{pk.type_name}' at #{Time.now} >>>")
58
+ pk.to_s.gsub(/\\/,'\\\\').gsub(/[^\x20-\x7e\n]/){|x| '\x' + x.unpack('H2')[0].upcase}.split("\n").each do |i|
59
+ @log.debug("..." + i)
60
+ end
61
+ @log.debug("<<< END OF PACKET <<<")
62
+ end
63
+
26
64
  ## Hand off raw UDP packet data here for parsing and dispatch:
27
65
  def dispatch_packet(data, source_ip, source_port)
28
66
  now = Time.now
29
- Syslog.info("Packet (#{data.size} bytes) from [#{source_ip}]:#{source_port} received at #{now}")
67
+ @log.debug("Packet (#{data.size} bytes) from [#{source_ip}]:#{source_port} received at #{now}")
30
68
  if data.size < 300
31
- Syslog.info("Ignoring small packet (less than BOOTP minimum size.")
69
+ @log.debug("Ignoring small packet (less than BOOTP minimum size.") if @debug
32
70
  return
33
71
  end
34
72
 
@@ -36,8 +74,8 @@ module DHCP # :nodoc:
36
74
  begin
37
75
  packet = DHCP::Packet.new(data)
38
76
  rescue => e
39
- show_packet(packet)
40
- Syslog.err("Error parsing DHCP packet.")
77
+ show_packet(packet) if @debug
78
+ @log.debug("Error parsing DHCP packet.") if @debug
41
79
  return
42
80
  end
43
81
 
@@ -46,36 +84,36 @@ module DHCP # :nodoc:
46
84
  relay = true
47
85
 
48
86
  ## Quick relay sanity-check on GIADDR:
49
- if packet.giaddr == IPAddress.new('0.0.0.0')
50
- Syslog.err("Packet from relay (port 67) has no GIADDR address set. Ignoring.")
87
+ if packet.giaddr == ZERO_IP
88
+ @log.debug("Packet from relay (port 67) has no GIADDR address set. Ignoring.") if @debug
51
89
  return
52
90
  end
53
91
 
54
92
  unless relay_authorized?(source_ip, packet.giaddr)
55
- Syslog.err("Ignoring DHCP packet from unauthorized relay [#{source_ip}].")
93
+ @log.debug("Ignoring DHCP packet from unauthorized relay [#{source_ip}].") if @debug
56
94
  return
57
95
  end
58
96
  elsif source_port == 68 ## DHCP on directly attached subnet
59
97
  relay = false
60
98
 
61
99
  ## Quick relay sanity-check on GIADDR:
62
- if packet.giaddr != IPAddress.new('0.0.0.0')
63
- Syslog.err("Direct (non-relay) packet has set GIADDR to [#{packet.giaddr}] in violation of RFC. Ignoring.")
100
+ if packet.giaddr != ZERO_IP
101
+ @log.debug("Direct (non-relay) packet has set GIADDR to [#{packet.giaddr}] in violation of RFC. Ignoring.") if @debug
64
102
  return
65
103
  end
66
104
  else
67
- Syslog.err("Ignoring packet from UDP port other than 67 (relay) or 68 (direct)")
105
+ @log.debug("Ignoring packet from UDP port other than 67 (relay) or 68 (direct)") if @debug
68
106
  return
69
107
  end
70
108
 
71
109
  ## Ethernet hardware type sanity check:
72
110
  if packet.htype != DHCP::HTYPE[:htype_10mb_ethernet][0] || packet.hlen != DHCP::HTYPE[:htype_10mb_ethernet][1]
73
- Syslog.err("Request hardware type or length doesn't match ETHERNET type and length. Ignoring.")
111
+ @log.debug("Request hardware type or length doesn't match ETHERNET type and length. Ignoring.") if @debug
74
112
  return
75
113
  end
76
114
 
77
115
  if packet.op != DHCP::BOOTREQUEST
78
- Syslog.err("Recived a non-BOOTREQUEST packet. Ignoring.")
116
+ @log.debug("Recived a non-BOOTREQUEST packet. Ignoring.") if @debug
79
117
  return
80
118
  end
81
119
 
@@ -94,11 +132,11 @@ module DHCP # :nodoc:
94
132
  when DHCP::DHCPLEASEQUERY
95
133
  handle_leasequery(packet, source_ip, relay)
96
134
  when DHCP::DHCPOFFER, DHCP::DHCPACK, DHCP::DHCPNAK, DHCP::DHCPFORCERENEW, DHCP::DHCPLEASEUNASSIGNED, DHCP::DHCPLEASEACTIVE, DHCP::DHCPLEASEUNKNOWN
97
- show_packet(packet)
98
- Syslog.err("Packet type #{packet.type_name} in a BOOTREQUEST is invalid.")
135
+ show_packet(packet) if @debug
136
+ @log.debug("Packet type #{packet.type_name} in a BOOTREQUEST is invalid.") if @debug
99
137
  else
100
- show_packet(packet)
101
- Syslog.err("Invalid, unknown, or unhandled DHCP packet type received.")
138
+ show_packet(packet) if @debug
139
+ @log.debug("Invalid, unknown, or unhandled DHCP packet type received.") if @debug
102
140
  end
103
141
  end
104
142
 
@@ -108,32 +146,32 @@ module DHCP # :nodoc:
108
146
 
109
147
  ## Handle DHCPDISCOVER packet:
110
148
  def handle_discover(packet, source_ip, relay)
111
- show_packet(packet)
112
- Syslog.info("handle_discover")
149
+ show_packet(packet) if @debug
150
+ @log.debug("handle_discover") if @debug
113
151
  end
114
152
 
115
153
  ## Handle DHCPREQUEST packet:
116
154
  def handle_request(packet, source_ip, relay)
117
- show_packet(packet)
118
- Syslog.info("handle_request")
155
+ show_packet(packet) if @debug
156
+ @log.debug("handle_request") if @debug
119
157
  end
120
158
 
121
159
  ## Handle DHCPINFORM packet:
122
160
  def handle_inform(packet, source_ip, relay)
123
- show_packet(packet)
124
- Syslog.info("handle_inform")
161
+ show_packet(packet) if @debug
162
+ @log.debug("handle_inform") if @debug
125
163
  end
126
164
 
127
165
  ## Handle DHCPDECLINE packet:
128
166
  def handle_decline(packet, source_ip, relay)
129
- show_packet(packet)
130
- Syslog.info("handle_decline")
167
+ show_packet(packet) if @debug
168
+ @log.debug("handle_decline") if @debug
131
169
  end
132
170
 
133
171
  ## Handle DHCPLEASEQUERY packet:
134
172
  def handle_leasequery(packet, source_ip, relay)
135
- show_packet(packet)
136
- Syslog.info("handle_leasequery")
173
+ show_packet(packet) if @debug
174
+ @log.debug("handle_leasequery") if @debug
137
175
  end
138
176
  end
139
177
 
data/lib/dhcp/version.rb CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  module DHCP # :nodoc:
5
5
  module Version # :nodoc:
6
- STRING = '0.0.3'
6
+ STRING = '0.0.4'
7
7
  end
8
8
  end
9
9
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dhcp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron D. Gifford
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-09 00:00:00.000000000 Z
11
+ date: 2014-12-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ipaddress
@@ -40,6 +40,7 @@ files:
40
40
  - lib/dhcp/dhcp.rb
41
41
  - lib/dhcp/options.rb
42
42
  - lib/dhcp/packet.rb
43
+ - lib/dhcp/s.rb
43
44
  - lib/dhcp/server.rb
44
45
  - lib/dhcp/version.rb
45
46
  homepage: http://www.aarongifford.com/computers/dhcp/
@@ -65,5 +66,5 @@ rubyforge_project: dhcp
65
66
  rubygems_version: 2.4.5
66
67
  signing_key:
67
68
  specification_version: 4
68
- summary: dhcp-0.0.3
69
+ summary: dhcp-0.0.4
69
70
  test_files: []