├── .gitignore
├── README.md
├── SharpDHCPServer.sln
├── SharpDHCPServerLib
├── DHCPMsgType.cs
├── DHCPOption.cs
├── DHCPReplyOptions.cs
├── DHCPRequest.cs
├── DHCPServer.cs
├── NetworkRoute.cs
├── Properties
│ └── .svn
│ │ ├── all-wcprops
│ │ ├── entries
│ │ └── text-base
│ │ └── AssemblyInfo.cs.svn-base
├── RelayInfo.cs
└── SharpDHCPServerLib.csproj
├── SharpDHCPServer_Sample
├── Program.cs
├── Properties
│ └── .svn
│ │ ├── all-wcprops
│ │ ├── entries
│ │ └── text-base
│ │ └── AssemblyInfo.cs.svn-base
└── SharpDHCPServer_Sample.csproj
└── appveyor.yml
/.gitignore:
--------------------------------------------------------------------------------
1 | # Build Folders (you can keep bin if you'd like, to store dlls and pdbs)
2 | [Bb]in/
3 | [Oo]bj/
4 |
5 | # mstest test results
6 | TestResults
7 |
8 | ## Ignore Visual Studio temporary files, build results, and
9 | ## files generated by popular Visual Studio add-ons.
10 |
11 | # User-specific files
12 | *.suo
13 | *.user
14 | *.sln.docstates
15 |
16 | # Build results
17 | [Dd]ebug/
18 | [Rr]elease/
19 | x64/
20 | *_i.c
21 | *_p.c
22 | *.ilk
23 | *.meta
24 | *.obj
25 | *.pch
26 | *.pdb
27 | *.pgc
28 | *.pgd
29 | *.rsp
30 | *.sbr
31 | *.tlb
32 | *.tli
33 | *.tlh
34 | *.tmp
35 | *.log
36 | *.vspscc
37 | *.vssscc
38 | .builds
39 |
40 | # Visual C++ cache files
41 | ipch/
42 | *.aps
43 | *.ncb
44 | *.opensdf
45 | *.sdf
46 |
47 | # Visual Studio Code
48 | *.vs/
49 |
50 | # Visual Studio profiler
51 | *.psess
52 | *.vsp
53 | *.vspx
54 |
55 | # Guidance Automation Toolkit
56 | *.gpState
57 |
58 | # ReSharper is a .NET coding add-in
59 | _ReSharper*
60 |
61 | # NCrunch
62 | *.ncrunch*
63 | .*crunch*.local.xml
64 |
65 | # Installshield output folder
66 | [Ee]xpress
67 |
68 | # DocProject is a documentation generator add-in
69 | DocProject/buildhelp/
70 | DocProject/Help/*.HxT
71 | DocProject/Help/*.HxC
72 | DocProject/Help/*.hhc
73 | DocProject/Help/*.hhk
74 | DocProject/Help/*.hhp
75 | DocProject/Help/Html2
76 | DocProject/Help/html
77 |
78 | # Click-Once directory
79 | publish
80 |
81 | # Publish Web Output
82 | *.Publish.xml
83 |
84 | # NuGet Packages Directory
85 | packages
86 |
87 | # Windows Azure Build Output
88 | csx
89 | *.build.csdef
90 |
91 | # Windows Store app package directory
92 | AppPackages/
93 |
94 | # Others
95 | [Bb]in
96 | [Oo]bj
97 | sql
98 | TestResults
99 | [Tt]est[Rr]esult*
100 | *.Cache
101 | ClientBin
102 | [Ss]tyle[Cc]op.*
103 | ~$*
104 | *.dbmdl
105 | Generated_Code #added for RIA/Silverlight projects
106 |
107 | # Backup & report files from converting an old project file to a newer
108 | # Visual Studio version. Backup files are not needed, because we have git ;-)
109 | _UpgradeReport_Files/
110 | Backup*/
111 | UpgradeLog*.XML
112 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | A full amanged DHCP Server Library
2 |
3 | Caution ! In C# Sending Broadcast Messaged over a Interface is only possible if gateway is set!
4 |
--------------------------------------------------------------------------------
/SharpDHCPServer.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.29519.87
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SharpDHCPServerLib", "SharpDHCPServerLib\SharpDHCPServerLib.csproj", "{B7FCD134-E2B2-43A9-96C5-3DEDB5669F37}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpDHCPServer_Sample", "SharpDHCPServer_Sample\SharpDHCPServer_Sample.csproj", "{E0A4A539-681E-45E1-84A8-C530BA129856}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Debug|Mixed Platforms = Debug|Mixed Platforms
14 | Debug|x86 = Debug|x86
15 | Release|Any CPU = Release|Any CPU
16 | Release|Mixed Platforms = Release|Mixed Platforms
17 | Release|x86 = Release|x86
18 | EndGlobalSection
19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
20 | {B7FCD134-E2B2-43A9-96C5-3DEDB5669F37}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {B7FCD134-E2B2-43A9-96C5-3DEDB5669F37}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {B7FCD134-E2B2-43A9-96C5-3DEDB5669F37}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
23 | {B7FCD134-E2B2-43A9-96C5-3DEDB5669F37}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
24 | {B7FCD134-E2B2-43A9-96C5-3DEDB5669F37}.Debug|x86.ActiveCfg = Debug|Any CPU
25 | {B7FCD134-E2B2-43A9-96C5-3DEDB5669F37}.Release|Any CPU.ActiveCfg = Release|Any CPU
26 | {B7FCD134-E2B2-43A9-96C5-3DEDB5669F37}.Release|Any CPU.Build.0 = Release|Any CPU
27 | {B7FCD134-E2B2-43A9-96C5-3DEDB5669F37}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
28 | {B7FCD134-E2B2-43A9-96C5-3DEDB5669F37}.Release|Mixed Platforms.Build.0 = Release|Any CPU
29 | {B7FCD134-E2B2-43A9-96C5-3DEDB5669F37}.Release|x86.ActiveCfg = Release|Any CPU
30 | {E0A4A539-681E-45E1-84A8-C530BA129856}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
31 | {E0A4A539-681E-45E1-84A8-C530BA129856}.Debug|Any CPU.Build.0 = Debug|Any CPU
32 | {E0A4A539-681E-45E1-84A8-C530BA129856}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
33 | {E0A4A539-681E-45E1-84A8-C530BA129856}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
34 | {E0A4A539-681E-45E1-84A8-C530BA129856}.Debug|x86.ActiveCfg = Debug|Any CPU
35 | {E0A4A539-681E-45E1-84A8-C530BA129856}.Debug|x86.Build.0 = Debug|Any CPU
36 | {E0A4A539-681E-45E1-84A8-C530BA129856}.Release|Any CPU.ActiveCfg = Release|Any CPU
37 | {E0A4A539-681E-45E1-84A8-C530BA129856}.Release|Any CPU.Build.0 = Release|Any CPU
38 | {E0A4A539-681E-45E1-84A8-C530BA129856}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
39 | {E0A4A539-681E-45E1-84A8-C530BA129856}.Release|Mixed Platforms.Build.0 = Release|Any CPU
40 | {E0A4A539-681E-45E1-84A8-C530BA129856}.Release|x86.ActiveCfg = Release|Any CPU
41 | {E0A4A539-681E-45E1-84A8-C530BA129856}.Release|x86.Build.0 = Release|Any CPU
42 | EndGlobalSection
43 | GlobalSection(SolutionProperties) = preSolution
44 | HideSolutionNode = FALSE
45 | EndGlobalSection
46 | GlobalSection(ExtensibilityGlobals) = postSolution
47 | SolutionGuid = {C1E1858F-6B92-4A3B-8BB3-4009D4243F67}
48 | EndGlobalSection
49 | GlobalSection(SubversionScc) = preSolution
50 | Svn-Managed = True
51 | Manager = AnkhSVN - Subversion Support for Visual Studio
52 | EndGlobalSection
53 | EndGlobal
54 |
--------------------------------------------------------------------------------
/SharpDHCPServerLib/DHCPMsgType.cs:
--------------------------------------------------------------------------------
1 | namespace DotNetProjects.DhcpServer
2 | {
3 | /// DHCP message type
4 | public enum DHCPMsgType
5 | {
6 | /// DHCP DISCOVER message
7 | DHCPDISCOVER = 1,
8 | /// DHCP OFFER message
9 | DHCPOFFER = 2,
10 | /// DHCP REQUEST message
11 | DHCPREQUEST = 3,
12 | /// DHCP DECLINE message
13 | DHCPDECLINE = 4,
14 | /// DHCP ACK message
15 | DHCPACK = 5,
16 | /// DHCP NAK message
17 | DHCPNAK = 6,
18 | /// DHCP RELEASE message
19 | DHCPRELEASE = 7,
20 | /// DHCP INFORM message
21 | DHCPINFORM = 8
22 | }
23 | }
--------------------------------------------------------------------------------
/SharpDHCPServerLib/DHCPOption.cs:
--------------------------------------------------------------------------------
1 | namespace DotNetProjects.DhcpServer
2 | {
3 | /// DHCP option enum
4 | public enum DHCPOption
5 | {
6 | /// Option 1
7 | SubnetMask = 1,
8 | /// Option 2
9 | TimeOffset = 2,
10 | /// Option 3
11 | Router = 3,
12 | /// Option 4
13 | TimeServer = 4,
14 | /// Option 5
15 | NameServer = 5,
16 | /// Option 6
17 | DomainNameServers = 6,
18 | /// Option 7
19 | LogServer = 7,
20 | /// Option 8
21 | CookieServer = 8,
22 | /// Option 9
23 | LPRServer = 9,
24 | /// Option 10
25 | ImpressServer = 10,
26 | /// Option 11
27 | ResourceLocServer = 11,
28 | /// Option 12
29 | HostName = 12,
30 | /// Option 13
31 | BootFileSize = 13,
32 | /// Option 14
33 | MeritDump = 14,
34 | /// Option 15
35 | DomainName = 15,
36 | /// Option 16
37 | SwapServer = 16,
38 | /// Option 17
39 | RootPath = 17,
40 | /// Option 18
41 | ExtensionsPath = 18,
42 | /// Option 19
43 | IpForwarding = 19,
44 | /// Option 20
45 | NonLocalSourceRouting = 20,
46 | /// Option 21
47 | PolicyFilter = 21,
48 | /// Option 22
49 | MaximumDatagramReAssemblySize = 22,
50 | /// Option 23
51 | DefaultIPTimeToLive = 23,
52 | /// Option 24
53 | PathMTUAgingTimeout = 24,
54 | /// Option 25
55 | PathMTUPlateauTable = 25,
56 | /// Option 26
57 | InterfaceMTU = 26,
58 | /// Option 27
59 | AllSubnetsAreLocal = 27,
60 | /// Option 28
61 | BroadcastAddress = 28,
62 | /// Option 29
63 | PerformMaskDiscovery = 29,
64 | /// Option 30
65 | MaskSupplier = 30,
66 | /// Option 31
67 | PerformRouterDiscovery = 31,
68 | /// Option 32
69 | RouterSolicitationAddress = 32,
70 | /// Option 33
71 | StaticRoute = 33,
72 | /// Option 34
73 | TrailerEncapsulation = 34,
74 | /// Option 35
75 | ARPCacheTimeout = 35,
76 | /// Option 36
77 | EthernetEncapsulation = 36,
78 | /// Option 37
79 | TCPDefaultTTL = 37,
80 | /// Option 38
81 | TCPKeepaliveInterval = 38,
82 | /// Option 39
83 | TCPKeepaliveGarbage = 39,
84 | /// Option 40
85 | NetworkInformationServiceDomain = 40,
86 | /// Option 41
87 | NetworkInformationServers = 41,
88 | /// Option 42
89 | NetworkTimeProtocolServers = 42,
90 | /// Option 43
91 | VendorSpecificInformation = 43,
92 | /// Option 44
93 | NetBIOSoverTCPIPNameServer = 44,
94 | /// Option 45
95 | NetBIOSoverTCPIPDatagramDistributionServer = 45,
96 | /// Option 46
97 | NetBIOSoverTCPIPNodeType = 46,
98 | /// Option 47
99 | NetBIOSoverTCPIPScope = 47,
100 | /// Option 48
101 | XWindowSystemFontServer = 48,
102 | /// Option 49
103 | XWindowSystemDisplayManager = 49,
104 | /// Option 50
105 | RequestedIPAddress = 50,
106 | /// Option 51
107 | IPAddressLeaseTime = 51,
108 | /// Option 52
109 | OptionOverload = 52,
110 | /// Option 53
111 | DHCPMessageTYPE = 53,
112 | /// Option 54
113 | ServerIdentifier = 54,
114 | /// Option 55
115 | ParameterRequestList = 55,
116 | /// Option 56
117 | Message = 56,
118 | /// Option 57
119 | MaximumDHCPMessageSize = 57,
120 | /// Option 58
121 | RenewalTimeValue_T1 = 58,
122 | /// Option 59
123 | RebindingTimeValue_T2 = 59,
124 | /// Option 60
125 | Vendorclassidentifier = 60,
126 | /// Option 61
127 | ClientIdentifier = 61,
128 | /// Option 62
129 | NetWateIPDomainName = 62,
130 | /// Option 63
131 | NetWateIPInformation = 63,
132 | /// Option 64
133 | NetworkInformationServicePlusDomain = 64,
134 | /// Option 65
135 | NetworkInformationServicePlusServers = 65,
136 | /// Option 66
137 | TFTPServerName = 66,
138 | /// Option 67
139 | BootfileName = 67,
140 | /// Option 68
141 | MobileIPHomeAgent = 68,
142 | /// Option 69
143 | SMTPServer = 69,
144 | /// Option 70
145 | POP3Server = 70,
146 | /// Option 71
147 | NNTPServer = 71,
148 | /// Option 72
149 | DefaultWWWServer = 72,
150 | /// Option 73
151 | DefaultFingerServer = 73,
152 | /// Option 74
153 | DefaultIRCServer = 74,
154 | /// Option 75
155 | StreetTalkServer = 75,
156 | /// Option 76
157 | STDAServer = 76,
158 | /// Option 82
159 | RelayInfo = 82,
160 | /// Option 121
161 | StaticRoutes = 121,
162 | /// Option 249
163 | StaticRoutesWin = 249,
164 | /// Option 252
165 | Wpad = 252,
166 | /// Option 255 (END option)
167 | END_Option = 255
168 | }
169 | }
--------------------------------------------------------------------------------
/SharpDHCPServerLib/DHCPReplyOptions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Net;
4 |
5 | namespace DotNetProjects.DhcpServer
6 | {
7 | /// Reply options
8 | public class DHCPReplyOptions
9 | {
10 | /// IP address
11 | public IPAddress SubnetMask = null;
12 | /// Next Server IP address (bootp)
13 | public IPAddress ServerIpAddress = null;
14 | /// IP address lease time (seconds)
15 | public UInt32 IPAddressLeaseTime = 60 * 60 * 24;
16 | /// Renewal time (seconds)
17 | public UInt32? RenewalTimeValue_T1 = 60 * 60 * 24;
18 | /// Rebinding time (seconds)
19 | public UInt32? RebindingTimeValue_T2 = 60 * 60 * 24;
20 | /// Domain name
21 | public string DomainName = null;
22 | /// IP address of DHCP server
23 | public IPAddress ServerIdentifier = null;
24 | /// Router (gateway) IP
25 | public IPAddress RouterIP = null;
26 | /// Domain name servers (DNS)
27 | public IPAddress[] DomainNameServers = null;
28 | /// Log server IP
29 | public IPAddress LogServerIP = null;
30 | /// Static routes
31 | public NetworkRoute[] StaticRoutes = null;
32 | /// Other options which will be sent on request
33 | public Dictionary OtherRequestedOptions = new Dictionary();
34 | }
35 | }
--------------------------------------------------------------------------------
/SharpDHCPServerLib/DHCPRequest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Net;
5 | using System.Net.Sockets;
6 | using System.Text;
7 |
8 | namespace DotNetProjects.DhcpServer
9 | {
10 | ///
11 | /// DHCP request
12 | ///
13 | public class DHCPRequest
14 | {
15 | private readonly DHCPServer dhcpServer;
16 | private readonly DHCPPacket requestData;
17 | private Socket requestSocket;
18 | private const int OPTION_OFFSET = 240;
19 | private const int PORT_TO_SEND_TO_CLIENT = 68;
20 | private const int PORT_TO_SEND_TO_RELAY = 67;
21 |
22 | ///
23 | /// Raw DHCP packet
24 | ///
25 | public struct DHCPPacket
26 | {
27 | /// Op code: 1 = boot request, 2 = boot reply
28 | public byte op;
29 | /// Hardware address type
30 | public byte htype;
31 | /// Hardware address length: length of MACID
32 | public byte hlen;
33 | /// Hardware options
34 | public byte hops;
35 | /// Transaction id
36 | public byte[] xid;
37 | /// Elapsed time from trying to boot
38 | public byte[] secs;
39 | /// Flags
40 | public byte[] flags;
41 | /// Client IP
42 | public byte[] ciaddr;
43 | /// Your client IP
44 | public byte[] yiaddr;
45 | /// Server IP
46 | public byte[] siaddr;
47 | /// Relay agent IP
48 | public byte[] giaddr;
49 | /// Client HW address
50 | public byte[] chaddr;
51 | /// Optional server host name
52 | public byte[] sname;
53 | /// Boot file name
54 | public byte[] file;
55 | /// Magic cookie
56 | public byte[] mcookie;
57 | /// Options (rest)
58 | public byte[] options;
59 | }
60 |
61 | internal DHCPRequest(byte[] data, Socket socket, DHCPServer server)
62 | {
63 | dhcpServer = server;
64 | System.IO.BinaryReader rdr;
65 | System.IO.MemoryStream stm = new System.IO.MemoryStream(data, 0, data.Length);
66 | rdr = new System.IO.BinaryReader(stm);
67 | // Reading data
68 | requestData.op = rdr.ReadByte();
69 | requestData.htype = rdr.ReadByte();
70 | requestData.hlen = rdr.ReadByte();
71 | requestData.hops = rdr.ReadByte();
72 | requestData.xid = rdr.ReadBytes(4);
73 | requestData.secs = rdr.ReadBytes(2);
74 | requestData.flags = rdr.ReadBytes(2);
75 | requestData.ciaddr = rdr.ReadBytes(4);
76 | requestData.yiaddr = rdr.ReadBytes(4);
77 | requestData.siaddr = rdr.ReadBytes(4);
78 | requestData.giaddr = rdr.ReadBytes(4);
79 | requestData.chaddr = rdr.ReadBytes(16);
80 | requestData.sname = rdr.ReadBytes(64);
81 | requestData.file = rdr.ReadBytes(128);
82 | requestData.mcookie = rdr.ReadBytes(4);
83 | requestData.options = rdr.ReadBytes(data.Length - OPTION_OFFSET);
84 | requestSocket = socket;
85 | }
86 |
87 | ///
88 | /// Returns array of requested by client options
89 | ///
90 | /// Array of requested by client options
91 | public DHCPOption[] GetRequestedOptionsList()
92 | {
93 | var reqList = this.GetOptionData(DHCPOption.ParameterRequestList);
94 | var optList = new List();
95 | if (reqList != null) foreach (var option in reqList) optList.Add((DHCPOption)option); else return null;
96 | return optList.ToArray();
97 | }
98 |
99 | private byte[] CreateOptionStruct(DHCPMsgType msgType, DHCPReplyOptions replyOptions, Dictionary otherForceOptions, IEnumerable forceOptions)
100 | {
101 | Dictionary options = new Dictionary();
102 |
103 | byte[] resultOptions = null;
104 | // Requested options
105 | var reqList = GetRequestedOptionsList();
106 | // Option82?
107 | var relayInfo = this.GetOptionData(DHCPOption.RelayInfo);
108 | CreateOptionElement(ref resultOptions, DHCPOption.DHCPMessageTYPE, new byte[] { (byte)msgType });
109 | // Server identifier - our IP address
110 | if ((replyOptions != null) && (replyOptions.ServerIdentifier != null))
111 | options[DHCPOption.ServerIdentifier] = replyOptions.ServerIdentifier.GetAddressBytes();
112 |
113 | if (reqList == null && forceOptions != null)
114 | reqList = new DHCPOption[0];
115 |
116 | if (forceOptions == null)
117 | forceOptions = new DHCPOption[0];
118 |
119 | // Requested options
120 | if ((reqList != null) && (replyOptions != null))
121 | foreach (DHCPOption i in reqList.Union(forceOptions).Distinct().OrderBy(x=>(int)x))
122 | {
123 | byte[] optionData = null;
124 | // If it's force option - ignore it. We'll send it later.
125 | if ((otherForceOptions != null) && (otherForceOptions.TryGetValue(i, out optionData)))
126 | continue;
127 | switch (i)
128 | {
129 | case DHCPOption.SubnetMask:
130 | if (replyOptions.SubnetMask != null)
131 | optionData = replyOptions.SubnetMask.GetAddressBytes();
132 | break;
133 | case DHCPOption.Router:
134 | if (replyOptions.RouterIP != null)
135 | optionData = replyOptions.RouterIP.GetAddressBytes();
136 | break;
137 | case DHCPOption.DomainNameServers:
138 | if (replyOptions.DomainNameServers != null)
139 | {
140 | optionData = new byte[] { };
141 | foreach (var dns in replyOptions.DomainNameServers)
142 | {
143 | var dnsserv = dns.GetAddressBytes();
144 | Array.Resize(ref optionData, optionData.Length + 4);
145 | Array.Copy(dnsserv, 0, optionData, optionData.Length - 4, 4);
146 | }
147 | }
148 | break;
149 | case DHCPOption.DomainName:
150 | if (!string.IsNullOrEmpty(replyOptions.DomainName))
151 | optionData = System.Text.Encoding.ASCII.GetBytes(replyOptions.DomainName);
152 | break;
153 | case DHCPOption.ServerIdentifier:
154 | if (replyOptions.ServerIdentifier != null)
155 | optionData = replyOptions.ServerIdentifier.GetAddressBytes();
156 | break;
157 | case DHCPOption.LogServer:
158 | if (replyOptions.LogServerIP != null)
159 | optionData = replyOptions.LogServerIP.GetAddressBytes();
160 | break;
161 | case DHCPOption.StaticRoutes:
162 | case DHCPOption.StaticRoutesWin:
163 | if (replyOptions.StaticRoutes != null)
164 | {
165 | optionData = new byte[] { };
166 | foreach (var route in replyOptions.StaticRoutes)
167 | {
168 | var routeData = route.BuildRouteData();
169 | Array.Resize(ref optionData, optionData.Length + routeData.Length);
170 | Array.Copy(routeData, 0, optionData, optionData.Length - routeData.Length, routeData.Length);
171 | }
172 | }
173 | break;
174 | default:
175 | replyOptions.OtherRequestedOptions.TryGetValue(i, out optionData);
176 | break;
177 | }
178 | if (optionData != null)
179 | {
180 | options[i] = optionData;
181 | }
182 | }
183 |
184 | if (GetMsgType() != DHCPMsgType.DHCPINFORM)
185 | {
186 | // Lease time
187 | if (replyOptions != null)
188 | {
189 | options[DHCPOption.IPAddressLeaseTime] = EncodeTimeOption(replyOptions.IPAddressLeaseTime);
190 | if (replyOptions.RenewalTimeValue_T1.HasValue)
191 | {
192 | options[DHCPOption.RenewalTimeValue_T1] = EncodeTimeOption(replyOptions.RenewalTimeValue_T1.Value);
193 | }
194 | if (replyOptions.RebindingTimeValue_T2.HasValue)
195 | {
196 | options[DHCPOption.RebindingTimeValue_T2] = EncodeTimeOption(replyOptions.RebindingTimeValue_T2.Value);
197 | }
198 | }
199 | }
200 | // Other requested options
201 | if (otherForceOptions != null)
202 | foreach (var option in otherForceOptions.Keys)
203 | {
204 | options[option] = otherForceOptions[option];
205 | if (option == DHCPOption.RelayInfo)
206 | relayInfo = null;
207 | }
208 |
209 | // Option 82? Send it back!
210 | if (relayInfo != null)
211 | {
212 | options[DHCPOption.RelayInfo] = relayInfo;
213 | }
214 |
215 | foreach (var option in options.OrderBy(x=>(int)x.Key))
216 | {
217 | CreateOptionElement(ref resultOptions, option.Key, option.Value);
218 | }
219 |
220 | // Create the end option
221 | Array.Resize(ref resultOptions, resultOptions.Length + 1);
222 | Array.Copy(new byte[] { 255 }, 0, resultOptions, resultOptions.Length - 1, 1);
223 | return resultOptions;
224 | }
225 |
226 | private static byte[] EncodeTimeOption(uint seconds)
227 | {
228 | var leaseTime = new byte[4];
229 | leaseTime[3] = (byte)seconds;
230 | leaseTime[2] = (byte)(seconds >> 8);
231 | leaseTime[1] = (byte)(seconds >> 16);
232 | leaseTime[0] = (byte)(seconds >> 24);
233 | return leaseTime;
234 | }
235 |
236 | static private void CreateOptionElement(ref byte[] options, DHCPOption option, byte[] data)
237 | {
238 | byte[] optionData;
239 |
240 | optionData = new byte[data.Length + 2];
241 | optionData[0] = (byte)option;
242 | optionData[1] = (byte)data.Length;
243 | Array.Copy(data, 0, optionData, 2, data.Length);
244 | if (options == null)
245 | Array.Resize(ref options, (int)optionData.Length);
246 | else
247 | Array.Resize(ref options, options.Length + optionData.Length);
248 | Array.Copy(optionData, 0, options, options.Length - optionData.Length, optionData.Length);
249 | }
250 |
251 | ///
252 | /// Sends DHCP reply
253 | ///
254 | /// Type of DHCP message to send
255 | /// IP for client
256 | /// Reply options (will be sent if requested)
257 | public void SendDHCPReply(DHCPMsgType msgType, IPAddress ip, DHCPReplyOptions replyData)
258 | {
259 | SendDHCPReply(msgType, ip, replyData, null, null);
260 | }
261 |
262 |
263 |
264 | ///
265 | /// Sends DHCP reply
266 | ///
267 | /// Type of DHCP message to send
268 | /// IP for client
269 | /// Reply options (will be sent if requested)
270 | /// Force reply options (will be sent anyway)
271 | public void SendDHCPReply(DHCPMsgType msgType, IPAddress ip, DHCPReplyOptions replyData,
272 | Dictionary otherForceOptions)
273 | {
274 | SendDHCPReply(msgType, ip, replyData, otherForceOptions, null);
275 | }
276 |
277 | ///
278 | /// Sends DHCP reply
279 | ///
280 | /// Type of DHCP message to send
281 | /// IP for client
282 | /// Reply options (will be sent if requested)
283 | /// Force reply options (will be sent anyway)
284 | public void SendDHCPReply(DHCPMsgType msgType, IPAddress ip, DHCPReplyOptions replyData,
285 | IEnumerable forceOptions)
286 | {
287 | SendDHCPReply(msgType, ip, replyData, null, forceOptions);
288 | }
289 |
290 | ///
291 | /// Sends DHCP reply
292 | ///
293 | /// Type of DHCP message to send
294 | /// IP for client
295 | /// Reply options (will be sent if requested)
296 | /// Force reply options (will be sent anyway)
297 | private void SendDHCPReply(DHCPMsgType msgType, IPAddress ip, DHCPReplyOptions replyData, Dictionary otherForceOptions, IEnumerable forceOptions)
298 | {
299 | var replyBuffer = requestData;
300 | replyBuffer.op = 2; // Reply
301 | replyBuffer.yiaddr = ip.GetAddressBytes(); // Client's IP
302 | if (replyData.ServerIpAddress != null)
303 | {
304 | replyBuffer.siaddr = replyData.ServerIpAddress.GetAddressBytes();
305 | }
306 | replyBuffer.options = CreateOptionStruct(msgType, replyData, otherForceOptions, forceOptions); // Options
307 | if (!string.IsNullOrEmpty(dhcpServer.ServerName))
308 | {
309 | var serverNameBytes = Encoding.ASCII.GetBytes(dhcpServer.ServerName);
310 | int len = (serverNameBytes.Length > 63) ? 63 : serverNameBytes.Length;
311 | Array.Copy(serverNameBytes, replyBuffer.sname, len);
312 | replyBuffer.sname[len] = 0;
313 | }
314 | lock (requestSocket)
315 | {
316 | var DataToSend = BuildDataStructure(replyBuffer);
317 | if (DataToSend.Length < 300)
318 | {
319 | var sendArray = new byte[300];
320 | Array.Copy(DataToSend, 0, sendArray, 0, DataToSend.Length);
321 | DataToSend = sendArray;
322 | }
323 |
324 | IPEndPoint endPoint;
325 | if ((replyBuffer.giaddr[0] == 0) && (replyBuffer.giaddr[1] == 0) &&
326 | (replyBuffer.giaddr[2] == 0) && (replyBuffer.giaddr[3] == 0))
327 | {
328 | requestSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true);
329 | endPoint = new IPEndPoint(dhcpServer.BroadcastAddress, PORT_TO_SEND_TO_CLIENT);
330 | if (dhcpServer.SendDhcpAnswerNetworkInterface != null)
331 | {
332 | requestSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, (int)IPAddress.HostToNetworkOrder(dhcpServer.SendDhcpAnswerNetworkInterface.GetIPProperties().GetIPv4Properties().Index));
333 | }
334 | requestSocket.SendTo(DataToSend, endPoint);
335 | }
336 | else
337 | {
338 | requestSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, false);
339 | endPoint = new IPEndPoint(new IPAddress(replyBuffer.giaddr), PORT_TO_SEND_TO_RELAY);
340 | if (dhcpServer.SendDhcpAnswerNetworkInterface != null)
341 | {
342 | requestSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, (int)IPAddress.HostToNetworkOrder(dhcpServer.SendDhcpAnswerNetworkInterface.GetIPProperties().GetIPv4Properties().Index));
343 | }
344 | requestSocket.SendTo(DataToSend, endPoint);
345 | }
346 | }
347 | }
348 |
349 | private static byte[] BuildDataStructure(DHCPPacket packet)
350 | {
351 | byte[] mArray;
352 |
353 | try
354 | {
355 | mArray = new byte[0];
356 | AddOptionElement(new byte[] { packet.op }, ref mArray);
357 | AddOptionElement(new byte[] { packet.htype }, ref mArray);
358 | AddOptionElement(new byte[] { packet.hlen }, ref mArray);
359 | AddOptionElement(new byte[] { packet.hops }, ref mArray);
360 | AddOptionElement(packet.xid, ref mArray);
361 | AddOptionElement(packet.secs, ref mArray);
362 | AddOptionElement(packet.flags, ref mArray);
363 | AddOptionElement(packet.ciaddr, ref mArray);
364 | AddOptionElement(packet.yiaddr, ref mArray);
365 | AddOptionElement(packet.siaddr, ref mArray);
366 | AddOptionElement(packet.giaddr, ref mArray);
367 | AddOptionElement(packet.chaddr, ref mArray);
368 | AddOptionElement(packet.sname, ref mArray);
369 | AddOptionElement(packet.file, ref mArray);
370 |
371 | AddOptionElement(packet.mcookie, ref mArray);
372 | AddOptionElement(packet.options, ref mArray);
373 | return mArray;
374 | }
375 | finally
376 | {
377 | mArray = null;
378 | }
379 | }
380 |
381 | private static void AddOptionElement(byte[] fromValue, ref byte[] targetArray)
382 | {
383 | if (targetArray != null)
384 | Array.Resize(ref targetArray, targetArray.Length + fromValue.Length);
385 | else
386 | Array.Resize(ref targetArray, fromValue.Length);
387 | Array.Copy(fromValue, 0, targetArray, targetArray.Length - fromValue.Length, fromValue.Length);
388 | }
389 |
390 | ///
391 | /// Returns option content
392 | ///
393 | /// Option to retrieve
394 | /// Option content
395 | public byte[] GetOptionData(DHCPOption option)
396 | {
397 | int DHCPId = 0;
398 | byte DDataID, DataLength = 0;
399 | byte[] dumpData;
400 |
401 | DHCPId = (int)option;
402 | for (int i = 0; i < requestData.options.Length; i++)
403 | {
404 | DDataID = requestData.options[i];
405 | if (DDataID == (byte)DHCPOption.END_Option) break;
406 | if (DDataID == DHCPId)
407 | {
408 | DataLength = requestData.options[i + 1];
409 | dumpData = new byte[DataLength];
410 | Array.Copy(requestData.options, i + 2, dumpData, 0, DataLength);
411 | return dumpData;
412 | }
413 | else if (DDataID == 0)
414 | {
415 | }
416 | else
417 | {
418 | DataLength = requestData.options[i + 1];
419 | i += 1 + DataLength;
420 | }
421 | }
422 |
423 | return null;
424 | }
425 |
426 | ///
427 | /// Returns all options
428 | ///
429 | /// Options dictionary
430 | public Dictionary GetAllOptions()
431 | {
432 | var result = new Dictionary();
433 | DHCPOption DDataID;
434 | byte DataLength = 0;
435 |
436 | for (int i = 0; i < requestData.options.Length; i++)
437 | {
438 | DDataID = (DHCPOption)requestData.options[i];
439 | if (DDataID == DHCPOption.END_Option) break;
440 | DataLength = requestData.options[i + 1];
441 | byte[] dumpData = new byte[DataLength];
442 | Array.Copy(requestData.options, i + 2, dumpData, 0, DataLength);
443 | result[DDataID] = dumpData;
444 |
445 | DataLength = requestData.options[i + 1];
446 | i += 1 + DataLength;
447 | }
448 |
449 | return result;
450 | }
451 |
452 | ///
453 | /// Returns ciaddr (client IP address)
454 | ///
455 | /// ciaddr
456 | public IPAddress GetCiaddr()
457 | {
458 | if ((requestData.ciaddr[0] == 0) &&
459 | (requestData.ciaddr[1] == 0) &&
460 | (requestData.ciaddr[2] == 0) &&
461 | (requestData.ciaddr[3] == 0)
462 | ) return null;
463 | return new IPAddress(requestData.ciaddr);
464 | }
465 | ///
466 | /// Returns giaddr (gateway IP address switched by relay)
467 | ///
468 | /// giaddr
469 | public IPAddress GetGiaddr()
470 | {
471 | if ((requestData.giaddr[0] == 0) &&
472 | (requestData.giaddr[1] == 0) &&
473 | (requestData.giaddr[2] == 0) &&
474 | (requestData.giaddr[3] == 0)
475 | ) return null;
476 | return new IPAddress(requestData.giaddr);
477 | }
478 | ///
479 | /// Returns chaddr (client hardware address)
480 | ///
481 | /// chaddr
482 | public byte[] GetChaddr()
483 | {
484 | var res = new byte[requestData.hlen];
485 | Array.Copy(requestData.chaddr, res, requestData.hlen);
486 | return res;
487 | }
488 | ///
489 | /// Returns requested IP (option 50)
490 | ///
491 | /// Requested IP
492 | public IPAddress GetRequestedIP()
493 | {
494 | var ipBytes = GetOptionData(DHCPOption.RequestedIPAddress);
495 | if (ipBytes == null) return null;
496 | return new IPAddress(ipBytes);
497 | }
498 | ///
499 | /// Returns type of DHCP request
500 | ///
501 | /// DHCP message type
502 | public DHCPMsgType GetMsgType()
503 | {
504 | byte[] DData;
505 | DData = GetOptionData(DHCPOption.DHCPMessageTYPE);
506 | if (DData != null)
507 | return (DHCPMsgType)DData[0];
508 | return 0;
509 | }
510 | ///
511 | /// Returns entire content of DHCP packet
512 | ///
513 | /// DHCP packet
514 | public DHCPPacket GetRawPacket()
515 | {
516 | return requestData;
517 | }
518 | ///
519 | /// Returns relay info (option 82)
520 | ///
521 | /// Relay info
522 | public RelayInfo? GetRelayInfo()
523 | {
524 | var result = new RelayInfo();
525 | var relayInfo = GetOptionData(DHCPOption.RelayInfo);
526 | if (relayInfo != null)
527 | {
528 | int i = 0;
529 | while (i < relayInfo.Length)
530 | {
531 | var subOptID = relayInfo[i];
532 | if (subOptID == 1)
533 | {
534 | result.AgentCircuitID = new byte[relayInfo[i + 1]];
535 | Array.Copy(relayInfo, i + 2, result.AgentCircuitID, 0, relayInfo[i + 1]);
536 | }
537 | else if (subOptID == 2)
538 | {
539 | result.AgentRemoteID = new byte[relayInfo[i + 1]];
540 | Array.Copy(relayInfo, i + 2, result.AgentRemoteID, 0, relayInfo[i + 1]);
541 | }
542 | i += 2 + relayInfo[i + 1];
543 | }
544 | return result;
545 | }
546 | return null;
547 | }
548 | }
549 | }
--------------------------------------------------------------------------------
/SharpDHCPServerLib/DHCPServer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net;
3 | using System.Net.NetworkInformation;
4 | using System.Net.Sockets;
5 | using System.Threading;
6 | using System.Threading.Tasks;
7 |
8 | namespace DotNetProjects.DhcpServer
9 | {
10 | ///
11 | /// DHCP Server
12 | ///
13 | public class DHCPServer : IDisposable
14 | {
15 | /// Delegate for DHCP message
16 | public delegate void DHCPDataReceivedEventHandler(DHCPRequest dhcpRequest);
17 |
18 | /// Will be called on any DHCP message
19 | public event DHCPDataReceivedEventHandler OnDataReceived = delegate { };
20 | /// Will be called on any DISCOVER message
21 | public event DHCPDataReceivedEventHandler OnDiscover = delegate { };
22 | /// Will be called on any REQUEST message
23 | public event DHCPDataReceivedEventHandler OnRequest = delegate { };
24 | /// Will be called on any DECLINE message
25 | public event DHCPDataReceivedEventHandler OnDecline = delegate { };
26 | /// Will be called on any DECLINE released
27 | public event DHCPDataReceivedEventHandler OnReleased = delegate { };
28 | /// Will be called on any DECLINE inform
29 | public event DHCPDataReceivedEventHandler OnInform = delegate { };
30 |
31 | /// Server name (optional)
32 | public string ServerName { get; set; }
33 |
34 | private Socket socket = null;
35 | private Task receiveDataTask = null;
36 | private const int PORT_TO_LISTEN_TO = 67;
37 | private IPAddress _bindIp;
38 | private CancellationTokenSource _cancellationTokenSource;
39 |
40 | public event Action UnhandledException;
41 |
42 | public IPAddress BroadcastAddress { get; set; }
43 |
44 | public NetworkInterface SendDhcpAnswerNetworkInterface { get; set; }
45 |
46 | ///
47 | /// Creates DHCP server, it will be started instantly
48 | ///
49 | /// IP address to bind
50 | public DHCPServer(IPAddress bindIp)
51 | {
52 | _bindIp = bindIp;
53 | }
54 |
55 | /// Creates DHCP server, it will be started instantly
56 | public DHCPServer() : this(IPAddress.Any)
57 | {
58 | BroadcastAddress = IPAddress.Broadcast;
59 | }
60 |
61 | /// Starts the DHCP server.
62 | /// Invalid Socket or error while accessing the socket.
63 | /// No permission for requested operation.
64 | public void Start()
65 | {
66 | var ipLocalEndPoint = new IPEndPoint(_bindIp, PORT_TO_LISTEN_TO);
67 | socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
68 | socket.Bind(ipLocalEndPoint);
69 | _cancellationTokenSource = new CancellationTokenSource();
70 | receiveDataTask = new Task(ReceiveDataThread, _cancellationTokenSource.Token, TaskCreationOptions.LongRunning);
71 | receiveDataTask.Start();
72 | }
73 |
74 | /// Disposes DHCP server
75 | public void Dispose()
76 | {
77 | if (socket != null)
78 | {
79 | socket.Close();
80 | socket = null;
81 | }
82 | if (receiveDataTask != null)
83 | {
84 | _cancellationTokenSource.Cancel();
85 | receiveDataTask.Wait();
86 | receiveDataTask = null;
87 | _cancellationTokenSource.Dispose();
88 | _cancellationTokenSource = null;
89 | }
90 | }
91 |
92 | private void ReceiveDataThread()
93 | {
94 | while (!_cancellationTokenSource.IsCancellationRequested)
95 | {
96 | try
97 | {
98 | IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
99 | EndPoint remote = (EndPoint)(sender); var buffer = new byte[1024];
100 | int len = socket.ReceiveFrom(buffer, ref remote);
101 | if (len > 0)
102 | {
103 | Array.Resize(ref buffer, len);
104 | Task.Factory.StartNew(() => DataReceived(buffer));
105 | }
106 | }
107 | catch (Exception ex)
108 | {
109 | if (UnhandledException != null)
110 | UnhandledException(ex);
111 | }
112 | }
113 | }
114 |
115 | private void DataReceived(object o)
116 | {
117 | var data = (byte[])o;
118 | try
119 | {
120 | var dhcpRequest = new DHCPRequest(data, socket, this);
121 | //ccDHCP = new clsDHCP();
122 |
123 |
124 | //data is now in the structure
125 | //get the msg type
126 | OnDataReceived(dhcpRequest);
127 | var msgType = dhcpRequest.GetMsgType();
128 | switch (msgType)
129 | {
130 | case DHCPMsgType.DHCPDISCOVER:
131 | OnDiscover(dhcpRequest);
132 | break;
133 | case DHCPMsgType.DHCPREQUEST:
134 | OnRequest(dhcpRequest);
135 | break;
136 | case DHCPMsgType.DHCPDECLINE:
137 | OnDecline(dhcpRequest);
138 | break;
139 | case DHCPMsgType.DHCPRELEASE:
140 | OnReleased(dhcpRequest);
141 | break;
142 | case DHCPMsgType.DHCPINFORM:
143 | OnInform(dhcpRequest);
144 | break;
145 | //default:
146 | // Console.WriteLine("Unknown DHCP message: " + (int)MsgTyp + " (" + MsgTyp.ToString() + ")");
147 | // break;
148 | }
149 | }
150 | catch (Exception ex)
151 | {
152 | if (UnhandledException != null)
153 | UnhandledException(ex);
154 | }
155 | }
156 | }
157 | }
--------------------------------------------------------------------------------
/SharpDHCPServerLib/NetworkRoute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net;
3 |
4 | namespace DotNetProjects.DhcpServer
5 | {
6 | /// Network route
7 | public struct NetworkRoute
8 | {
9 | /// IP address of destination network
10 | public IPAddress Network;
11 | /// Subnet mask length
12 | public byte NetMaskLength;
13 | /// Gateway
14 | public IPAddress Gateway;
15 |
16 | /// Creates network route
17 | /// IP address to bind
18 | /// Subnet mask length
19 | /// Gateway
20 | public NetworkRoute(IPAddress network, byte netMaskLength, IPAddress gateway)
21 | {
22 | Network = network;
23 | NetMaskLength = netMaskLength;
24 | Gateway = gateway;
25 | }
26 |
27 | /// Creates network route
28 | /// IP address to bind
29 | /// Subnet mask
30 | /// Gateway
31 | public NetworkRoute(IPAddress network, IPAddress netMask, IPAddress gateway)
32 | {
33 | byte length = 0;
34 | var mask = netMask.GetAddressBytes();
35 | for (byte x = 0; x < 4; x++)
36 | {
37 | for (byte b = 0; b < 8; b++)
38 | if (((mask[x] >> (7 - b)) & 1) == 1)
39 | length++;
40 | else break;
41 | }
42 | Network = network;
43 | NetMaskLength = length;
44 | Gateway = gateway;
45 | }
46 |
47 | internal byte[] BuildRouteData()
48 | {
49 | int ipLength;
50 | if (NetMaskLength <= 8) ipLength = 1;
51 | else if (NetMaskLength <= 16) ipLength = 2;
52 | else if (NetMaskLength <= 24) ipLength = 3;
53 | else ipLength = 4;
54 | var res = new byte[1 + ipLength + 4];
55 | res[0] = NetMaskLength;
56 | Array.Copy(Network.GetAddressBytes(), 0, res, 1, ipLength);
57 | Array.Copy(Gateway.GetAddressBytes(), 0, res, 1 + ipLength, 4);
58 | return res;
59 | }
60 | }
61 | }
--------------------------------------------------------------------------------
/SharpDHCPServerLib/Properties/.svn/all-wcprops:
--------------------------------------------------------------------------------
1 | K 25
2 | svn:wc:ra_dav:version-url
3 | V 51
4 | /svn/!svn/ver/2/trunk/SharpDHCPServerLib/Properties
5 | END
6 | AssemblyInfo.cs
7 | K 25
8 | svn:wc:ra_dav:version-url
9 | V 67
10 | /svn/!svn/ver/2/trunk/SharpDHCPServerLib/Properties/AssemblyInfo.cs
11 | END
12 |
--------------------------------------------------------------------------------
/SharpDHCPServerLib/Properties/.svn/entries:
--------------------------------------------------------------------------------
1 | 10
2 |
3 | dir
4 | 2
5 | https://sharpdhcpserver.googlecode.com/svn/trunk/SharpDHCPServerLib/Properties
6 | https://sharpdhcpserver.googlecode.com/svn
7 |
8 |
9 |
10 | 2010-12-06T13:59:04.594212Z
11 | 2
12 | Avdyukhin@gmail.com
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | 3d45f574-0380-fa68-85f7-e44bac00989b
28 |
29 | AssemblyInfo.cs
30 | file
31 |
32 |
33 |
34 |
35 | 2010-12-06T13:51:30.709049Z
36 | c131f1daf5dad472d15168f3252a5ad3
37 | 2010-12-06T13:59:04.594212Z
38 | 2
39 | Avdyukhin@gmail.com
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | 2060
62 |
63 |
--------------------------------------------------------------------------------
/SharpDHCPServerLib/Properties/.svn/text-base/AssemblyInfo.cs.svn-base:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // Управление общими сведениями о сборке осуществляется с помощью
6 | // набора атрибутов. Измените значения этих атрибутов, чтобы изменить сведения,
7 | // связанные со сборкой.
8 | [assembly: AssemblyTitle("SharpDHCPServerLib")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Cluster")]
12 | [assembly: AssemblyProduct("SharpDHCPServerLib")]
13 | [assembly: AssemblyCopyright("Copyright © Cluster 2010")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Параметр ComVisible со значением FALSE делает типы в сборке невидимыми
18 | // для COM-компонентов. Если требуется обратиться к типу в этой сборке через
19 | // COM, задайте атрибуту ComVisible значение TRUE для этого типа.
20 | [assembly: ComVisible(false)]
21 |
22 | // Следующий GUID служит для идентификации библиотеки типов, если этот проект будет видимым для COM
23 | [assembly: Guid("5b90d8af-c01f-4d81-9b8f-2e06c98aac49")]
24 |
25 | // Сведения о версии сборки состоят из следующих четырех значений:
26 | //
27 | // Основной номер версии
28 | // Дополнительный номер версии
29 | // Номер построения
30 | // Редакция
31 | //
32 | // Можно задать все значения или принять номер построения и номер редакции по умолчанию,
33 | // используя "*", как показано ниже:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/SharpDHCPServerLib/RelayInfo.cs:
--------------------------------------------------------------------------------
1 | namespace DotNetProjects.DhcpServer
2 | {
3 | /// DHCP relay information (option 82)
4 | public struct RelayInfo
5 | {
6 | /// Agent circuit ID
7 | public byte[] AgentCircuitID;
8 | /// Agent remote ID
9 | public byte[] AgentRemoteID;
10 | }
11 | }
--------------------------------------------------------------------------------
/SharpDHCPServerLib/SharpDHCPServerLib.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | netstandard2.0;net40
4 | DotNetProjects.DhcpServer
5 | DotNetProjects
6 | DotNetProjects
7 | DotNetProjects.DhcpServer
8 | https://github.com/dotnetprojects/sharp-dhcp-server-lib
9 | MIT
10 | 1.0.0.0
11 | 1.0.0.0
12 | a fully managed DhcpServer
13 | 2019
14 | true
15 | DotNetProjects.DhcpServer
16 | DotNetProjects.DhcpServer
17 | 1.0.0
18 |
19 | true
20 | true
21 | snupkg
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/SharpDHCPServer_Sample/Program.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * ShapDHCPServer (C) 2010, Cluster
3 | * http://clusterrr.com
4 | * http://code.google.com/p/sharpdhcpserver/
5 | *
6 | * DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
7 | * Version 2, December 2004
8 | *
9 | * Copyright (C) 2004 Sam Hocevar
10 | * 14 rue de Plaisance, 75014 Paris, France
11 | * Everyone is permitted to copy and distribute verbatim or modified
12 | * copies of this license document, and changing it is allowed as long
13 | * as the name is changed.
14 | *
15 | * DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
16 | * TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
17 | *
18 | * 0. You just DO WHAT THE FUCK YOU WANT TO.
19 | *
20 | */
21 |
22 | using System;
23 | using System.Collections.Generic;
24 | using System.Linq;
25 | using System.Text;
26 | using System.Net;
27 | using System.Net.NetworkInformation;
28 | using DotNetProjects.DhcpServer;
29 |
30 | namespace Cluster.SharpDHCPServer_Sample
31 | {
32 | class Program
33 | {
34 | const string LOCAL_INTERFACE = "0.0.0.0";
35 | static byte nextIP = 10;
36 | static Dictionary leases = new Dictionary();
37 | static void Main(string[] args)
38 | {
39 | var lst = NetworkInterface.GetAllNetworkInterfaces();
40 |
41 | var eth0If = NetworkInterface.GetAllNetworkInterfaces().FirstOrDefault(x => x.Name == "USB_ETH");
42 | var server = new DHCPServer();
43 | server.ServerName = "SharpDHCPServer";
44 | server.OnDataReceived += Request;
45 | server.BroadcastAddress = IPAddress.Broadcast;
46 | server.SendDhcpAnswerNetworkInterface = eth0If;
47 | server.Start();
48 | Console.WriteLine("Running DHCP server. Press enter to stop it.");
49 | Console.ReadLine();
50 | server.Dispose();
51 | }
52 |
53 | static void Request(DHCPRequest dhcpRequest)
54 | {
55 | try
56 | {
57 | var type = dhcpRequest.GetMsgType();
58 | var mac = ByteArrayToString(dhcpRequest.GetChaddr());
59 | // IP for client
60 | IPAddress ip;
61 | if (!leases.TryGetValue(mac, out ip))
62 | {
63 | ip = new IPAddress(new byte[] {192, 168, 1, nextIP++});
64 | leases[mac] = ip;
65 | }
66 | Console.WriteLine(type.ToString() + " request from " + mac + ", it will be " + ip.ToString());
67 |
68 | var options = dhcpRequest.GetAllOptions();
69 | Console.Write("Options:");
70 | foreach (DHCPOption option in options.Keys)
71 | {
72 | Console.WriteLine(option.ToString() + ": " + ByteArrayToString(options[option]));
73 | }
74 | // Lets show some request info
75 | var requestedOptions = dhcpRequest.GetRequestedOptionsList();
76 | if (requestedOptions != null)
77 | {
78 | Console.Write("Requested options:");
79 | foreach (DHCPOption option in requestedOptions) Console.Write(" " + option.ToString());
80 | Console.WriteLine();
81 | }
82 | // Option 82 info
83 | var relayInfoN = dhcpRequest.GetRelayInfo();
84 | if (relayInfoN != null)
85 | {
86 | var relayInfo = (RelayInfo) relayInfoN;
87 | if (relayInfo.AgentCircuitID != null)
88 | Console.WriteLine("Relay agent circuit ID: " + ByteArrayToString(relayInfo.AgentCircuitID));
89 | if (relayInfo.AgentRemoteID != null)
90 | Console.WriteLine("Relay agent remote ID: " + ByteArrayToString(relayInfo.AgentRemoteID));
91 | }
92 | Console.WriteLine();
93 |
94 | var replyOptions = new DHCPReplyOptions();
95 | // Options should be filled with valid data. Only requested options will be sent.
96 | replyOptions.SubnetMask = IPAddress.Parse("255.255.255.0");
97 | replyOptions.DomainName = "SharpDHCPServer";
98 | replyOptions.ServerIdentifier = IPAddress.Parse("10.0.0.1");
99 | replyOptions.RouterIP = IPAddress.Parse("10.0.0.1");
100 | replyOptions.DomainNameServers = new IPAddress[]
101 | {IPAddress.Parse("192.168.100.2"), IPAddress.Parse("192.168.100.3")};
102 | // Some static routes
103 | replyOptions.StaticRoutes = new NetworkRoute[]
104 | {
105 | new NetworkRoute(IPAddress.Parse("10.0.0.0"), IPAddress.Parse("255.0.0.0"),
106 | IPAddress.Parse("10.0.0.1")),
107 | new NetworkRoute(IPAddress.Parse("192.168.0.0"), IPAddress.Parse("255.255.0.0"),
108 | IPAddress.Parse("10.0.0.1")),
109 | new NetworkRoute(IPAddress.Parse("172.16.0.0"), IPAddress.Parse("255.240.0.0"),
110 | IPAddress.Parse("10.0.0.1")),
111 | new NetworkRoute(IPAddress.Parse("80.252.130.248"), IPAddress.Parse("255.255.255.248"),
112 | IPAddress.Parse("10.0.0.1")),
113 | new NetworkRoute(IPAddress.Parse("80.252.128.88"), IPAddress.Parse("255.255.255.248"),
114 | IPAddress.Parse("10.0.0.1")),
115 | };
116 |
117 | // Lets send reply to client!
118 | if (type == DHCPMsgType.DHCPDISCOVER)
119 | dhcpRequest.SendDHCPReply(DHCPMsgType.DHCPOFFER, ip, replyOptions);
120 | if (type == DHCPMsgType.DHCPREQUEST)
121 | dhcpRequest.SendDHCPReply(DHCPMsgType.DHCPACK, ip, replyOptions);
122 | }
123 | catch (Exception ex)
124 | {
125 | Console.WriteLine(ex);
126 | }
127 | }
128 |
129 | static string ByteArrayToString(byte[] ar)
130 | {
131 | var res = new StringBuilder();
132 | foreach (var b in ar)
133 | {
134 | res.Append(b.ToString("X2"));
135 | }
136 | res.Append(" (");
137 | foreach (var b in ar)
138 | {
139 | if ((b >= 32) && (b <127))
140 | res.Append(Encoding.ASCII.GetString(new byte[] { b }));
141 | else res.Append(" ");
142 | }
143 | res.Append(")");
144 | return res.ToString();
145 | }
146 | }
147 | }
148 |
--------------------------------------------------------------------------------
/SharpDHCPServer_Sample/Properties/.svn/all-wcprops:
--------------------------------------------------------------------------------
1 | K 25
2 | svn:wc:ra_dav:version-url
3 | V 55
4 | /svn/!svn/ver/2/trunk/SharpDHCPServer_Sample/Properties
5 | END
6 | AssemblyInfo.cs
7 | K 25
8 | svn:wc:ra_dav:version-url
9 | V 71
10 | /svn/!svn/ver/2/trunk/SharpDHCPServer_Sample/Properties/AssemblyInfo.cs
11 | END
12 |
--------------------------------------------------------------------------------
/SharpDHCPServer_Sample/Properties/.svn/entries:
--------------------------------------------------------------------------------
1 | 10
2 |
3 | dir
4 | 2
5 | https://sharpdhcpserver.googlecode.com/svn/trunk/SharpDHCPServer_Sample/Properties
6 | https://sharpdhcpserver.googlecode.com/svn
7 |
8 |
9 |
10 | 2010-12-06T13:59:04.594212Z
11 | 2
12 | Avdyukhin@gmail.com
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | 3d45f574-0380-fa68-85f7-e44bac00989b
28 |
29 | AssemblyInfo.cs
30 | file
31 |
32 |
33 |
34 |
35 | 2010-12-06T13:51:30.753049Z
36 | ab4507a3a785b28cd58c3d387576aeb7
37 | 2010-12-06T13:59:04.594212Z
38 | 2
39 | Avdyukhin@gmail.com
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | 2068
62 |
63 |
--------------------------------------------------------------------------------
/SharpDHCPServer_Sample/Properties/.svn/text-base/AssemblyInfo.cs.svn-base:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // Управление общими сведениями о сборке осуществляется с помощью
6 | // набора атрибутов. Измените значения этих атрибутов, чтобы изменить сведения,
7 | // связанные со сборкой.
8 | [assembly: AssemblyTitle("SharpDHCPServer_Sample")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Cluster")]
12 | [assembly: AssemblyProduct("SharpDHCPServer_Sample")]
13 | [assembly: AssemblyCopyright("Copyright © Cluster 2010")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Параметр ComVisible со значением FALSE делает типы в сборке невидимыми
18 | // для COM-компонентов. Если требуется обратиться к типу в этой сборке через
19 | // COM, задайте атрибуту ComVisible значение TRUE для этого типа.
20 | [assembly: ComVisible(false)]
21 |
22 | // Следующий GUID служит для идентификации библиотеки типов, если этот проект будет видимым для COM
23 | [assembly: Guid("b0578828-11d1-4197-8af2-f029410d1672")]
24 |
25 | // Сведения о версии сборки состоят из следующих четырех значений:
26 | //
27 | // Основной номер версии
28 | // Дополнительный номер версии
29 | // Номер построения
30 | // Редакция
31 | //
32 | // Можно задать все значения или принять номер построения и номер редакции по умолчанию,
33 | // используя "*", как показано ниже:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/SharpDHCPServer_Sample/SharpDHCPServer_Sample.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | netcoreapp3.0
4 |
5 |
6 | Debug
7 | x86
8 | 8.0.30703
9 | 2.0
10 | {E0A4A539-681E-45E1-84A8-C530BA129856}
11 | Exe
12 | Properties
13 | Cluster.SharpDHCPServer_Sample
14 | SharpDHCPServer_Sample
15 | 512
16 | true
17 | true
18 | snupkg
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | AnyCPU
27 | true
28 | full
29 | false
30 | bin\Debug\
31 | DEBUG;TRACE
32 | prompt
33 | 4
34 | false
35 |
36 |
37 | x86
38 | pdbonly
39 | true
40 | bin\Release\
41 | TRACE
42 | prompt
43 | 4
44 | false
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | version: 2.0.{build}
2 |
3 | branches:
4 | only:
5 | - master
6 |
7 | dotnet_csproj:
8 | patch: true
9 | file: '**\*.csproj'
10 | version: '{version}'
11 | package_version: '{version}'
12 | assembly_version: '{version}'
13 | file_version: '{version}'
14 | informational_version: '{version}'
15 |
16 | configuration: Debug
17 |
18 | image: Visual Studio 2019
19 |
20 | before_build:
21 | - nuget restore
22 |
23 | build:
24 | project: SharpDHCPServer.sln
25 |
26 | test: off
27 |
28 | artifacts:
29 | - path: '**\DotNetProjects.DhcpServer*.nupkg'
30 |
31 | #uncomment to publish to NuGet
32 | deploy:
33 | provider: NuGet
34 | api_key:
35 | secure: 88aMSx9ONm6ZEyZHiWughpXbF3QGPuYy7yjQxQSt69pDc89aKMBYm8KPOaCIUX9s
36 | artifact: /.*\.nupkg/
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------