blondy-dhcpd 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ae29d05c58be4df1ba9ed1bbb261272d0704fc3e
4
+ data.tar.gz: fc31f7a889b49b1c20d0af9d8da1d6ffbe794852
5
+ SHA512:
6
+ metadata.gz: 2574b0e7689854ac759562a3c66a1f67e2e4126f554421c9401c6665e944f36fc46e98d017eef47b84a03357691903d30252459560267ae695ec7b6e3056fcc4
7
+ data.tar.gz: 362900db015b131b562e166308fc125207e1c15c43a626c2d0f2a7300128863ac0c1f8fc20590344761dfe6c6a6b63f955ac5080237221fd4bd84e3e884ad401
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+
3
+ rvm:
4
+ - 1.9.3
5
+ - 2.0.0
6
+
7
+ script: bundle exec rspec -c spec/
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'net-dhcp', :git => 'https://github.com/mjtko/net-dhcp-ruby'
6
+ gem 'log4r'
7
+ gem 'eventmachine'
8
+
9
+ group :test do
10
+ gem 'rspec'
11
+ end
12
+
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Pavel Novitskiy
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,47 @@
1
+ [![Gem Version](https://badge.fury.io/rb/blondy-dhcpd.png)](http://badge.fury.io/rb/net-dhcp) [![Build Status](https://travis-ci.org/presto53/blondy-dhcpd.png)](https://travis-ci.org/presto53/blondy-dhcpd)
2
+
3
+ blondy-dhcpd
4
+ ============
5
+ DHCPd with remote pools
6
+
7
+ Installation
8
+ ---------------
9
+
10
+ Configuration
11
+ ---------------
12
+
13
+ Usage
14
+ ---------------
15
+
16
+ Contributing
17
+ ---------------
18
+
19
+ 1. Fork it
20
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
21
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
22
+ 4. Push to the branch (`git push origin my-new-feature`)
23
+ 5. Create new Pull Request
24
+
25
+ Licensing
26
+ ---------------
27
+ The MIT License (MIT)
28
+
29
+ Copyright (c) 2013 Pavel Novitskiy
30
+
31
+ Permission is hereby granted, free of charge, to any person obtaining a copy
32
+ of this software and associated documentation files (the "Software"), to deal
33
+ in the Software without restriction, including without limitation the rights
34
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
35
+ copies of the Software, and to permit persons to whom the Software is
36
+ furnished to do so, subject to the following conditions:
37
+
38
+ The above copyright notice and this permission notice shall be included in all
39
+ copies or substantial portions of the Software.
40
+
41
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
42
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
43
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
44
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
45
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
46
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
47
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'blondy/dhcpd/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "blondy-dhcpd"
8
+ spec.version = Blondy::Dhcpd::VERSION
9
+ spec.authors = ["Pavel Novitskiy"]
10
+ spec.email = ["altusensix@gmail.com"]
11
+ spec.description = %q{DHCPd with remote pool configurations obtained via HTTP API from blondy-server}
12
+ spec.summary = %q{DHCPd with remote pools}
13
+ spec.homepage = "https://github.com/presto53/blondy-dhcpd"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec", "~> 2.0"
24
+
25
+ spec.add_runtime_dependency 'eventmachine', '>= 0.12.0'
26
+ spec.add_runtime_dependency 'net-dhcp', '>= 1.1.1'
27
+ spec.add_runtime_dependency 'log4r'
28
+ end
@@ -0,0 +1,10 @@
1
+ require 'eventmachine'
2
+ require_relative 'dhcpd/server'
3
+
4
+ module Blondy
5
+ module DHCPD
6
+ EM.run do
7
+ EM.open_datagram_socket('0.0.0.0', 67, Server)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,26 @@
1
+ require 'net-dhcp'
2
+ require 'ostruct'
3
+ require 'ipaddr'
4
+
5
+ module Blondy
6
+ module DHCPD
7
+ class Dispatcher
8
+ def self.dispatch(data, ip, port)
9
+ @data = DHCP::Message.from_udp_payload(data)
10
+ reply = OpenStruct.new
11
+ if @data.kind_of?(DHCP::Discover)
12
+ if @data.giaddr == 0
13
+ reply.ip = '255.255.255.255'
14
+ reply.port = 68
15
+ else
16
+ reply.ip = IPAddr.new(@data.giaddr, family = Socket::AF_INET).to_s
17
+ reply.port = 67
18
+ end
19
+ reply.data = DHCP::Offer.new
20
+ end
21
+ reply.data.xid = @data.xid
22
+ reply
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,18 @@
1
+ require 'net-dhcp'
2
+ require 'eventmachine'
3
+ require 'socket'
4
+
5
+ module Blondy
6
+ module DHCPD
7
+ # Main class for handling connections
8
+ class Server < EM::Connection
9
+ # Fires up Dispatcher and send reply back by callback
10
+ def receive_data(data)
11
+ ip, port = Socket.unpack_sockaddr_in(get_peername)
12
+ action = proc { Dispatcher.dispatch(data, ip, port) }
13
+ callback = proc { |reply| send_datagram(reply.data.pack, reply.ip, reply.port) if reply }
14
+ EM.defer(action,callback)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,5 @@
1
+ module Blondy
2
+ module Dhcpd
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,81 @@
1
+ require 'spec_helper'
2
+
3
+ module Blondy
4
+ module DHCPD
5
+ describe 'Dispatcher' do
6
+ subject(:dispatcher) {Dispatcher}
7
+ let(:from_ip) {'0.0.0.0'}
8
+ let(:from_port) {67}
9
+ let(:discover) do
10
+ d = DHCP::Discover.new
11
+ d.xid = 123456789
12
+ d
13
+ end
14
+
15
+ context 'receive dhcp message' do
16
+ it 'reply xid is the same as received xid' do
17
+ dispatcher.dispatch(discover.pack, from_ip, from_port).data.xid.should == discover.xid
18
+ end
19
+ end
20
+
21
+ context 'receive discovery message' do
22
+ # RFC 2131 (http://www.ietf.org/rfc/rfc2131.txt)
23
+ #
24
+ # http://stackoverflow.com/a/10757849
25
+ #
26
+ # If the 'giaddr' field in a DHCP message from a client is non-zero,
27
+ # the server sends any return messages to the 'DHCP server' port on
28
+ # the BOOTP relay agent whose address appears in 'giaddr'.
29
+ # If the 'giaddr' field is zero and the 'ciaddr' field is nonzero,
30
+ # then the server unicasts DHCPOFFER and DHCPACK messages to the address in 'ciaddr'.
31
+ # If 'giaddr' is zero and 'ciaddr' is zero, and the broadcast bit is set,
32
+ # then the server broadcasts DHCPOFFER and DHCPACK messages to 0xffffffff.
33
+ # If the broadcast bit is not set and 'giaddr' is zero and 'ciaddr' is zero,
34
+ # then the server unicasts DHCPOFFER and DHCPACK messages to the client's hardware address
35
+ # and 'yiaddr' address. In all cases, when 'giaddr' is zero,
36
+ # the server broadcasts any DHCPNAK messages to 0xffffffff.
37
+ let(:reply) do
38
+ reply = OpenStruct.new
39
+ reply.data = DHCP::Offer.new
40
+ reply
41
+ end
42
+
43
+ context 'giaddr != 0' do
44
+ it 'send offer message to bootp relay' do
45
+ pending
46
+ data.giaddr = IPAddr.new('192.168.3.3').to_i
47
+ server.should_receive(:send_datagram).with(reply.data.pack, '192.168.3.3', 67)
48
+ server.receive_data(data.pack)
49
+ end
50
+ end
51
+ context 'giaddr = 0 and ciaddr != 0' do
52
+ it 'send offer message to client by unicast' do
53
+ pending
54
+ data.ciaddr = IPAddr.new('192.168.3.3').to_i
55
+ server.should_receive(:send_data).with(reply.data.pack, '192.168.3.3', 68)
56
+ server.receive_data(data.pack)
57
+ end
58
+ end
59
+ context 'giaddr = 0 and ciaddr = 0 and flags = 1' do
60
+ it 'send offer message to client by broadcast to 255.255.255.255' do
61
+ pending
62
+ data.flags = 1
63
+ server.should_receive(:send_data).with(reply.data.pack, '', 68)
64
+ server.receive_data(data.pack)
65
+ end
66
+ end
67
+ context 'giaddr = 0 and ciaddr = 0 and flags = 0' do
68
+ it 'send offer message to client by unicast it to client hwaddr and yiaddr' do
69
+ pending
70
+ data.yiaddr = IPAddr.new('192.168.3.200').to_i
71
+ data.chaddr = [80, 229, 73, 35, 15, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
72
+ reply.data.chaddr.should eq(data.chaddr)
73
+ server.should_receive(:send_data).with(reply.data.pack, '192.168.3.200', 68)
74
+ server.receive_data(data.pack)
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
81
+
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ # nasty hack to avoid creating new thread
4
+ module EM
5
+ def self.defer(op, callback)
6
+ callback.call(op.call)
7
+ end
8
+ end
9
+
10
+ module Blondy
11
+ module DHCPD
12
+ describe 'Server' do
13
+ subject(:server) {EM.open_datagram_socket('127.0.0.1', 67, Server)}
14
+ let(:dispatcher) {Dispatcher}
15
+ let(:discover) do
16
+ d = DHCP::Discover.new
17
+ d.xid = 123456789
18
+ d
19
+ end
20
+
21
+ before(:each) do
22
+ allow(EM).to receive(:open_udp_socket).and_return 0
23
+ allow(Socket).to receive(:unpack_sockaddr_in).and_return ['0.0.0.0', '68']
24
+ end
25
+
26
+ context 'receive dhcp message' do
27
+ before(:each) do
28
+ @ip, @port = Socket.unpack_sockaddr_in(server.get_peername)
29
+ end
30
+ it 'run dispatcher' do
31
+ dispatcher.should_receive(:dispatch).with(discover.pack, @ip, @port)
32
+ server.receive_data(discover.pack)
33
+ end
34
+ it 'send reply' do
35
+ server.should_receive(:send_datagram)
36
+ server.receive_data(discover.pack)
37
+ end
38
+ end
39
+
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,46 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+
8
+ require 'net-dhcp'
9
+ require 'eventmachine'
10
+ require 'ostruct'
11
+ require 'ipaddr'
12
+ require 'rspec'
13
+
14
+ spec_root = File.dirname(File.absolute_path(__FILE__))
15
+ Dir.glob(spec_root + '/../lib/blondy/dhcpd/*') {|file| require file}
16
+
17
+
18
+ RSpec.configure do |config|
19
+ config.treat_symbols_as_metadata_keys_with_true_values = true
20
+ config.run_all_when_everything_filtered = true
21
+ config.filter_run :focus
22
+
23
+ # Run specs in random order to surface order dependencies. If you find an
24
+ # order dependency and want to debug it, you can fix the order by providing
25
+ # the seed, which is printed after each run.
26
+ # --seed 1234
27
+ config.order = 'random'
28
+ end
29
+
30
+ # Wrap for running examples inside eventmachine reactor
31
+ RSpec::Core::Example.class_eval do
32
+ alias ignorant_run run
33
+
34
+ def run(example_group_instance, reporter)
35
+ Fiber.new do
36
+ EM.run do
37
+ df = EM::DefaultDeferrable.new
38
+ result = nil
39
+ df.callback { |x| EM.stop_event_loop; Fiber.yield result }
40
+ result = ignorant_run example_group_instance, reporter
41
+ df.succeed
42
+ end
43
+ end.resume
44
+ end
45
+ end
46
+
metadata ADDED
@@ -0,0 +1,147 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: blondy-dhcpd
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Pavel Novitskiy
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-12-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: eventmachine
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 0.12.0
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: 0.12.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: net-dhcp
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: 1.1.1
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 1.1.1
83
+ - !ruby/object:Gem::Dependency
84
+ name: log4r
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: DHCPd with remote pool configurations obtained via HTTP API from blondy-server
98
+ email:
99
+ - altusensix@gmail.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - ".gitignore"
105
+ - ".rspec"
106
+ - ".travis.yml"
107
+ - Gemfile
108
+ - LICENSE.txt
109
+ - README.md
110
+ - Rakefile
111
+ - blondy-dhcpd.gemspec
112
+ - lib/blondy/dhcpd.rb
113
+ - lib/blondy/dhcpd/dispatcher.rb
114
+ - lib/blondy/dhcpd/server.rb
115
+ - lib/blondy/dhcpd/version.rb
116
+ - spec/dispatcher_spec.rb
117
+ - spec/server_spec.rb
118
+ - spec/spec_helper.rb
119
+ homepage: https://github.com/presto53/blondy-dhcpd
120
+ licenses:
121
+ - MIT
122
+ metadata: {}
123
+ post_install_message:
124
+ rdoc_options: []
125
+ require_paths:
126
+ - lib
127
+ required_ruby_version: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ required_rubygems_version: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ requirements: []
138
+ rubyforge_project:
139
+ rubygems_version: 2.1.11
140
+ signing_key:
141
+ specification_version: 4
142
+ summary: DHCPd with remote pools
143
+ test_files:
144
+ - spec/dispatcher_spec.rb
145
+ - spec/server_spec.rb
146
+ - spec/spec_helper.rb
147
+ has_rdoc: