tun: OpenBSD: use an API to parse the address, drop endianess dance

The net package has all we need and internally repesents addresses
as byte arrays.

<netinet6/in6.h> `struct in6_addr` is just a union over differnt sized
byte arrays, so chosing u_int8_t[16] lets us access addresses byte-wise
and thus no longer need to fiddle with multi-byte values and host vs.
network byte order.
This commit is contained in:
Klemens Nanni 2024-09-29 23:56:05 +03:00
parent fc8b15a909
commit b5016d7f97
No known key found for this signature in database

View file

@ -4,10 +4,8 @@
package tun package tun
import ( import (
"encoding/binary"
"fmt" "fmt"
"strconv" "net"
"strings"
"syscall" "syscall"
"unsafe" "unsafe"
@ -25,12 +23,15 @@ type in6_addrlifetime struct {
ia6t_pltime uint32 ia6t_pltime uint32
} }
// Match types from the net package, effectively being [16]byte for IPv6 addresses.
type in6_addr [16]uint8
type sockaddr_in6 struct { type sockaddr_in6 struct {
sin6_len uint8 sin6_len uint8
sin6_family uint8 sin6_family uint8
sin6_port uint16 sin6_port uint16
sin6_flowinfo uint32 sin6_flowinfo uint32
sin6_addr [8]uint16 sin6_addr in6_addr
sin6_scope_id uint32 sin6_scope_id uint32
} }
@ -70,6 +71,12 @@ func (tun *TunAdapter) setupAddress(addr string) error {
var sfd int var sfd int
var err error var err error
ip, _, err := net.ParseCIDR(addr)
if err != nil {
tun.log.Errorf("Error in ParseCIDR: %v", err)
return err
}
// Create system socket // Create system socket
if sfd, err = unix.Socket(unix.AF_INET6, unix.SOCK_DGRAM, 0); err != nil { if sfd, err = unix.Socket(unix.AF_INET6, unix.SOCK_DGRAM, 0); err != nil {
tun.log.Printf("Create AF_INET6 socket failed: %v", err) tun.log.Printf("Create AF_INET6 socket failed: %v", err)
@ -86,12 +93,9 @@ func (tun *TunAdapter) setupAddress(addr string) error {
copy(ar.ifra_name[:], tun.Name()) copy(ar.ifra_name[:], tun.Name())
ar.ifra_addr.sin6_len = uint8(unsafe.Sizeof(ar.ifra_addr)) ar.ifra_addr.sin6_len = uint8(unsafe.Sizeof(ar.ifra_addr))
ar.ifra_addr.sin6_family = unix.AF_INET6 ar.ifra_addr.sin6_family = unix.AF_INET6
parts := strings.Split(strings.Split(addr, "/")[0], ":")
for i := 0; i < 8; i++ { for i := range in6_aliasreq.sin6_addr {
addr, _ := strconv.ParseUint(parts[i], 16, 16) sa6.sin6_addr[i] = addr[i]
b := make([]byte, 16)
binary.LittleEndian.PutUint16(b, uint16(addr))
ar.ifra_addr.sin6_addr[i] = uint16(binary.BigEndian.Uint16(b))
} }
// Set the interface address // Set the interface address