summaryrefslogtreecommitdiffhomepage
path: root/README.md
diff options
context:
space:
mode:
Diffstat (limited to 'README.md')
-rw-r--r--README.md93
1 files changed, 91 insertions, 2 deletions
diff --git a/README.md b/README.md
index 017dd3a..f977363 100644
--- a/README.md
+++ b/README.md
@@ -73,10 +73,99 @@ func main() {
```
-## DHCPv6 packet parsing
+## DHCPv6 packet crafting and manipulation
-TODO
+```
+package main
+
+import (
+ "log"
+ "net"
+ "github.com/insomniacslk/dhcp/dhcpv6"
+ "github.com/insomniacslk/dhcp/iana"
+)
+
+func main() {
+ // In this example we create and manipulate a DHCPv6 solicit packet
+ // and encapsulate it in a relay packet. To to this, we use
+ // `dhcpv6.DHCPv6Message` and `dhcpv6.DHCPv6Relay`, two structures
+ // that implement the `dhcpv6.DHCPv6` interface.
+ // Then print the wire-format representation of the packet.
+
+ // Create the DHCPv6 Solicit first, using the interface "eth0"
+ // to get the MAC address
+ msg, err := dhcpv6.NewSolicitForInterface("eth0")
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ // In this example I want to redact the MAC address of my
+ // network interface, so instead of replacing it manually,
+ // I will show how to use modifiers for the purpose.
+ // A Modifier is simply a function that can be applied on
+ // a DHCPv6 object to manipulate it. Here we use it to
+ // replace the MAC address with a dummy one.
+ // Modifiers can be passed to many functions, for example
+ // to constructors, `Exchange()`, `Solicit()`, etc. Check
+ // the source code to know where to use them.
+ // Existing modifiers are implemented in dhcpv6/modifiers.go .
+ mac, err := net.ParseMAC("00:fa:ce:b0:0c:00")
+ if err != nil {
+ log.Fatal(err)
+ }
+ duid := dhcpv6.Duid{
+ Type: dhcpv6.DUID_LLT,
+ HwType: iana.HwTypeEthernet,
+ Time: dhcpv6.GetTime(),
+ LinkLayerAddr: mac,
+ }
+ // As suggested above, an alternative is to call
+ // dhcpv6.NewSolicitForInterface("eth0", dhcpv6.WithCLientID(duid))
+ msg = dhcpv6.WithClientID(duid)(msg)
+
+ // Now encapsulate the message in a DHCPv6 relay.
+ // As per RFC3315, the link-address and peer-address have
+ // to be set by the relay agent. We use dummy values here.
+ linkAddr := net.ParseIP("2001:0db8::1")
+ peerAddr := net.ParseIP("2001:0db8::2")
+ relay, err := dhcpv6.EncapsulateRelay(msg, dhcpv6.MessageTypeRelayForward, linkAddr, peerAddr)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ // Print a verbose representation of the relay packet, that will also
+ // show a short representation of the inner Solicit message.
+ // To print a detailed summary of the inner packet, extract it
+ // first from the relay using `relay.GetInnerMessage()`.
+ log.Print(relay.Summary())
+
+ // And finally, print the bytes that would be sent on the wire
+ log.Print(relay.ToBytes())
+
+ // Note: there are many more functions in the library, check them
+ // out in the source code. For example, if you want to decode a
+ // byte stream into a DHCPv6 message or relay, you can use
+ // `dhcpv6.FromBytes`.
+}
+```
+
+The output (slightly modified for readability) is
+```
+$ go run main.go
+2018/11/08 13:56:31 DHCPv6Relay
+ messageType=RELAY-FORW
+ hopcount=0
+ linkaddr=2001:db8::1
+ peeraddr=2001:db8::2
+ options=[OptRelayMsg{relaymsg=DHCPv6Message(messageType=SOLICIT transactionID=0x9e0242, 4 options)}]
+
+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
+ 0 0 0 0 0 0 0 0 0 0 0 2 0 9 0 52 1 158 2 66 0 1 0 14
+ 0 1 0 1 35 118 253 15 0 250 206 176 12 0 0 6 0 4 0 23
+ 0 24 0 8 0 2 0 0 0 3 0 12 250 206 176 12 0 0 14 16 0
+ 0 21 24]
+```
## DHCPv6 server