golang.zx2c4.com/wireguard/windows@v0.5.4-0.20230123132234-dcc0eb72a04b/conf/writer.go (about)

     1  /* SPDX-License-Identifier: MIT
     2   *
     3   * Copyright (C) 2019-2022 WireGuard LLC. All Rights Reserved.
     4   */
     5  
     6  package conf
     7  
     8  import (
     9  	"fmt"
    10  	"net/netip"
    11  	"strings"
    12  	"unsafe"
    13  
    14  	"golang.org/x/sys/windows"
    15  	"golang.zx2c4.com/wireguard/windows/driver"
    16  	"golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
    17  )
    18  
    19  func (conf *Config) ToWgQuick() string {
    20  	var output strings.Builder
    21  	output.WriteString("[Interface]\n")
    22  
    23  	output.WriteString(fmt.Sprintf("PrivateKey = %s\n", conf.Interface.PrivateKey.String()))
    24  
    25  	if conf.Interface.ListenPort > 0 {
    26  		output.WriteString(fmt.Sprintf("ListenPort = %d\n", conf.Interface.ListenPort))
    27  	}
    28  
    29  	if len(conf.Interface.Addresses) > 0 {
    30  		addrStrings := make([]string, len(conf.Interface.Addresses))
    31  		for i, address := range conf.Interface.Addresses {
    32  			addrStrings[i] = address.String()
    33  		}
    34  		output.WriteString(fmt.Sprintf("Address = %s\n", strings.Join(addrStrings[:], ", ")))
    35  	}
    36  
    37  	if len(conf.Interface.DNS)+len(conf.Interface.DNSSearch) > 0 {
    38  		addrStrings := make([]string, 0, len(conf.Interface.DNS)+len(conf.Interface.DNSSearch))
    39  		for _, address := range conf.Interface.DNS {
    40  			addrStrings = append(addrStrings, address.String())
    41  		}
    42  		addrStrings = append(addrStrings, conf.Interface.DNSSearch...)
    43  		output.WriteString(fmt.Sprintf("DNS = %s\n", strings.Join(addrStrings[:], ", ")))
    44  	}
    45  
    46  	if conf.Interface.MTU > 0 {
    47  		output.WriteString(fmt.Sprintf("MTU = %d\n", conf.Interface.MTU))
    48  	}
    49  
    50  	if len(conf.Interface.PreUp) > 0 {
    51  		output.WriteString(fmt.Sprintf("PreUp = %s\n", conf.Interface.PreUp))
    52  	}
    53  	if len(conf.Interface.PostUp) > 0 {
    54  		output.WriteString(fmt.Sprintf("PostUp = %s\n", conf.Interface.PostUp))
    55  	}
    56  	if len(conf.Interface.PreDown) > 0 {
    57  		output.WriteString(fmt.Sprintf("PreDown = %s\n", conf.Interface.PreDown))
    58  	}
    59  	if len(conf.Interface.PostDown) > 0 {
    60  		output.WriteString(fmt.Sprintf("PostDown = %s\n", conf.Interface.PostDown))
    61  	}
    62  	if conf.Interface.TableOff {
    63  		output.WriteString("Table = off\n")
    64  	}
    65  
    66  	for _, peer := range conf.Peers {
    67  		output.WriteString("\n[Peer]\n")
    68  
    69  		output.WriteString(fmt.Sprintf("PublicKey = %s\n", peer.PublicKey.String()))
    70  
    71  		if !peer.PresharedKey.IsZero() {
    72  			output.WriteString(fmt.Sprintf("PresharedKey = %s\n", peer.PresharedKey.String()))
    73  		}
    74  
    75  		if len(peer.AllowedIPs) > 0 {
    76  			addrStrings := make([]string, len(peer.AllowedIPs))
    77  			for i, address := range peer.AllowedIPs {
    78  				addrStrings[i] = address.String()
    79  			}
    80  			output.WriteString(fmt.Sprintf("AllowedIPs = %s\n", strings.Join(addrStrings[:], ", ")))
    81  		}
    82  
    83  		if !peer.Endpoint.IsEmpty() {
    84  			output.WriteString(fmt.Sprintf("Endpoint = %s\n", peer.Endpoint.String()))
    85  		}
    86  
    87  		if peer.PersistentKeepalive > 0 {
    88  			output.WriteString(fmt.Sprintf("PersistentKeepalive = %d\n", peer.PersistentKeepalive))
    89  		}
    90  	}
    91  	return output.String()
    92  }
    93  
    94  func (config *Config) ToDriverConfiguration() (*driver.Interface, uint32) {
    95  	preallocation := unsafe.Sizeof(driver.Interface{}) + uintptr(len(config.Peers))*unsafe.Sizeof(driver.Peer{})
    96  	for i := range config.Peers {
    97  		preallocation += uintptr(len(config.Peers[i].AllowedIPs)) * unsafe.Sizeof(driver.AllowedIP{})
    98  	}
    99  	var c driver.ConfigBuilder
   100  	c.Preallocate(uint32(preallocation))
   101  	c.AppendInterface(&driver.Interface{
   102  		Flags:      driver.InterfaceHasPrivateKey | driver.InterfaceHasListenPort,
   103  		ListenPort: config.Interface.ListenPort,
   104  		PrivateKey: config.Interface.PrivateKey,
   105  		PeerCount:  uint32(len(config.Peers)),
   106  	})
   107  	for i := range config.Peers {
   108  		flags := driver.PeerHasPublicKey | driver.PeerHasPersistentKeepalive
   109  		if !config.Peers[i].PresharedKey.IsZero() {
   110  			flags |= driver.PeerHasPresharedKey
   111  		}
   112  		var endpoint winipcfg.RawSockaddrInet
   113  		if !config.Peers[i].Endpoint.IsEmpty() {
   114  			addr, err := netip.ParseAddr(config.Peers[i].Endpoint.Host)
   115  			if err == nil {
   116  				flags |= driver.PeerHasEndpoint
   117  				endpoint.SetAddrPort(netip.AddrPortFrom(addr, config.Peers[i].Endpoint.Port))
   118  			}
   119  		}
   120  		c.AppendPeer(&driver.Peer{
   121  			Flags:               flags,
   122  			PublicKey:           config.Peers[i].PublicKey,
   123  			PresharedKey:        config.Peers[i].PresharedKey,
   124  			PersistentKeepalive: config.Peers[i].PersistentKeepalive,
   125  			Endpoint:            endpoint,
   126  			AllowedIPsCount:     uint32(len(config.Peers[i].AllowedIPs)),
   127  		})
   128  		for j := range config.Peers[i].AllowedIPs {
   129  			a := &driver.AllowedIP{Cidr: uint8(config.Peers[i].AllowedIPs[j].Bits())}
   130  			copy(a.Address[:], config.Peers[i].AllowedIPs[j].Addr().AsSlice())
   131  			if config.Peers[i].AllowedIPs[j].Addr().Is4() {
   132  				a.AddressFamily = windows.AF_INET
   133  			} else if config.Peers[i].AllowedIPs[j].Addr().Is6() {
   134  				a.AddressFamily = windows.AF_INET6
   135  			}
   136  			c.AppendAllowedIP(a)
   137  		}
   138  	}
   139  	return c.Interface()
   140  }