@@ -31,199 +31,15 @@ go get -u github.com/insomniacslk/dhcp/dhcpv{4,6}
31
31
The sections below will illustrate how to use the ` dhcpv6 ` and ` dhcpv4 `
32
32
packages.
33
33
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
149
40
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
- }
199
41
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
227
43
228
44
229
45
# Public projects that use it
235
51
* Bender from Pinterest, a library for load-testing, https://github.com/pinterest/bender
236
52
* FBender from Facebook, a tool for load-testing based on Bender, https://github.com/facebookincubator/fbender
237
53
* 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