@@ -24,6 +24,39 @@ type LinkAddr struct {
2424// Family implements the Family method of Addr interface.
2525func (a * LinkAddr ) Family () int { return sysAF_LINK }
2626
27+ func (a * LinkAddr ) lenAndSpace () (int , int ) {
28+ l := 8 + len (a .Name ) + len (a .Addr )
29+ return l , roundup (l )
30+ }
31+
32+ func (a * LinkAddr ) marshal (b []byte ) (int , error ) {
33+ l , ll := a .lenAndSpace ()
34+ if len (b ) < ll {
35+ return 0 , errShortBuffer
36+ }
37+ nlen , alen := len (a .Name ), len (a .Addr )
38+ if nlen > 255 || alen > 255 {
39+ return 0 , errInvalidAddr
40+ }
41+ b [0 ] = byte (l )
42+ b [1 ] = sysAF_LINK
43+ if a .Index > 0 {
44+ nativeEndian .PutUint16 (b [2 :4 ], uint16 (a .Index ))
45+ }
46+ data := b [8 :]
47+ if nlen > 0 {
48+ b [5 ] = byte (nlen )
49+ copy (data [:nlen ], a .Addr )
50+ data = data [nlen :]
51+ }
52+ if alen > 0 {
53+ b [6 ] = byte (alen )
54+ copy (data [:alen ], a .Name )
55+ data = data [alen :]
56+ }
57+ return ll , nil
58+ }
59+
2760func parseLinkAddr (b []byte ) (Addr , error ) {
2861if len (b ) < 8 {
2962return nil , errInvalidAddr
@@ -90,6 +123,21 @@ type Inet4Addr struct {
90123// Family implements the Family method of Addr interface.
91124func (a * Inet4Addr ) Family () int { return sysAF_INET }
92125
126+ func (a * Inet4Addr ) lenAndSpace () (int , int ) {
127+ return sizeofSockaddrInet , roundup (sizeofSockaddrInet )
128+ }
129+
130+ func (a * Inet4Addr ) marshal (b []byte ) (int , error ) {
131+ l , ll := a .lenAndSpace ()
132+ if len (b ) < ll {
133+ return 0 , errShortBuffer
134+ }
135+ b [0 ] = byte (l )
136+ b [1 ] = sysAF_INET
137+ copy (b [4 :8 ], a .IP [:])
138+ return ll , nil
139+ }
140+
93141// An Inet6Addr represents an internet address for IPv6.
94142type Inet6Addr struct {
95143IP [16 ]byte // IP address
@@ -99,18 +147,36 @@ type Inet6Addr struct {
99147// Family implements the Family method of Addr interface.
100148func (a * Inet6Addr ) Family () int { return sysAF_INET6 }
101149
150+ func (a * Inet6Addr ) lenAndSpace () (int , int ) {
151+ return sizeofSockaddrInet6 , roundup (sizeofSockaddrInet6 )
152+ }
153+
154+ func (a * Inet6Addr ) marshal (b []byte ) (int , error ) {
155+ l , ll := a .lenAndSpace ()
156+ if len (b ) < ll {
157+ return 0 , errShortBuffer
158+ }
159+ b [0 ] = byte (l )
160+ b [1 ] = sysAF_INET6
161+ copy (b [8 :24 ], a .IP [:])
162+ if a .ZoneID > 0 {
163+ nativeEndian .PutUint32 (b [24 :28 ], uint32 (a .ZoneID ))
164+ }
165+ return ll , nil
166+ }
167+
102168// parseInetAddr parses b as an internet address for IPv4 or IPv6.
103169func parseInetAddr (af int , b []byte ) (Addr , error ) {
104170switch af {
105171case sysAF_INET :
106- if len (b ) < 16 {
172+ if len (b ) < sizeofSockaddrInet {
107173return nil , errInvalidAddr
108174}
109175a := & Inet4Addr {}
110176copy (a .IP [:], b [4 :8 ])
111177return a , nil
112178case sysAF_INET6 :
113- if len (b ) < 28 {
179+ if len (b ) < sizeofSockaddrInet6 {
114180return nil , errInvalidAddr
115181}
116182a := & Inet6Addr {ZoneID : int (nativeEndian .Uint32 (b [24 :28 ]))}
@@ -174,7 +240,7 @@ func parseKernelInetAddr(af int, b []byte) (int, Addr, error) {
174240off6 = 8 // offset of in6_addr
175241)
176242switch {
177- case b [0 ] == 28 : // size of sockaddr_in6
243+ case b [0 ] == sizeofSockaddrInet6 :
178244a := & Inet6Addr {}
179245copy (a .IP [:], b [off6 :off6 + 16 ])
180246return int (b [0 ]), a , nil
@@ -186,7 +252,7 @@ func parseKernelInetAddr(af int, b []byte) (int, Addr, error) {
186252copy (a .IP [:], b [l - off6 :l ])
187253}
188254return int (b [0 ]), a , nil
189- case b [0 ] == 16 : // size of sockaddr_in
255+ case b [0 ] == sizeofSockaddrInet :
190256a := & Inet4Addr {}
191257copy (a .IP [:], b [off4 :off4 + 4 ])
192258return int (b [0 ]), a , nil
@@ -211,6 +277,24 @@ type DefaultAddr struct {
211277// Family implements the Family method of Addr interface.
212278func (a * DefaultAddr ) Family () int { return a .af }
213279
280+ func (a * DefaultAddr ) lenAndSpace () (int , int ) {
281+ l := len (a .Raw )
282+ return l , roundup (l )
283+ }
284+
285+ func (a * DefaultAddr ) marshal (b []byte ) (int , error ) {
286+ l , ll := a .lenAndSpace ()
287+ if len (b ) < ll {
288+ return 0 , errShortBuffer
289+ }
290+ if l > 255 {
291+ return 0 , errInvalidAddr
292+ }
293+ b [1 ] = byte (l )
294+ copy (b [:l ], a .Raw )
295+ return ll , nil
296+ }
297+
214298func parseDefaultAddr (b []byte ) (Addr , error ) {
215299if len (b ) < 2 || len (b ) < int (b [0 ]) {
216300return nil , errInvalidAddr
@@ -219,6 +303,66 @@ func parseDefaultAddr(b []byte) (Addr, error) {
219303return a , nil
220304}
221305
306+ func addrsSpace (as []Addr ) int {
307+ var l int
308+ for _ , a := range as {
309+ switch a := a .(type ) {
310+ case * LinkAddr :
311+ _ , ll := a .lenAndSpace ()
312+ l += ll
313+ case * Inet4Addr :
314+ _ , ll := a .lenAndSpace ()
315+ l += ll
316+ case * Inet6Addr :
317+ _ , ll := a .lenAndSpace ()
318+ l += ll
319+ case * DefaultAddr :
320+ _ , ll := a .lenAndSpace ()
321+ l += ll
322+ }
323+ }
324+ return l
325+ }
326+
327+ // marshalAddrs marshals as returns a bitmap indicating which address
328+ // is stored in b.
329+ func marshalAddrs (b []byte , as []Addr ) (uint , error ) {
330+ var attrs uint
331+ for i , a := range as {
332+ switch a := a .(type ) {
333+ case * LinkAddr :
334+ l , err := a .marshal (b )
335+ if err != nil {
336+ return 0 , err
337+ }
338+ b = b [l :]
339+ attrs |= 1 << uint (i )
340+ case * Inet4Addr :
341+ l , err := a .marshal (b )
342+ if err != nil {
343+ return 0 , err
344+ }
345+ b = b [l :]
346+ attrs |= 1 << uint (i )
347+ case * Inet6Addr :
348+ l , err := a .marshal (b )
349+ if err != nil {
350+ return 0 , err
351+ }
352+ b = b [l :]
353+ attrs |= 1 << uint (i )
354+ case * DefaultAddr :
355+ l , err := a .marshal (b )
356+ if err != nil {
357+ return 0 , err
358+ }
359+ b = b [l :]
360+ attrs |= 1 << uint (i )
361+ }
362+ }
363+ return attrs , nil
364+ }
365+
222366func parseAddrs (attrs uint , fn func (int , []byte ) (int , Addr , error ), b []byte ) ([]Addr , error ) {
223367var as [sysRTAX_MAX ]Addr
224368af := int (sysAF_UNSPEC )
0 commit comments