@@ -31,199 +31,15 @@ go get -u github.com/insomniacslk/dhcp/dhcpv{4,6}
3131The sections below will illustrate how to use the ` dhcpv6 ` and ` dhcpv4 `
3232packages.
3333
34- See more example code at https://github.com/insomniacslk/exdhcp
35-
36-
37- ## DHCPv6 client
38-
39- To run a DHCPv6 transaction on the interface "eth0":
40-
41- ``` go
42- package main
43-
44- import (
45- " log"
46-
47- " github.com/insomniacslk/dhcp/dhcpv6"
48- )
49-
50-
51- func main () {
52- // NewClient sets up a new DHCPv6 client with default values
53- // for read and write timeouts, for destination address and listening
54- // address
55- client := dhcpv6.NewClient ()
56-
57- // Exchange runs a Solicit-Advertise-Request-Reply transaction on the
58- // specified network interface, and returns a list of DHCPv6 packets
59- // (a "conversation") and an error if any. Notice that Exchange may
60- // return a non-empty packet list even if there is an error. This is
61- // intended, because the transaction may fail at any point, and we
62- // still want to know what packets were exchanged until then.
63- // A default Solicit packet will be used during the "conversation",
64- // which can be manipulated by using modifiers.
65- conversation , err := client.Exchange (" eth0" )
66-
67- // Summary() prints a verbose representation of the exchanged packets.
68- for _ , packet := range conversation {
69- log.Print (packet.Summary ())
70- }
71- // error handling is done *after* printing, so we still print the
72- // exchanged packets if any, as explained above.
73- if err != nil {
74- log.Fatal (err)
75- }
76- }
77- ```
78-
79-
80- ## DHCPv6 packet crafting and manipulation
81-
82- ``` go
83- package main
84-
85- import (
86- " log"
87- " net"
88-
89- " github.com/insomniacslk/dhcp/dhcpv6"
90- " github.com/insomniacslk/dhcp/iana"
91- )
92-
93- func main () {
94- // In this example we create and manipulate a DHCPv6 solicit packet
95- // and encapsulate it in a relay packet. To to this, we use
96- // `dhcpv6.DHCPv6Message` and `dhcpv6.DHCPv6Relay`, two structures
97- // that implement the `dhcpv6.DHCPv6` interface.
98- // Then print the wire-format representation of the packet.
99-
100- // Create the DHCPv6 Solicit first, using the interface "eth0"
101- // to get the MAC address
102- msg , err := dhcpv6.NewSolicitForInterface (" eth0" )
103- if err != nil {
104- log.Fatal (err)
105- }
106-
107- // In this example I want to redact the MAC address of my
108- // network interface, so instead of replacing it manually,
109- // I will show how to use modifiers for the purpose.
110- // A Modifier is simply a function that can be applied on
111- // a DHCPv6 object to manipulate it. Here we use it to
112- // replace the MAC address with a dummy one.
113- // Modifiers can be passed to many functions, for example
114- // to constructors, `Exchange()`, `Solicit()`, etc. Check
115- // the source code to know where to use them.
116- // Existing modifiers are implemented in dhcpv6/modifiers.go .
117- mac , err := net.ParseMAC (" 00:fa:ce:b0:0c:00" )
118- if err != nil {
119- log.Fatal (err)
120- }
121- duid := dhcpv6.Duid {
122- Type: dhcpv6.DUID_LLT ,
123- HwType: iana.HwTypeEthernet ,
124- Time: dhcpv6.GetTime (),
125- LinkLayerAddr: mac,
126- }
127- // As suggested above, an alternative is to call
128- // dhcpv6.NewSolicitForInterface("eth0", dhcpv6.WithCLientID(duid))
129- msg = dhcpv6.WithClientID (duid)(msg)
130-
131- // Now encapsulate the message in a DHCPv6 relay.
132- // As per RFC3315, the link-address and peer-address have
133- // to be set by the relay agent. We use dummy values here.
134- linkAddr := net.ParseIP (" 2001:0db8::1" )
135- peerAddr := net.ParseIP (" 2001:0db8::2" )
136- relay , err := dhcpv6.EncapsulateRelay (msg, dhcpv6.MessageTypeRelayForward , linkAddr, peerAddr)
137- if err != nil {
138- log.Fatal (err)
139- }
140-
141- // Print a verbose representation of the relay packet, that will also
142- // show a short representation of the inner Solicit message.
143- // To print a detailed summary of the inner packet, extract it
144- // first from the relay using `relay.GetInnerMessage()`.
145- log.Print (relay.Summary ())
146-
147- // And finally, print the bytes that would be sent on the wire
148- log.Print (relay.ToBytes ())
34+ * [ dhcpv6 client] ( examples/client6/ )
35+ * [ dhcpv6 server] ( examples/server6/ )
36+ * [ dhcpv6 packet crafting] ( examples/packetcrafting6 )
37+ * TODO dhcpv4 client
38+ * TODO dhcpv4 server
39+ * TODO dhcpv4 packet crafting
14940
150- // Note: there are many more functions in the library, check them
151- // out in the source code. For example, if you want to decode a
152- // byte stream into a DHCPv6 message or relay, you can use
153- // `dhcpv6.FromBytes`.
154- }
155- ```
156-
157- The output (slightly modified for readability) is
158- ```
159- $ go run main.go
160- 2018/11/08 13:56:31 DHCPv6Relay
161- messageType=RELAY-FORW
162- hopcount=0
163- linkaddr=2001:db8::1
164- peeraddr=2001:db8::2
165- options=[OptRelayMsg{relaymsg=DHCPv6Message(messageType=SOLICIT transactionID=0x9e0242, 4 options)}]
166-
167- 2018/11/08 13:56:31 [12 0 32 1 13 184 0 0 0 0 0 0 0 0 0 0 0 1 32 1 13 184
168- 0 0 0 0 0 0 0 0 0 0 0 2 0 9 0 52 1 158 2 66 0 1 0 14
169- 0 1 0 1 35 118 253 15 0 250 206 176 12 0 0 6 0 4 0 23
170- 0 24 0 8 0 2 0 0 0 3 0 12 250 206 176 12 0 0 14 16 0
171- 0 21 24]
172- ```
173-
174- ## DHCPv6 server
175-
176- A DHCPv6 server requires the user to implement a request handler. Basically the
177- user has to provide the logic to answer to each packet. The library offers a few
178- facilities to forge response packets, e.g. ` NewAdvertiseFromSolicit ` ,
179- ` NewReplyFromDHCPv6Message ` and so on. Look at the source code to see what's
180- available.
181-
182- An example server that will print (but not reply to) the client's request is
183- shown below:
184-
185- ``` go
186- package main
187-
188- import (
189- " log"
190- " net"
191-
192- " github.com/insomniacslk/dhcp/dhcpv6"
193- )
194-
195- func handler (conn net .PacketConn , peer net .Addr , m dhcpv6 .DHCPv6 ) {
196- // this function will just print the received DHCPv6 message, without replying
197- log.Print (m.Summary ())
198- }
19941
200- func main () {
201- laddr := net.UDPAddr {
202- IP: net.ParseIP (" ::1" ),
203- Port: dhcpv6.DefaultServerPort ,
204- }
205- server := dhcpv6.NewServer (laddr, handler)
206-
207- defer server.Close ()
208- if err := server.ActivateAndServe (); err != nil {
209- log.Panic (err)
210- }
211- }
212- ```
213-
214- ## DHCPv4 client
215-
216- TODO
217-
218-
219- ## DHCPv4 packet parsing
220-
221- TODO
222-
223-
224- ## DHCPv4 server
225-
226- TODO
42+ See more example code at https://github.com/insomniacslk/exdhcp
22743
22844
22945# Public projects that use it
23551* Bender from Pinterest, a library for load-testing, https://github.com/pinterest/bender
23652* FBender from Facebook, a tool for load-testing based on Bender, https://github.com/facebookincubator/fbender
23753* CoreDHCP, a fast, multithreaded, modular and extensible DHCP server, https://github.com/coredhcp/coredhcp
54+ * u-root, an embeddable root file system, https://github.com/u-root/u-root
0 commit comments