summaryrefslogtreecommitdiffhomepage
path: root/iana/archtype.go
blob: d85870ccde5decc851be76545d6cdcf449669427 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package iana

import (
	"fmt"
	"strings"

	"github.com/u-root/uio/uio"
)

// Arch encodes an architecture type per RFC 4578, Section 2.1.
type Arch uint16

// See RFC 4578, 5970, and http://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xhtml#processor-architecture
const (
	INTEL_X86PC       Arch = 0
	NEC_PC98          Arch = 1
	EFI_ITANIUM       Arch = 2
	DEC_ALPHA         Arch = 3
	ARC_X86           Arch = 4
	INTEL_LEAN_CLIENT Arch = 5
	EFI_IA32          Arch = 6
	EFI_X86_64        Arch = 7
	EFI_XSCALE        Arch = 8
	EFI_BC            Arch = 9
	EFI_ARM32         Arch = 10
	EFI_ARM64         Arch = 11
	PPC_OPEN_FIRMWARE Arch = 12
	PPC_EPAPR         Arch = 13
	PPC_OPAL          Arch = 14
	EFI_X86_HTTP      Arch = 15
	EFI_X86_64_HTTP   Arch = 16
	EFI_BC_HTTP       Arch = 17
	EFI_ARM32_HTTP    Arch = 18
	EFI_ARM64_HTTP    Arch = 19
	INTEL_X86PC_HTTP  Arch = 20
	UBOOT_ARM32       Arch = 21
	UBOOT_ARM64       Arch = 22
	UBOOT_ARM32_HTTP  Arch = 23
	UBOOT_ARM64_HTTP  Arch = 24
	EFI_RISCV32       Arch = 25
	EFI_RISCV32_HTTP  Arch = 26
	EFI_RISCV64       Arch = 27
	EFI_RISCV64_HTTP  Arch = 28
	EFI_RISCV128      Arch = 29
	EFI_RISCV128_HTTP Arch = 30
	S390_BASIC        Arch = 31
	S390_EXTENDED     Arch = 32
	EFI_MIPS32        Arch = 33
	EFI_MIPS64        Arch = 34
	EFI_SUNWAY32      Arch = 35
	EFI_SUNWAY64      Arch = 36
)

// archTypeToStringMap maps an Arch to a mnemonic name
var archTypeToStringMap = map[Arch]string{
	INTEL_X86PC:       "Intel x86PC",
	NEC_PC98:          "NEC/PC98",
	EFI_ITANIUM:       "EFI Itanium",
	DEC_ALPHA:         "DEC Alpha",
	ARC_X86:           "Arc x86",
	INTEL_LEAN_CLIENT: "Intel Lean Client",
	EFI_IA32:          "EFI IA32",
	EFI_XSCALE:        "EFI Xscale",
	EFI_X86_64:        "EFI x86-64",
	EFI_BC:            "EFI BC",
	EFI_ARM32:         "EFI ARM32",
	EFI_ARM64:         "EFI ARM64",
	PPC_OPEN_FIRMWARE: "PowerPC Open Firmware",
	PPC_EPAPR:         "PowerPC ePAPR",
	PPC_OPAL:          "POWER OPAL v3",
	EFI_X86_HTTP:      "EFI x86 boot from HTTP",
	EFI_X86_64_HTTP:   "EFI x86-64 boot from HTTP",
	EFI_BC_HTTP:       "EFI BC boot from HTTP",
	EFI_ARM32_HTTP:    "EFI ARM32 boot from HTTP",
	EFI_ARM64_HTTP:    "EFI ARM64 boot from HTTP",
	INTEL_X86PC_HTTP:  "Intel x86PC boot from HTTP",
	UBOOT_ARM32:       "U-Boot ARM32",
	UBOOT_ARM64:       "U-Boot ARM64",
	UBOOT_ARM32_HTTP:  "U-boot ARM32 boot from HTTP",
	UBOOT_ARM64_HTTP:  "U-Boot ARM64 boot from HTTP",
	EFI_RISCV32:       "EFI RISC-V 32-bit",
	EFI_RISCV32_HTTP:  "EFI RISC-V 32-bit boot from HTTP",
	EFI_RISCV64:       "EFI RISC-V 64-bit",
	EFI_RISCV64_HTTP:  "EFI RISC-V 64-bit boot from HTTP",
	EFI_RISCV128:      "EFI RISC-V 128-bit",
	EFI_RISCV128_HTTP: "EFI RISC-V 128-bit boot from HTTP",
	S390_BASIC:        "s390 Basic",
	S390_EXTENDED:     "s390 Extended",
	EFI_MIPS32:        "EFI MIPS32",
	EFI_MIPS64:        "EFI MIPS64",
	EFI_SUNWAY32:      "EFI Sunway 32-bit",
	EFI_SUNWAY64:      "EFI Sunway 64-bit",
}

// String returns a mnemonic name for a given architecture type.
func (a Arch) String() string {
	if at := archTypeToStringMap[a]; at != "" {
		return at
	}
	return "unknown"
}

// Archs represents multiple Arch values.
type Archs []Arch

// Contains returns whether b is one of the Archs in a.
func (a Archs) Contains(b Arch) bool {
	for _, t := range a {
		if t == b {
			return true
		}
	}
	return false
}

// ToBytes returns the serialized option defined by RFC 4578 (DHCPv4) and RFC
// 5970 (DHCPv6) as the Client System Architecture Option.
func (a Archs) ToBytes() []byte {
	buf := uio.NewBigEndianBuffer(nil)
	for _, at := range a {
		buf.Write16(uint16(at))
	}
	return buf.Data()
}

// String returns the list of archs in a human-readable manner.
func (a Archs) String() string {
	s := make([]string, 0, len(a))
	for _, arch := range a {
		s = append(s, arch.String())
	}
	return strings.Join(s, ", ")
}

// FromBytes parses a DHCP list of architecture types as defined by RFC 4578
// and RFC 5970.
func (a *Archs) FromBytes(data []byte) error {
	buf := uio.NewBigEndianBuffer(data)
	if buf.Len() == 0 {
		return fmt.Errorf("must have at least one archtype if option is present")
	}

	*a = make([]Arch, 0, buf.Len()/2)
	for buf.Has(2) {
		*a = append(*a, Arch(buf.Read16()))
	}
	return buf.FinError()
}