1// Copyright 2016 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5//go:build darwin || dragonfly || freebsd || netbsd || openbsd
6// +build darwin dragonfly freebsd netbsd openbsd
7
8package route
9
10import "runtime"
11
12// An Addr represents an address associated with packet routing.
13type Addr interface {
14	// Family returns an address family.
15	Family() int
16}
17
18// A LinkAddr represents a link-layer address.
19type LinkAddr struct {
20	Index int    // interface index when attached
21	Name  string // interface name when attached
22	Addr  []byte // link-layer address when attached
23}
24
25// Family implements the Family method of Addr interface.
26func (a *LinkAddr) Family() int { return sysAF_LINK }
27
28func (a *LinkAddr) lenAndSpace() (int, int) {
29	l := 8 + len(a.Name) + len(a.Addr)
30	return l, roundup(l)
31}
32
33func (a *LinkAddr) marshal(b []byte) (int, error) {
34	l, ll := a.lenAndSpace()
35	if len(b) < ll {
36		return 0, errShortBuffer
37	}
38	nlen, alen := len(a.Name), len(a.Addr)
39	if nlen > 255 || alen > 255 {
40		return 0, errInvalidAddr
41	}
42	b[0] = byte(l)
43	b[1] = sysAF_LINK
44	if a.Index > 0 {
45		nativeEndian.PutUint16(b[2:4], uint16(a.Index))
46	}
47	data := b[8:]
48	if nlen > 0 {
49		b[5] = byte(nlen)
50		copy(data[:nlen], a.Name)
51		data = data[nlen:]
52	}
53	if alen > 0 {
54		b[6] = byte(alen)
55		copy(data[:alen], a.Addr)
56		data = data[alen:]
57	}
58	return ll, nil
59}
60
61func parseLinkAddr(b []byte) (Addr, error) {
62	if len(b) < 8 {
63		return nil, errInvalidAddr
64	}
65	_, a, err := parseKernelLinkAddr(sysAF_LINK, b[4:])
66	if err != nil {
67		return nil, err
68	}
69	a.(*LinkAddr).Index = int(nativeEndian.Uint16(b[2:4]))
70	return a, nil
71}
72
73// parseKernelLinkAddr parses b as a link-layer address in
74// conventional BSD kernel form.
75func parseKernelLinkAddr(_ int, b []byte) (int, Addr, error) {
76	// The encoding looks like the following:
77	// +----------------------------+
78	// | Type             (1 octet) |
79	// +----------------------------+
80	// | Name length      (1 octet) |
81	// +----------------------------+
82	// | Address length   (1 octet) |
83	// +----------------------------+
84	// | Selector length  (1 octet) |
85	// +----------------------------+
86	// | Data            (variable) |
87	// +----------------------------+
88	//
89	// On some platforms, all-bit-one of length field means "don't
90	// care".
91	nlen, alen, slen := int(b[1]), int(b[2]), int(b[3])
92	if nlen == 0xff {
93		nlen = 0
94	}
95	if alen == 0xff {
96		alen = 0
97	}
98	if slen == 0xff {
99		slen = 0
100	}
101	l := 4 + nlen + alen + slen
102	if len(b) < l {
103		return 0, nil, errInvalidAddr
104	}
105	data := b[4:]
106	var name string
107	var addr []byte
108	if nlen > 0 {
109		name = string(data[:nlen])
110		data = data[nlen:]
111	}
112	if alen > 0 {
113		addr = data[:alen]
114		data = data[alen:]
115	}
116	return l, &LinkAddr{Name: name, Addr: addr}, nil
117}
118
119// An Inet4Addr represents an internet address for IPv4.
120type Inet4Addr struct {
121	IP [4]byte // IP address
122}
123
124// Family implements the Family method of Addr interface.
125func (a *Inet4Addr) Family() int { return sysAF_INET }
126
127func (a *Inet4Addr) lenAndSpace() (int, int) {
128	return sizeofSockaddrInet, roundup(sizeofSockaddrInet)
129}
130
131func (a *Inet4Addr) marshal(b []byte) (int, error) {
132	l, ll := a.lenAndSpace()
133	if len(b) < ll {
134		return 0, errShortBuffer
135	}
136	b[0] = byte(l)
137	b[1] = sysAF_INET
138	copy(b[4:8], a.IP[:])
139	return ll, nil
140}
141
142// An Inet6Addr represents an internet address for IPv6.
143type Inet6Addr struct {
144	IP     [16]byte // IP address
145	ZoneID int      // zone identifier
146}
147
148// Family implements the Family method of Addr interface.
149func (a *Inet6Addr) Family() int { return sysAF_INET6 }
150
151func (a *Inet6Addr) lenAndSpace() (int, int) {
152	return sizeofSockaddrInet6, roundup(sizeofSockaddrInet6)
153}
154
155func (a *Inet6Addr) marshal(b []byte) (int, error) {
156	l, ll := a.lenAndSpace()
157	if len(b) < ll {
158		return 0, errShortBuffer
159	}
160	b[0] = byte(l)
161	b[1] = sysAF_INET6
162	copy(b[8:24], a.IP[:])
163	if a.ZoneID > 0 {
164		nativeEndian.PutUint32(b[24:28], uint32(a.ZoneID))
165	}
166	return ll, nil
167}
168
169// parseInetAddr parses b as an internet address for IPv4 or IPv6.
170func parseInetAddr(af int, b []byte) (Addr, error) {
171	switch af {
172	case sysAF_INET:
173		if len(b) < sizeofSockaddrInet {
174			return nil, errInvalidAddr
175		}
176		a := &Inet4Addr{}
177		copy(a.IP[:], b[4:8])
178		return a, nil
179	case sysAF_INET6:
180		if len(b) < sizeofSockaddrInet6 {
181			return nil, errInvalidAddr
182		}
183		a := &Inet6Addr{ZoneID: int(nativeEndian.Uint32(b[24:28]))}
184		copy(a.IP[:], b[8:24])
185		if a.IP[0] == 0xfe && a.IP[1]&0xc0 == 0x80 || a.IP[0] == 0xff && (a.IP[1]&0x0f == 0x01 || a.IP[1]&0x0f == 0x02) {
186			// KAME based IPv6 protocol stack usually
187			// embeds the interface index in the
188			// interface-local or link-local address as
189			// the kernel-internal form.
190			id := int(bigEndian.Uint16(a.IP[2:4]))
191			if id != 0 {
192				a.ZoneID = id
193				a.IP[2], a.IP[3] = 0, 0
194			}
195		}
196		return a, nil
197	default:
198		return nil, errInvalidAddr
199	}
200}
201
202// parseKernelInetAddr parses b as an internet address in conventional
203// BSD kernel form.
204func parseKernelInetAddr(af int, b []byte) (int, Addr, error) {
205	// The encoding looks similar to the NLRI encoding.
206	// +----------------------------+
207	// | Length           (1 octet) |
208	// +----------------------------+
209	// | Address prefix  (variable) |
210	// +----------------------------+
211	//
212	// The differences between the kernel form and the NLRI
213	// encoding are:
214	//
215	// - The length field of the kernel form indicates the prefix
216	//   length in bytes, not in bits
217	//
218	// - In the kernel form, zero value of the length field
219	//   doesn't mean 0.0.0.0/0 or ::/0
220	//
221	// - The kernel form appends leading bytes to the prefix field
222	//   to make the <length, prefix> tuple to be conformed with
223	//   the routing message boundary
224	l := int(b[0])
225	if runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
226		// On Darwin, an address in the kernel form is also
227		// used as a message filler.
228		if l == 0 || len(b) > roundup(l) {
229			l = roundup(l)
230		}
231	} else {
232		l = roundup(l)
233	}
234	if len(b) < l {
235		return 0, nil, errInvalidAddr
236	}
237	// Don't reorder case expressions.
238	// The case expressions for IPv6 must come first.
239	const (
240		off4 = 4 // offset of in_addr
241		off6 = 8 // offset of in6_addr
242	)
243	switch {
244	case b[0] == sizeofSockaddrInet6:
245		a := &Inet6Addr{}
246		copy(a.IP[:], b[off6:off6+16])
247		return int(b[0]), a, nil
248	case af == sysAF_INET6:
249		a := &Inet6Addr{}
250		if l-1 < off6 {
251			copy(a.IP[:], b[1:l])
252		} else {
253			copy(a.IP[:], b[l-off6:l])
254		}
255		return int(b[0]), a, nil
256	case b[0] == sizeofSockaddrInet:
257		a := &Inet4Addr{}
258		copy(a.IP[:], b[off4:off4+4])
259		return int(b[0]), a, nil
260	default: // an old fashion, AF_UNSPEC or unknown means AF_INET
261		a := &Inet4Addr{}
262		if l-1 < off4 {
263			copy(a.IP[:], b[1:l])
264		} else {
265			copy(a.IP[:], b[l-off4:l])
266		}
267		return int(b[0]), a, nil
268	}
269}
270
271// A DefaultAddr represents an address of various operating
272// system-specific features.
273type DefaultAddr struct {
274	af  int
275	Raw []byte // raw format of address
276}
277
278// Family implements the Family method of Addr interface.
279func (a *DefaultAddr) Family() int { return a.af }
280
281func (a *DefaultAddr) lenAndSpace() (int, int) {
282	l := len(a.Raw)
283	return l, roundup(l)
284}
285
286func (a *DefaultAddr) marshal(b []byte) (int, error) {
287	l, ll := a.lenAndSpace()
288	if len(b) < ll {
289		return 0, errShortBuffer
290	}
291	if l > 255 {
292		return 0, errInvalidAddr
293	}
294	b[1] = byte(l)
295	copy(b[:l], a.Raw)
296	return ll, nil
297}
298
299func parseDefaultAddr(b []byte) (Addr, error) {
300	if len(b) < 2 || len(b) < int(b[0]) {
301		return nil, errInvalidAddr
302	}
303	a := &DefaultAddr{af: int(b[1]), Raw: b[:b[0]]}
304	return a, nil
305}
306
307func addrsSpace(as []Addr) int {
308	var l int
309	for _, a := range as {
310		switch a := a.(type) {
311		case *LinkAddr:
312			_, ll := a.lenAndSpace()
313			l += ll
314		case *Inet4Addr:
315			_, ll := a.lenAndSpace()
316			l += ll
317		case *Inet6Addr:
318			_, ll := a.lenAndSpace()
319			l += ll
320		case *DefaultAddr:
321			_, ll := a.lenAndSpace()
322			l += ll
323		}
324	}
325	return l
326}
327
328// marshalAddrs marshals as and returns a bitmap indicating which
329// address is stored in b.
330func marshalAddrs(b []byte, as []Addr) (uint, error) {
331	var attrs uint
332	for i, a := range as {
333		switch a := a.(type) {
334		case *LinkAddr:
335			l, err := a.marshal(b)
336			if err != nil {
337				return 0, err
338			}
339			b = b[l:]
340			attrs |= 1 << uint(i)
341		case *Inet4Addr:
342			l, err := a.marshal(b)
343			if err != nil {
344				return 0, err
345			}
346			b = b[l:]
347			attrs |= 1 << uint(i)
348		case *Inet6Addr:
349			l, err := a.marshal(b)
350			if err != nil {
351				return 0, err
352			}
353			b = b[l:]
354			attrs |= 1 << uint(i)
355		case *DefaultAddr:
356			l, err := a.marshal(b)
357			if err != nil {
358				return 0, err
359			}
360			b = b[l:]
361			attrs |= 1 << uint(i)
362		}
363	}
364	return attrs, nil
365}
366
367func parseAddrs(attrs uint, fn func(int, []byte) (int, Addr, error), b []byte) ([]Addr, error) {
368	var as [sysRTAX_MAX]Addr
369	af := int(sysAF_UNSPEC)
370	for i := uint(0); i < sysRTAX_MAX && len(b) >= roundup(0); i++ {
371		if attrs&(1<<i) == 0 {
372			continue
373		}
374		if i <= sysRTAX_BRD {
375			switch b[1] {
376			case sysAF_LINK:
377				a, err := parseLinkAddr(b)
378				if err != nil {
379					return nil, err
380				}
381				as[i] = a
382				l := roundup(int(b[0]))
383				if len(b) < l {
384					return nil, errMessageTooShort
385				}
386				b = b[l:]
387			case sysAF_INET, sysAF_INET6:
388				af = int(b[1])
389				a, err := parseInetAddr(af, b)
390				if err != nil {
391					return nil, err
392				}
393				as[i] = a
394				l := roundup(int(b[0]))
395				if len(b) < l {
396					return nil, errMessageTooShort
397				}
398				b = b[l:]
399			default:
400				l, a, err := fn(af, b)
401				if err != nil {
402					return nil, err
403				}
404				as[i] = a
405				ll := roundup(l)
406				if len(b) < ll {
407					b = b[l:]
408				} else {
409					b = b[ll:]
410				}
411			}
412		} else {
413			a, err := parseDefaultAddr(b)
414			if err != nil {
415				return nil, err
416			}
417			as[i] = a
418			l := roundup(int(b[0]))
419			if len(b) < l {
420				return nil, errMessageTooShort
421			}
422			b = b[l:]
423		}
424	}
425	return as[:], nil
426}
427