diff --git a/conn/bind_windows.go b/conn/bind_windows.go
index d744987..42e06ad 100644
--- a/conn/bind_windows.go
+++ b/conn/bind_windows.go
@@ -121,10 +121,8 @@ func (*WinRingBind) ParseEndpoint(s string) (Endpoint, error) {
 	if (addrinfo.Family != windows.AF_INET && addrinfo.Family != windows.AF_INET6) || addrinfo.Addrlen > unsafe.Sizeof(WinRingEndpoint{}) {
 		return nil, windows.ERROR_INVALID_ADDRESS
 	}
-	var src []byte
 	var dst [unsafe.Sizeof(WinRingEndpoint{})]byte
-	unsafeSlice(unsafe.Pointer(&src), unsafe.Pointer(addrinfo.Addr), int(addrinfo.Addrlen))
-	copy(dst[:], src)
+	copy(dst[:], unsafe.Slice((*byte)(unsafe.Pointer(addrinfo.Addr)), addrinfo.Addrlen))
 	return (*WinRingEndpoint)(unsafe.Pointer(&dst[0])), nil
 }
 
@@ -581,21 +579,3 @@ func bindSocketToInterface6(handle windows.Handle, interfaceIndex uint32) error
 	const IPV6_UNICAST_IF = 31
 	return windows.SetsockoptInt(handle, windows.IPPROTO_IPV6, IPV6_UNICAST_IF, int(interfaceIndex))
 }
-
-// unsafeSlice updates the slice slicePtr to be a slice
-// referencing the provided data with its length & capacity set to
-// lenCap.
-//
-// TODO: when Go 1.16 or Go 1.17 is the minimum supported version,
-// update callers to use unsafe.Slice instead of this.
-func unsafeSlice(slicePtr, data unsafe.Pointer, lenCap int) {
-	type sliceHeader struct {
-		Data unsafe.Pointer
-		Len  int
-		Cap  int
-	}
-	h := (*sliceHeader)(slicePtr)
-	h.Data = data
-	h.Len = lenCap
-	h.Cap = lenCap
-}
diff --git a/tun/wintun/session_windows.go b/tun/wintun/session_windows.go
index ffa9380..f023baf 100644
--- a/tun/wintun/session_windows.go
+++ b/tun/wintun/session_windows.go
@@ -67,7 +67,7 @@ func (session Session) ReceivePacket() (packet []byte, err error) {
 		err = e1
 		return
 	}
-	unsafeSlice(unsafe.Pointer(&packet), unsafe.Pointer(r0), int(packetSize))
+	packet = unsafe.Slice((*byte)(unsafe.Pointer(r0)), packetSize)
 	return
 }
 
@@ -81,28 +81,10 @@ func (session Session) AllocateSendPacket(packetSize int) (packet []byte, err er
 		err = e1
 		return
 	}
-	unsafeSlice(unsafe.Pointer(&packet), unsafe.Pointer(r0), int(packetSize))
+	packet = unsafe.Slice((*byte)(unsafe.Pointer(r0)), packetSize)
 	return
 }
 
 func (session Session) SendPacket(packet []byte) {
 	syscall.Syscall(procWintunSendPacket.Addr(), 2, session.handle, uintptr(unsafe.Pointer(&packet[0])), 0)
 }
-
-// unsafeSlice updates the slice slicePtr to be a slice
-// referencing the provided data with its length & capacity set to
-// lenCap.
-//
-// TODO: when Go 1.16 or Go 1.17 is the minimum supported version,
-// update callers to use unsafe.Slice instead of this.
-func unsafeSlice(slicePtr, data unsafe.Pointer, lenCap int) {
-	type sliceHeader struct {
-		Data unsafe.Pointer
-		Len  int
-		Cap  int
-	}
-	h := (*sliceHeader)(slicePtr)
-	h.Data = data
-	h.Len = lenCap
-	h.Cap = lenCap
-}