Skip to content

Commit 8e6a15b

Browse files
committed
Honor client bootp flags in response.
Signed-off-by: s3rj1k <[email protected]>
1 parent b2c93e8 commit 8e6a15b

File tree

6 files changed

+63
-12
lines changed

6 files changed

+63
-12
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ This repository contains a DHCPv4 Relay agent written in Go (Golang). This relay
4242
- [RFC3046: DHCP Relay Agent Information Option](https://www.rfc-editor.org/rfc/rfc3046.html)
4343
- [RFC3396: Encoding Long Options in the DHCPv4](https://www.rfc-editor.org/rfc/rfc3396.html)
4444
- [RFC3527: Link Selection sub-option for the Relay Agent Information Option for DHCPv4](https://www.rfc-editor.org/rfc/rfc3527.html)
45+
- [RFC5010: Relay Agent Flags Suboption](https://www.rfc-editor.org/rfc/rfc5010.html)
4546
- [RFC5107: DHCP Server Identifier Override Suboption](https://www.rfc-editor.org/rfc/rfc5107.html)
4647

4748
### Contribution

dhcpv4-reply-raw.go dhcpv4-reply.go

+20-6
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,16 @@ import (
1414
"code.local/dhcp-relay/specs"
1515
)
1616

17-
func HandleDHCPv4GenericReplyRaw(
17+
const (
18+
UnicastReply uint8 = 0
19+
BroadcastReply uint8 = 1
20+
)
21+
22+
func HandleDHCPv4GenericReply(
1823
cfg *HandleOptions,
1924
dhcpMessageType string,
2025
layerDHCPv4 *layers.DHCPv4,
26+
replyType uint8,
2127
) error {
2228
srcIP := layerDHCPv4.RelayAgentIP.To4()
2329
if srcIP == nil || srcIP.IsLoopback() || srcIP.Equal(net.IPv4zero) || srcIP.Equal(net.IPv4bcast) {
@@ -61,8 +67,6 @@ func HandleDHCPv4GenericReplyRaw(
6167
Flags: layers.IPv4DontFragment,
6268
TTL: cfg.ReplyTTL,
6369
Protocol: layers.IPProtocolUDP,
64-
SrcIP: srcIP.To4(),
65-
DstIP: layerDHCPv4.YourClientIP.To4(),
6670
}
6771

6872
layerUDP := &layers.UDP{
@@ -84,7 +88,17 @@ func HandleDHCPv4GenericReplyRaw(
8488
layerDHCPv4.RelayAgentIP = nil
8589
}
8690

87-
dhcp.SetUnicast(layerDHCPv4)
91+
if replyType == UnicastReply {
92+
layerIPv4.SrcIP = srcIP.To4()
93+
layerIPv4.DstIP = layerDHCPv4.YourClientIP.To4()
94+
95+
dhcp.SetUnicast(layerDHCPv4)
96+
} else if replyType == BroadcastReply {
97+
layerIPv4.SrcIP = net.IPv4zero
98+
layerIPv4.DstIP = net.IPv4bcast
99+
100+
dhcp.SetBroadcast(layerDHCPv4)
101+
}
88102

89103
buffer := gopacket.NewSerializeBuffer()
90104

@@ -124,10 +138,10 @@ func HandleDHCPv4GenericReplyRaw(
124138
cl.Infof("%s 0x%x: DHCP-%s [%d], IfIndex=%d, Src=%s, Dst=%s\n",
125139
logDataOutPrefix, layerDHCPv4.Xid, dhcpMessageType, layerDHCPv4.Len(), ifIndex,
126140
net.JoinHostPort(
127-
srcIP.To4().String(), strconv.Itoa(specs.DHCPv4ServerPort),
141+
layerIPv4.SrcIP.String(), strconv.Itoa(specs.DHCPv4ServerPort),
128142
),
129143
net.JoinHostPort(
130-
layerDHCPv4.YourClientIP.To4().String(), strconv.Itoa(specs.DHCPv4ClientPort),
144+
layerIPv4.DstIP.String(), strconv.Itoa(specs.DHCPv4ClientPort),
131145
),
132146
)
133147

dhcpv4-request.go

-3
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ func HandleDHCPv4GenericRequest(
7171

7272
dhcp.SetRelayAgentInformationOption(layerDHCPv4, subOpt1)
7373

74-
dhcp.SetUnicast(layerDHCPv4)
7574
layerDHCPv4.RelayHops++
7675

7776
for _, addr := range addrs {
@@ -106,8 +105,6 @@ func ForwardDHCPv4RelayedRequest(
106105
dhcpMessageType string,
107106
layerDHCPv4 *layers.DHCPv4,
108107
) error {
109-
dhcp.SetUnicast(layerDHCPv4)
110-
111108
buffer := gopacket.NewSerializeBuffer()
112109

113110
err := gopacket.SerializeLayers(

dhcpv4.go

+15-3
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,21 @@ func HandleDHCPv4(
7272

7373
funcDataInLog()
7474

75-
if err := HandleDHCPv4GenericReplyRaw(cfg, dhcpMessageType, layerDHCPv4); err != nil {
76-
cl.Errorf("Error handling DHCPv4-%s relayed message: %v\n",
77-
dhcpMessageType, err)
75+
bootFileName := dhcp.GetBootFileName(layerDHCPv4)
76+
if bootFileName != "" {
77+
cl.Debugf("Boot File Name: %s\n", bootFileName)
78+
}
79+
80+
if dhcp.IsUnicast(layerDHCPv4) {
81+
if err := HandleDHCPv4GenericReply(cfg, dhcpMessageType, layerDHCPv4, UnicastReply); err != nil {
82+
cl.Errorf("Error handling DHCPv4-%s unicast relayed message: %v\n",
83+
dhcpMessageType, err)
84+
}
85+
} else if dhcp.IsBroadcast(layerDHCPv4) {
86+
if err := HandleDHCPv4GenericReply(cfg, dhcpMessageType, layerDHCPv4, BroadcastReply); err != nil {
87+
cl.Errorf("Error handling DHCPv4-%s broadcast relayed message: %v\n",
88+
dhcpMessageType, err)
89+
}
7890
}
7991
}
8092
}

gpckt/dhcp/utils.go

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package dhcp
2+
3+
import (
4+
"bytes"
5+
6+
"github.com/gopacket/gopacket/layers"
7+
)
8+
9+
func GetBootFileName(layerDHCPv4 *layers.DHCPv4) string {
10+
if len(layerDHCPv4.File) == 0 {
11+
return ""
12+
}
13+
14+
return string(bytes.TrimSpace(layerDHCPv4.File))
15+
}

gpckt/layer.go

+12
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package gpckt
22

33
import (
4+
"fmt"
5+
46
"github.com/gopacket/gopacket"
57
"github.com/gopacket/gopacket/layers"
68
)
@@ -60,3 +62,13 @@ func GetDHCPv4(packet gopacket.Packet) *layers.DHCPv4 {
6062

6163
return layerDHCPv4
6264
}
65+
66+
func CopyDHCPv4(layerDHCPv4 *layers.DHCPv4) (*layers.DHCPv4, error) {
67+
out := new(layers.DHCPv4)
68+
69+
if err := out.DecodeFromBytes(layerDHCPv4.Contents, gopacket.NilDecodeFeedback); err != nil {
70+
return nil, fmt.Errorf("copy error: %w", err)
71+
}
72+
73+
return out, nil
74+
}

0 commit comments

Comments
 (0)