From 6400dfc9e84eb13dfafda8d05967937b2c843736 Mon Sep 17 00:00:00 2001 From: KonnovKM Date: Thu, 6 Jul 2023 10:30:19 +0300 Subject: header size check Signed-off-by: KonnovKM --- dhcpv4/nclient4/conn_unix.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/dhcpv4/nclient4/conn_unix.go b/dhcpv4/nclient4/conn_unix.go index 7f79f50..67ac94c 100644 --- a/dhcpv4/nclient4/conn_unix.go +++ b/dhcpv4/nclient4/conn_unix.go @@ -105,14 +105,15 @@ func (upc *BroadcastRawUDPConn) ReadFrom(b []byte) (int, net.Addr, error) { } ipHdr := ipv4(buf.Data()) + headerLength := ipHdr.headerLength() - if !buf.Has(int(ipHdr.headerLength())) { + if !buf.Has(int(headerLength)) { continue } - ipHdr = ipv4(buf.Consume(int(ipHdr.headerLength()))) + ipHdr = ipv4(buf.Consume(int(headerLength))) - if ipHdr.transportProtocol() != udpProtocolNumber { + if headerLength <= protocol || ipHdr.transportProtocol() != udpProtocolNumber { continue } -- cgit v1.2.3 From 5cb40274fad0127d68a331c30f667a38d9a064e0 Mon Sep 17 00:00:00 2001 From: Boneyan Date: Thu, 6 Jul 2023 10:42:41 +0300 Subject: Update go.mod Signed-off-by: KonnovKM --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 1f7e78f..13737a0 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/insomniacslk/dhcp +module github.com/Boneyan/dhcp go 1.18 -- cgit v1.2.3 From 9a7bd94b2257403a935f45867ca01d15558cf9d4 Mon Sep 17 00:00:00 2001 From: KonnovKM Date: Mon, 17 Jul 2023 15:07:00 +0300 Subject: no continue Signed-off-by: KonnovKM --- dhcpv4/nclient4/conn_unix.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dhcpv4/nclient4/conn_unix.go b/dhcpv4/nclient4/conn_unix.go index 67ac94c..239d007 100644 --- a/dhcpv4/nclient4/conn_unix.go +++ b/dhcpv4/nclient4/conn_unix.go @@ -113,8 +113,10 @@ func (upc *BroadcastRawUDPConn) ReadFrom(b []byte) (int, net.Addr, error) { ipHdr = ipv4(buf.Consume(int(headerLength))) - if headerLength <= protocol || ipHdr.transportProtocol() != udpProtocolNumber { - continue + if headerLength > protocol { + if ipHdr.transportProtocol() != udpProtocolNumber { + continue + } } if !buf.Has(udpHdrLen) { -- cgit v1.2.3 From 5bd60b59380c32813c0ada2a119fe602ec6fd5bf Mon Sep 17 00:00:00 2001 From: Boneyan Date: Mon, 17 Jul 2023 15:13:20 +0300 Subject: revert go.mod Signed-off-by: KonnovKM --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 13737a0..1f7e78f 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/Boneyan/dhcp +module github.com/insomniacslk/dhcp go 1.18 -- cgit v1.2.3 From 5d50c4b48aaac59c1c09b9174c8a7fd014c6eb75 Mon Sep 17 00:00:00 2001 From: KonnovKM Date: Thu, 27 Jul 2023 14:46:22 +0300 Subject: isValid() method Signed-off-by: KonnovKM --- dhcpv4/nclient4/conn_unix.go | 16 ++++--------- dhcpv4/nclient4/ipv4.go | 54 ++++++++++++++++++++++++++++++++++++-------- 2 files changed, 48 insertions(+), 22 deletions(-) diff --git a/dhcpv4/nclient4/conn_unix.go b/dhcpv4/nclient4/conn_unix.go index 239d007..1495dc2 100644 --- a/dhcpv4/nclient4/conn_unix.go +++ b/dhcpv4/nclient4/conn_unix.go @@ -99,24 +99,16 @@ func (upc *BroadcastRawUDPConn) ReadFrom(b []byte) (int, net.Addr, error) { pkt = pkt[:n] buf := uio.NewBigEndianBuffer(pkt) - // To read the header length, access data directly. - if !buf.Has(ipv4MinimumSize) { - continue - } - ipHdr := ipv4(buf.Data()) - headerLength := ipHdr.headerLength() - if !buf.Has(int(headerLength)) { + if !ipHdr.isValid(n) { continue } - ipHdr = ipv4(buf.Consume(int(headerLength))) + ipHdr = ipv4(buf.Consume(int(ipHdr.headerLength()))) - if headerLength > protocol { - if ipHdr.transportProtocol() != udpProtocolNumber { - continue - } + if ipHdr.transportProtocol() != udpProtocolNumber { + continue } if !buf.Has(udpHdrLen) { diff --git a/dhcpv4/nclient4/ipv4.go b/dhcpv4/nclient4/ipv4.go index c221965..3a3427a 100644 --- a/dhcpv4/nclient4/ipv4.go +++ b/dhcpv4/nclient4/ipv4.go @@ -14,6 +14,7 @@ // // This file contains code taken from gVisor. +//go:build go1.12 // +build go1.12 package nclient4 @@ -26,16 +27,17 @@ import ( ) const ( - versIHL = 0 - tos = 1 - totalLen = 2 - id = 4 - flagsFO = 6 - ttl = 8 - protocol = 9 - checksumOff = 10 - srcAddr = 12 - dstAddr = 16 + versIHL = 0 + tos = 1 + totalLen = 2 + id = 4 + flagsFO = 6 + ttl = 8 + protocol = 9 + checksumOff = 10 + srcAddr = 12 + dstAddr = 16 + ipVersionShift = 4 ) // transportProtocolNumber is the number of a transport protocol. @@ -95,8 +97,40 @@ const ( // ipv4AddressSize is the size, in bytes, of an IPv4 address. ipv4AddressSize = 4 + + // IPv4Version is the version of the IPv4 protocol. + ipv4Version = 4 ) +// IPVersion returns the version of IP used in the given packet. It returns -1 +// if the packet is not large enough to contain the version field. +func ipVersion(b []byte) int { + // Length must be at least offset+length of version field. + if len(b) < versIHL+1 { + return -1 + } + return int(b[versIHL] >> ipVersionShift) +} + +// IsValid performs basic validation on the packet. +func (b ipv4) isValid(pktSize int) bool { + if len(b) < ipv4MinimumSize { + return false + } + + hlen := int(b.headerLength()) + tlen := int(b.totalLength()) + if hlen < ipv4MinimumSize || hlen > tlen || tlen > pktSize { + return false + } + + if ipVersion(b) != ipv4Version { + return false + } + + return true +} + // headerLength returns the value of the "header length" field of the ipv4 // header. func (b ipv4) headerLength() uint8 { -- cgit v1.2.3 From 5771e168857a17094174b2c31c44fe7779ca0b75 Mon Sep 17 00:00:00 2001 From: KonnovKM Date: Mon, 31 Jul 2023 15:28:32 +0300 Subject: stylistic changes Signed-off-by: KonnovKM --- dhcpv4/nclient4/ipv4.go | 63 ++++++++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/dhcpv4/nclient4/ipv4.go b/dhcpv4/nclient4/ipv4.go index 3a3427a..f2bfb65 100644 --- a/dhcpv4/nclient4/ipv4.go +++ b/dhcpv4/nclient4/ipv4.go @@ -27,17 +27,16 @@ import ( ) const ( - versIHL = 0 - tos = 1 - totalLen = 2 - id = 4 - flagsFO = 6 - ttl = 8 - protocol = 9 - checksumOff = 10 - srcAddr = 12 - dstAddr = 16 - ipVersionShift = 4 + versIHL = 0 + tos = 1 + totalLen = 2 + id = 4 + flagsFO = 6 + ttl = 8 + protocol = 9 + checksumOff = 10 + srcAddr = 12 + dstAddr = 16 ) // transportProtocolNumber is the number of a transport protocol. @@ -102,7 +101,7 @@ const ( ipv4Version = 4 ) -// IPVersion returns the version of IP used in the given packet. It returns -1 +// ipVersion returns the version of IP used in the given packet. It returns -1 // if the packet is not large enough to contain the version field. func ipVersion(b []byte) int { // Length must be at least offset+length of version field. @@ -112,24 +111,9 @@ func ipVersion(b []byte) int { return int(b[versIHL] >> ipVersionShift) } -// IsValid performs basic validation on the packet. -func (b ipv4) isValid(pktSize int) bool { - if len(b) < ipv4MinimumSize { - return false - } - - hlen := int(b.headerLength()) - tlen := int(b.totalLength()) - if hlen < ipv4MinimumSize || hlen > tlen || tlen > pktSize { - return false - } - - if ipVersion(b) != ipv4Version { - return false - } - - return true -} +const ( + ipVersionShift = 4 +) // headerLength returns the value of the "header length" field of the ipv4 // header. @@ -204,6 +188,25 @@ func (b ipv4) encode(i *ipv4Fields) { copy(b[dstAddr:dstAddr+ipv4AddressSize], i.DstAddr) } +// isValid performs basic validation on the packet. +func (b ipv4) isValid(pktSize int) bool { + if len(b) < ipv4MinimumSize { + return false + } + + hlen := int(b.headerLength()) + tlen := int(b.totalLength()) + if hlen < ipv4MinimumSize || hlen > tlen || tlen > pktSize { + return false + } + + if ipVersion(b) != ipv4Version { + return false + } + + return true +} + const ( udpSrcPort = 0 udpDstPort = 2 -- cgit v1.2.3