func createParameters(p *parameters, asn uint16) ([]byte, uint8) {
	var param []byte
	initial := []byte{
		2,  
		0,  
		capRefresh,
		0,  
		cap4Byte,
		4,  
	}
	param = append(param, initial...)
	if isASN32(p.ASN32) {
		param = append(param, p.ASN32[:]...)
	} else {
		param = append(param, 0, 0)
		param = append(param, uint16ToByte(asn)...)
	}
	for _, a := range p.AddrFamilies {
		if isIPv4Unicast(a) {
			ip4 := createIPv4Cap()
			param = append(param, ip4...)
		}
		if isIPv6Unicast(a) {
			ip6 := createIPv6Cap()
			param = append(param, ip6...)
		}
	}
	for _, a := range p.AddPath {
		if isIPv4Unicast(a) {
			ip4 := createIPv4AddPath()
			param = append(param, ip4...)
		}
		if isIPv6Unicast(a) {
			ip6 := createIPv6AddPath()
			param = append(param, ip6...)
		}
	}
	param[1] = byte(len(param) - 2)
	return param, uint8(len(param))
}
TODO: Buggy, test!
package main
import (
	"bytes"
	"encoding/binary"
	"net"
)
const (
	bgpVersion = 4
	open         = 1
	update       = 2
	notification = 3
	keepalive    = 4
	refresh      = 5
	asSet      = 1
	asSequence = 2
	headerError     = 1
	openError       = 2
	updateError     = 3
	holdTimeExpired = 4
	fsmError        = 5
	cease           = 6
	minMessage = 19
	maxMessage = 4096
	afiIPv4     uint16 = 1
	afiIPv6     uint16 = 2
	safiUnicast uint8  = 1
)
type bgpid [4]byte
type ipv4Address []byte
type ipv6Address []byte
type twoByteLength [2]byte
type v4Addr struct {
	Mask   uint8
	Prefix net.IP
	ID     uint32
}
type v6Addr struct {
	Mask   uint8
	Prefix net.IP
	ID     uint32
}
type msgOpen struct {
	Version  uint8
	ASN      uint16
	HoldTime uint16
	BGPID    bgpid
	ParamLen uint8
}
func sizeOfStruct(i interface{}) int {
	buf := &bytes.Buffer{}
	binary.Write(buf, binary.BigEndian, i)
	return len(buf.Bytes())
}
func getMarker(b *bytes.Buffer) {
	b.Reset()
	b.Write([]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF})
}
func (p *peer) createKeepAlive() {
	getMarker(p.out)
	k := []byte{0, 0, keepalive}
	p.out.Write(k)
}
func (p *peer) encodeOutgoing() {
	b := p.out.Bytes()
	setSizeOfMessage(&b)
	binary.Write(p.conn, binary.BigEndian, b)
}
func setSizeOfMessage(b *[]byte) {
	s := uint16ToByte(uint16(len(*b)))
	(*b)[16] = s[0]
	(*b)[17] = s[1]
}
func (p *peer) createOpen() {
	getMarker(p.out)
	p.out.Write([]byte{0, 0, open, bgpVersion})
	p.out.Write(getOpenASN(p.asn))
	p.out.Write(uint16ToByte(p.holdtime))
	p.out.Write(p.rid[:])
	param, len := createParameters(&p.param, p.asn)
	p.out.Write([]byte{len})
	p.out.Write(param)
}
func getOpenASN(asn uint16) []byte {
	if asn == 23456 {
		return []byte{0x5b, 0xa0}
	}
	return uint16ToByte(asn)
}
func uint16ToByte(i uint16) []byte {
	a := i / 256
	b := i % 256
	return []byte{byte(a), byte(b)}
}
func uint32ToByte(i uint32) []byte {
	a := i / 16777216
	b := i / 65536
	c := i / 256
	d := i % 256
	return []byte{byte(a), byte(b), byte(c), byte(d)}
}