golang.org/x/sys@v0.20.1-0.20240517151509-673e0f94c16d/unix/syscall_internal_linux_test.go (about)

     1  // Copyright 2019 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 linux
     6  
     7  package unix
     8  
     9  import (
    10  	"reflect"
    11  	"strings"
    12  	"testing"
    13  	"unsafe"
    14  )
    15  
    16  func makeProto(proto int) *int {
    17  	return &proto
    18  }
    19  
    20  func Test_anyToSockaddr(t *testing.T) {
    21  	tests := []struct {
    22  		name  string
    23  		rsa   *RawSockaddrAny
    24  		sa    Sockaddr
    25  		err   error
    26  		proto *int
    27  	}{
    28  		{
    29  			name: "AF_TIPC bad addrtype",
    30  			rsa: &RawSockaddrAny{
    31  				Addr: RawSockaddr{
    32  					Family: AF_TIPC,
    33  				},
    34  			},
    35  			err: EINVAL,
    36  		},
    37  		{
    38  			name: "AF_TIPC NameSeq",
    39  			rsa: sockaddrTIPCToAny(RawSockaddrTIPC{
    40  				Family:   AF_TIPC,
    41  				Addrtype: TIPC_SERVICE_RANGE,
    42  				Scope:    1,
    43  				Addr: (&TIPCServiceRange{
    44  					Type:  1,
    45  					Lower: 2,
    46  					Upper: 3,
    47  				}).tipcAddr(),
    48  			}),
    49  			sa: &SockaddrTIPC{
    50  				Scope: 1,
    51  				Addr: &TIPCServiceRange{
    52  					Type:  1,
    53  					Lower: 2,
    54  					Upper: 3,
    55  				},
    56  			},
    57  		},
    58  		{
    59  			name: "AF_TIPC Name",
    60  			rsa: sockaddrTIPCToAny(RawSockaddrTIPC{
    61  				Family:   AF_TIPC,
    62  				Addrtype: TIPC_SERVICE_ADDR,
    63  				Scope:    2,
    64  				Addr: (&TIPCServiceName{
    65  					Type:     1,
    66  					Instance: 2,
    67  					Domain:   3,
    68  				}).tipcAddr(),
    69  			}),
    70  			sa: &SockaddrTIPC{
    71  				Scope: 2,
    72  				Addr: &TIPCServiceName{
    73  					Type:     1,
    74  					Instance: 2,
    75  					Domain:   3,
    76  				},
    77  			},
    78  		},
    79  		{
    80  			name: "AF_TIPC ID",
    81  			rsa: sockaddrTIPCToAny(RawSockaddrTIPC{
    82  				Family:   AF_TIPC,
    83  				Addrtype: TIPC_SOCKET_ADDR,
    84  				Scope:    3,
    85  				Addr: (&TIPCSocketAddr{
    86  					Ref:  1,
    87  					Node: 2,
    88  				}).tipcAddr(),
    89  			}),
    90  			sa: &SockaddrTIPC{
    91  				Scope: 3,
    92  				Addr: &TIPCSocketAddr{
    93  					Ref:  1,
    94  					Node: 2,
    95  				},
    96  			},
    97  		},
    98  		{
    99  			name: "AF_INET IPPROTO_L2TP",
   100  			rsa: sockaddrL2TPIPToAny(RawSockaddrL2TPIP{
   101  				Family:  AF_INET,
   102  				Addr:    [4]byte{0xef, 0x10, 0x5b, 0xa2},
   103  				Conn_id: 0x1234abcd,
   104  			}),
   105  			sa: &SockaddrL2TPIP{
   106  				Addr:   [4]byte{0xef, 0x10, 0x5b, 0xa2},
   107  				ConnId: 0x1234abcd,
   108  			},
   109  			proto: makeProto(IPPROTO_L2TP),
   110  		},
   111  		{
   112  			name: "AF_INET6 IPPROTO_L2TP",
   113  			rsa: sockaddrL2TPIP6ToAny(RawSockaddrL2TPIP6{
   114  				Family:   AF_INET6,
   115  				Flowinfo: 42,
   116  				Addr: [16]byte{
   117  					0x20, 0x01, 0x0d, 0xb8,
   118  					0x85, 0xa3, 0x00, 0x00,
   119  					0x00, 0x00, 0x8a, 0x2e,
   120  					0x03, 0x70, 0x73, 0x34,
   121  				},
   122  				Scope_id: 90210,
   123  				Conn_id:  0x1234abcd,
   124  			}),
   125  			sa: &SockaddrL2TPIP6{
   126  				Addr: [16]byte{
   127  					0x20, 0x01, 0x0d, 0xb8,
   128  					0x85, 0xa3, 0x00, 0x00,
   129  					0x00, 0x00, 0x8a, 0x2e,
   130  					0x03, 0x70, 0x73, 0x34,
   131  				},
   132  				ZoneId: 90210,
   133  				ConnId: 0x1234abcd,
   134  			},
   135  			proto: makeProto(IPPROTO_L2TP),
   136  		},
   137  		{
   138  			name: "AF_UNIX unnamed/abstract",
   139  			rsa: sockaddrUnixToAny(RawSockaddrUnix{
   140  				Family: AF_UNIX,
   141  			}),
   142  			sa: &SockaddrUnix{
   143  				Name: "@",
   144  			},
   145  		},
   146  		{
   147  			name: "AF_UNIX named",
   148  			rsa: sockaddrUnixToAny(RawSockaddrUnix{
   149  				Family: AF_UNIX,
   150  				Path:   [108]int8{'g', 'o', 'p', 'h', 'e', 'r'},
   151  			}),
   152  			sa: &SockaddrUnix{
   153  				Name: "gopher",
   154  			},
   155  		},
   156  		{
   157  			name: "AF_IUCV",
   158  			rsa: sockaddrIUCVToAny(RawSockaddrIUCV{
   159  				Family:  AF_IUCV,
   160  				User_id: [8]int8{'*', 'M', 'S', 'G', ' ', ' ', ' ', ' '},
   161  				Name:    [8]int8{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
   162  			}),
   163  			sa: &SockaddrIUCV{
   164  				UserID: "*MSG    ",
   165  				Name:   "        ",
   166  			},
   167  		},
   168  		{
   169  			name: "AF_CAN CAN_RAW",
   170  			rsa: sockaddrCANToAny(RawSockaddrCAN{
   171  				Family:  AF_CAN,
   172  				Ifindex: 12345678,
   173  				Addr: [16]byte{
   174  					0xAA, 0xAA, 0xAA, 0xAA,
   175  					0xBB, 0xBB, 0xBB, 0xBB,
   176  					0x0, 0x0, 0x0, 0x0,
   177  					0x0, 0x0, 0x0, 0x0,
   178  				},
   179  			}),
   180  			sa: &SockaddrCAN{
   181  				Ifindex: 12345678,
   182  				RxID:    0xAAAAAAAA,
   183  				TxID:    0xBBBBBBBB,
   184  			},
   185  			proto: makeProto(CAN_RAW),
   186  		},
   187  		{
   188  			name: "AF_CAN CAN_J1939",
   189  			rsa: sockaddrCANToAny(RawSockaddrCAN{
   190  				Family:  AF_CAN,
   191  				Ifindex: 12345678,
   192  				Addr: [16]byte{
   193  					0xAA, 0xAA, 0xAA, 0xAA,
   194  					0xAA, 0xAA, 0xAA, 0xAA,
   195  					0xBB, 0xBB, 0xBB, 0xBB,
   196  					0xCC, 0x00, 0x00, 0x00,
   197  				},
   198  			}),
   199  			sa: &SockaddrCANJ1939{
   200  				Ifindex: 12345678,
   201  				Name:    0xAAAAAAAAAAAAAAAA,
   202  				PGN:     0xBBBBBBBB,
   203  				Addr:    0xCC,
   204  			},
   205  			proto: makeProto(CAN_J1939),
   206  		},
   207  		{
   208  			name: "AF_NFC RAW",
   209  			rsa: sockaddrNFCToAny(RawSockaddrNFC{
   210  				Sa_family:    AF_NFC,
   211  				Dev_idx:      10,
   212  				Target_idx:   20,
   213  				Nfc_protocol: 30,
   214  			}),
   215  			sa: &SockaddrNFC{
   216  				DeviceIdx:   10,
   217  				TargetIdx:   20,
   218  				NFCProtocol: 30,
   219  			},
   220  			proto: makeProto(NFC_SOCKPROTO_RAW),
   221  		},
   222  		{
   223  			name: "AF_NFC LLCP",
   224  			rsa: sockaddrNFCLLCPToAny(RawSockaddrNFCLLCP{
   225  				Sa_family:        AF_NFC,
   226  				Dev_idx:          10,
   227  				Target_idx:       20,
   228  				Nfc_protocol:     30,
   229  				Dsap:             40,
   230  				Ssap:             50,
   231  				Service_name:     [63]uint8{'t', 'e', 's', 't'},
   232  				Service_name_len: 4,
   233  			}),
   234  			sa: &SockaddrNFCLLCP{
   235  				DeviceIdx:      10,
   236  				TargetIdx:      20,
   237  				NFCProtocol:    30,
   238  				DestinationSAP: 40,
   239  				SourceSAP:      50,
   240  				ServiceName:    "test",
   241  			},
   242  			proto: makeProto(NFC_SOCKPROTO_LLCP),
   243  		},
   244  		{
   245  			name: "AF_NFC unknown",
   246  			rsa: sockaddrNFCToAny(RawSockaddrNFC{
   247  				Sa_family:    AF_NFC,
   248  				Dev_idx:      10,
   249  				Target_idx:   20,
   250  				Nfc_protocol: 30,
   251  			}),
   252  			err:   EINVAL,
   253  			proto: makeProto(^0),
   254  		},
   255  		{
   256  			name: "AF_VSOCK empty",
   257  			rsa:  sockaddrVMToAny(RawSockaddrVM{}),
   258  			err:  EAFNOSUPPORT,
   259  		},
   260  		{
   261  			name: "AF_VSOCK Cid and Port",
   262  			rsa: sockaddrVMToAny(RawSockaddrVM{
   263  				Family: AF_VSOCK,
   264  				Cid:    VMADDR_CID_HOST,
   265  				Port:   VMADDR_PORT_ANY,
   266  			}),
   267  			sa: &SockaddrVM{
   268  				CID:  VMADDR_CID_HOST,
   269  				Port: VMADDR_PORT_ANY,
   270  			},
   271  		},
   272  		{
   273  			name: "AF_MAX EAFNOSUPPORT",
   274  			rsa: &RawSockaddrAny{
   275  				Addr: RawSockaddr{
   276  					Family: AF_MAX,
   277  				},
   278  			},
   279  			err: EAFNOSUPPORT,
   280  		},
   281  		// TODO: expand to support other families.
   282  	}
   283  
   284  	realSocketProtocol := socketProtocol
   285  
   286  	for _, tt := range tests {
   287  		t.Run(tt.name, func(t *testing.T) {
   288  			fd := int(0)
   289  			if tt.proto != nil {
   290  				socketProtocol = func(fd int) (int, error) { return *tt.proto, nil }
   291  			} else {
   292  				socketProtocol = realSocketProtocol
   293  			}
   294  			sa, err := anyToSockaddr(fd, tt.rsa)
   295  			if err != tt.err {
   296  				t.Fatalf("unexpected error: %v, want: %v", err, tt.err)
   297  			}
   298  
   299  			if !reflect.DeepEqual(sa, tt.sa) {
   300  				t.Fatalf("unexpected Sockaddr:\n got: %#v\nwant: %#v", sa, tt.sa)
   301  			}
   302  		})
   303  	}
   304  }
   305  
   306  func TestSockaddrTIPC_sockaddr(t *testing.T) {
   307  	tests := []struct {
   308  		name string
   309  		sa   *SockaddrTIPC
   310  		raw  *RawSockaddrTIPC
   311  		err  error
   312  	}{
   313  		{
   314  			name: "no fields set",
   315  			sa:   &SockaddrTIPC{},
   316  			err:  EINVAL,
   317  		},
   318  		{
   319  			name: "ID",
   320  			sa: &SockaddrTIPC{
   321  				Scope: 1,
   322  				Addr: &TIPCSocketAddr{
   323  					Ref:  1,
   324  					Node: 2,
   325  				},
   326  			},
   327  			raw: &RawSockaddrTIPC{
   328  				Family:   AF_TIPC,
   329  				Addrtype: TIPC_SOCKET_ADDR,
   330  				Scope:    1,
   331  				Addr: (&TIPCSocketAddr{
   332  					Ref:  1,
   333  					Node: 2,
   334  				}).tipcAddr(),
   335  			},
   336  		},
   337  		{
   338  			name: "NameSeq",
   339  			sa: &SockaddrTIPC{
   340  				Scope: 2,
   341  				Addr: &TIPCServiceRange{
   342  					Type:  1,
   343  					Lower: 2,
   344  					Upper: 3,
   345  				},
   346  			},
   347  			raw: &RawSockaddrTIPC{
   348  				Family:   AF_TIPC,
   349  				Addrtype: TIPC_SERVICE_RANGE,
   350  				Scope:    2,
   351  				Addr: (&TIPCServiceRange{
   352  					Type:  1,
   353  					Lower: 2,
   354  					Upper: 3,
   355  				}).tipcAddr(),
   356  			},
   357  		},
   358  		{
   359  			name: "Name",
   360  			sa: &SockaddrTIPC{
   361  				Scope: 3,
   362  				Addr: &TIPCServiceName{
   363  					Type:     1,
   364  					Instance: 2,
   365  					Domain:   3,
   366  				},
   367  			},
   368  			raw: &RawSockaddrTIPC{
   369  				Family:   AF_TIPC,
   370  				Addrtype: TIPC_SERVICE_ADDR,
   371  				Scope:    3,
   372  				Addr: (&TIPCServiceName{
   373  					Type:     1,
   374  					Instance: 2,
   375  					Domain:   3,
   376  				}).tipcAddr(),
   377  			},
   378  		},
   379  	}
   380  
   381  	for _, tt := range tests {
   382  		t.Run(tt.name, func(t *testing.T) {
   383  			out, l, err := tt.sa.sockaddr()
   384  			if err != tt.err {
   385  				t.Fatalf("unexpected error: %v, want: %v", err, tt.err)
   386  			}
   387  
   388  			// Must be 0 on error or a fixed size otherwise.
   389  			if (tt.err != nil && l != 0) || (tt.raw != nil && l != SizeofSockaddrTIPC) {
   390  				t.Fatalf("unexpected Socklen: %d", l)
   391  			}
   392  			if out == nil {
   393  				// No pointer to cast, return early.
   394  				return
   395  			}
   396  
   397  			raw := (*RawSockaddrTIPC)(out)
   398  			if !reflect.DeepEqual(raw, tt.raw) {
   399  				t.Fatalf("unexpected RawSockaddrTIPC:\n got: %#v\nwant: %#v", raw, tt.raw)
   400  			}
   401  		})
   402  	}
   403  }
   404  
   405  func TestSockaddrL2TPIP_sockaddr(t *testing.T) {
   406  	tests := []struct {
   407  		name string
   408  		sa   *SockaddrL2TPIP
   409  		raw  *RawSockaddrL2TPIP
   410  		err  error
   411  	}{
   412  		{
   413  			name: "L2TPIP",
   414  			sa: &SockaddrL2TPIP{
   415  				Addr:   [4]byte{0xef, 0x10, 0x5b, 0xa2},
   416  				ConnId: 0x1234abcd,
   417  			},
   418  			raw: &RawSockaddrL2TPIP{
   419  				Family:  AF_INET,
   420  				Addr:    [4]byte{0xef, 0x10, 0x5b, 0xa2},
   421  				Conn_id: 0x1234abcd,
   422  			},
   423  		},
   424  	}
   425  
   426  	for _, tt := range tests {
   427  		t.Run(tt.name, func(t *testing.T) {
   428  			out, l, err := tt.sa.sockaddr()
   429  			if err != tt.err {
   430  				t.Fatalf("unexpected error: %v, want: %v", err, tt.err)
   431  			}
   432  
   433  			// Must be 0 on error or a fixed size otherwise.
   434  			if (tt.err != nil && l != 0) || (tt.raw != nil && l != SizeofSockaddrL2TPIP) {
   435  				t.Fatalf("unexpected Socklen: %d", l)
   436  			}
   437  
   438  			if out != nil {
   439  				raw := (*RawSockaddrL2TPIP)(out)
   440  				if !reflect.DeepEqual(raw, tt.raw) {
   441  					t.Fatalf("unexpected RawSockaddrL2TPIP:\n got: %#v\nwant: %#v", raw, tt.raw)
   442  				}
   443  			}
   444  		})
   445  	}
   446  }
   447  
   448  func TestSockaddrL2TPIP6_sockaddr(t *testing.T) {
   449  	tests := []struct {
   450  		name string
   451  		sa   *SockaddrL2TPIP6
   452  		raw  *RawSockaddrL2TPIP6
   453  		err  error
   454  	}{
   455  		{
   456  			name: "L2TPIP6",
   457  			sa: &SockaddrL2TPIP6{
   458  				Addr: [16]byte{
   459  					0x20, 0x01, 0x0d, 0xb8,
   460  					0x85, 0xa3, 0x00, 0x00,
   461  					0x00, 0x00, 0x8a, 0x2e,
   462  					0x03, 0x70, 0x73, 0x34,
   463  				},
   464  				ZoneId: 90210,
   465  				ConnId: 0x1234abcd,
   466  			},
   467  			raw: &RawSockaddrL2TPIP6{
   468  				Family: AF_INET6,
   469  				Addr: [16]byte{
   470  					0x20, 0x01, 0x0d, 0xb8,
   471  					0x85, 0xa3, 0x00, 0x00,
   472  					0x00, 0x00, 0x8a, 0x2e,
   473  					0x03, 0x70, 0x73, 0x34,
   474  				},
   475  				Scope_id: 90210,
   476  				Conn_id:  0x1234abcd,
   477  			},
   478  		},
   479  	}
   480  
   481  	for _, tt := range tests {
   482  		t.Run(tt.name, func(t *testing.T) {
   483  			out, l, err := tt.sa.sockaddr()
   484  			if err != tt.err {
   485  				t.Fatalf("unexpected error: %v, want: %v", err, tt.err)
   486  			}
   487  
   488  			// Must be 0 on error or a fixed size otherwise.
   489  			if (tt.err != nil && l != 0) || (tt.raw != nil && l != SizeofSockaddrL2TPIP6) {
   490  				t.Fatalf("unexpected Socklen: %d", l)
   491  			}
   492  
   493  			if out != nil {
   494  				raw := (*RawSockaddrL2TPIP6)(out)
   495  				if !reflect.DeepEqual(raw, tt.raw) {
   496  					t.Fatalf("unexpected RawSockaddrL2TPIP6:\n got: %#v\nwant: %#v", raw, tt.raw)
   497  				}
   498  			}
   499  		})
   500  	}
   501  }
   502  
   503  func TestSockaddrUnix_sockaddr(t *testing.T) {
   504  	tests := []struct {
   505  		name string
   506  		sa   *SockaddrUnix
   507  		raw  *RawSockaddrUnix
   508  		slen _Socklen
   509  		err  error
   510  	}{
   511  		{
   512  			name: "unnamed",
   513  			sa:   &SockaddrUnix{},
   514  			raw: &RawSockaddrUnix{
   515  				Family: AF_UNIX,
   516  			},
   517  			slen: 2, // family (uint16)
   518  		},
   519  		{
   520  			name: "abstract_starting_with_at",
   521  			sa: &SockaddrUnix{
   522  				Name: "@",
   523  			},
   524  			raw: &RawSockaddrUnix{
   525  				Family: AF_UNIX,
   526  			},
   527  			slen: 3, // family (uint16) + NULL
   528  		},
   529  		{
   530  			name: "abstract_starting_with_null",
   531  			sa: &SockaddrUnix{
   532  				Name: "\x00",
   533  			},
   534  			raw: &RawSockaddrUnix{
   535  				Family: AF_UNIX,
   536  			},
   537  			slen: 3, // family (uint16) + NULL
   538  		},
   539  		{
   540  			name: "named",
   541  			sa: &SockaddrUnix{
   542  				Name: "gopher",
   543  			},
   544  			raw: &RawSockaddrUnix{
   545  				Family: AF_UNIX,
   546  				Path:   [108]int8{'g', 'o', 'p', 'h', 'e', 'r'},
   547  			},
   548  			slen: _Socklen(3 + len("gopher")), // family (uint16) + len(gopher)
   549  		},
   550  		{
   551  			name: "named too long",
   552  			sa: &SockaddrUnix{
   553  				Name: strings.Repeat("A", 108),
   554  			},
   555  			err: EINVAL,
   556  		},
   557  	}
   558  
   559  	for _, tt := range tests {
   560  		t.Run(tt.name, func(t *testing.T) {
   561  			out, l, err := tt.sa.sockaddr()
   562  			if err != tt.err {
   563  				t.Fatalf("unexpected error: %v, want: %v", err, tt.err)
   564  			}
   565  
   566  			if l != tt.slen {
   567  				t.Fatalf("unexpected Socklen: %d, want %d", l, tt.slen)
   568  			}
   569  			if out == nil {
   570  				// No pointer to cast, return early.
   571  				return
   572  			}
   573  
   574  			raw := (*RawSockaddrUnix)(out)
   575  			if !reflect.DeepEqual(raw, tt.raw) {
   576  				t.Fatalf("unexpected RawSockaddrUnix:\n got: %#v\nwant: %#v", raw, tt.raw)
   577  			}
   578  		})
   579  	}
   580  }
   581  
   582  func TestSockaddrIUCV_sockaddr(t *testing.T) {
   583  	tests := []struct {
   584  		name string
   585  		sa   *SockaddrIUCV
   586  		raw  *RawSockaddrIUCV
   587  		err  error
   588  	}{
   589  		{
   590  			name: "no fields set",
   591  			sa:   &SockaddrIUCV{},
   592  			raw: &RawSockaddrIUCV{
   593  				Family:  AF_IUCV,
   594  				Nodeid:  [8]int8{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
   595  				User_id: [8]int8{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
   596  				Name:    [8]int8{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
   597  			},
   598  		},
   599  		{
   600  			name: "both fields set",
   601  			sa: &SockaddrIUCV{
   602  				UserID: "USERID",
   603  				Name:   "NAME",
   604  			},
   605  			raw: &RawSockaddrIUCV{
   606  				Family:  AF_IUCV,
   607  				Nodeid:  [8]int8{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
   608  				User_id: [8]int8{'U', 'S', 'E', 'R', 'I', 'D', ' ', ' '},
   609  				Name:    [8]int8{'N', 'A', 'M', 'E', ' ', ' ', ' ', ' '},
   610  			},
   611  		},
   612  		{
   613  			name: "too long userid",
   614  			sa: &SockaddrIUCV{
   615  				UserID: "123456789",
   616  			},
   617  			err: EINVAL,
   618  		},
   619  		{
   620  			name: "too long name",
   621  			sa: &SockaddrIUCV{
   622  				Name: "123456789",
   623  			},
   624  			err: EINVAL,
   625  		},
   626  	}
   627  
   628  	for _, tt := range tests {
   629  		t.Run(tt.name, func(t *testing.T) {
   630  			out, l, err := tt.sa.sockaddr()
   631  			if err != tt.err {
   632  				t.Fatalf("unexpected error: %v, want: %v", err, tt.err)
   633  			}
   634  
   635  			// Must be 0 on error or a fixed size otherwise.
   636  			if (tt.err != nil && l != 0) || (tt.raw != nil && l != SizeofSockaddrIUCV) {
   637  				t.Fatalf("unexpected Socklen: %d", l)
   638  			}
   639  			if out == nil {
   640  				// No pointer to cast, return early.
   641  				return
   642  			}
   643  
   644  			raw := (*RawSockaddrIUCV)(out)
   645  			if !reflect.DeepEqual(raw, tt.raw) {
   646  				t.Fatalf("unexpected RawSockaddrIUCV:\n got: %#v\nwant: %#v", raw, tt.raw)
   647  			}
   648  		})
   649  	}
   650  }
   651  
   652  func TestSockaddrCAN_sockaddr(t *testing.T) {
   653  	tests := []struct {
   654  		name string
   655  		sa   *SockaddrCAN
   656  		raw  *RawSockaddrCAN
   657  		err  error
   658  	}{
   659  		{
   660  			name: "with ids",
   661  			sa: &SockaddrCAN{
   662  				Ifindex: 12345678,
   663  				RxID:    0xAAAAAAAA,
   664  				TxID:    0xBBBBBBBB,
   665  			},
   666  			raw: &RawSockaddrCAN{
   667  				Family:  AF_CAN,
   668  				Ifindex: 12345678,
   669  				Addr: [16]byte{
   670  					0xAA, 0xAA, 0xAA, 0xAA,
   671  					0xBB, 0xBB, 0xBB, 0xBB,
   672  					0x0, 0x0, 0x0, 0x0,
   673  					0x0, 0x0, 0x0, 0x0,
   674  				},
   675  			},
   676  		},
   677  		{
   678  			name: "negative ifindex",
   679  			sa: &SockaddrCAN{
   680  				Ifindex: -1,
   681  			},
   682  			err: EINVAL,
   683  		},
   684  	}
   685  
   686  	for _, tt := range tests {
   687  		t.Run(tt.name, func(t *testing.T) {
   688  			out, l, err := tt.sa.sockaddr()
   689  			if err != tt.err {
   690  				t.Fatalf("unexpected error: %v, want: %v", err, tt.err)
   691  			}
   692  
   693  			// Must be 0 on error or a fixed size otherwise.
   694  			if (tt.err != nil && l != 0) || (tt.raw != nil && l != SizeofSockaddrCAN) {
   695  				t.Fatalf("unexpected Socklen: %d", l)
   696  			}
   697  
   698  			if out != nil {
   699  				raw := (*RawSockaddrCAN)(out)
   700  				if !reflect.DeepEqual(raw, tt.raw) {
   701  					t.Fatalf("unexpected RawSockaddrCAN:\n got: %#v\nwant: %#v", raw, tt.raw)
   702  				}
   703  			}
   704  		})
   705  	}
   706  }
   707  
   708  func TestSockaddrNFC_sockaddr(t *testing.T) {
   709  	tests := []struct {
   710  		name string
   711  		sa   *SockaddrNFC
   712  		raw  *RawSockaddrNFC
   713  		err  error
   714  	}{
   715  		{
   716  			name: "NFC RAW",
   717  			sa: &SockaddrNFC{
   718  				DeviceIdx:   12345678,
   719  				TargetIdx:   87654321,
   720  				NFCProtocol: 0xBBBBBBBB,
   721  			},
   722  			raw: &RawSockaddrNFC{
   723  				Sa_family:    AF_NFC,
   724  				Dev_idx:      12345678,
   725  				Target_idx:   87654321,
   726  				Nfc_protocol: 0xBBBBBBBB,
   727  			},
   728  		},
   729  	}
   730  
   731  	for _, tt := range tests {
   732  		t.Run(tt.name, func(t *testing.T) {
   733  			out, l, err := tt.sa.sockaddr()
   734  			if err != tt.err {
   735  				t.Fatalf("unexpected error: %v, want: %v", err, tt.err)
   736  			}
   737  
   738  			// Must be 0 on error or a fixed size otherwise.
   739  			if (tt.err != nil && l != 0) || (tt.raw != nil && l != SizeofSockaddrNFC) {
   740  				t.Fatalf("unexpected Socklen: %d", l)
   741  			}
   742  
   743  			if out != nil {
   744  				raw := (*RawSockaddrNFC)(out)
   745  				if !reflect.DeepEqual(raw, tt.raw) {
   746  					t.Fatalf("unexpected RawSockaddrNFC:\n got: %#v\nwant: %#v", raw, tt.raw)
   747  				}
   748  			}
   749  		})
   750  	}
   751  }
   752  
   753  func TestSockaddrNFCLLCP_sockaddr(t *testing.T) {
   754  	tests := []struct {
   755  		name string
   756  		sa   *SockaddrNFCLLCP
   757  		raw  *RawSockaddrNFCLLCP
   758  		err  error
   759  	}{
   760  		{
   761  			name: "valid",
   762  			sa: &SockaddrNFCLLCP{
   763  				DeviceIdx:      12345678,
   764  				TargetIdx:      87654321,
   765  				NFCProtocol:    0xBBBBBBBB,
   766  				DestinationSAP: 55,
   767  				SourceSAP:      56,
   768  				ServiceName:    "test service",
   769  			},
   770  			raw: &RawSockaddrNFCLLCP{
   771  				Sa_family:        AF_NFC,
   772  				Dev_idx:          12345678,
   773  				Target_idx:       87654321,
   774  				Nfc_protocol:     0xBBBBBBBB,
   775  				Dsap:             55,
   776  				Ssap:             56,
   777  				Service_name:     [63]uint8{'t', 'e', 's', 't', ' ', 's', 'e', 'r', 'v', 'i', 'c', 'e'},
   778  				Service_name_len: 12,
   779  			},
   780  		},
   781  		{
   782  			name: "too long service name",
   783  			sa: &SockaddrNFCLLCP{
   784  				DeviceIdx:      12345678,
   785  				TargetIdx:      87654321,
   786  				NFCProtocol:    0xBBBBBBBB,
   787  				DestinationSAP: 55,
   788  				SourceSAP:      56,
   789  				ServiceName:    "too long too long too long too long too long too long too long too long too long",
   790  			},
   791  			err: EINVAL,
   792  		},
   793  	}
   794  
   795  	for _, tt := range tests {
   796  		t.Run(tt.name, func(t *testing.T) {
   797  			out, l, err := tt.sa.sockaddr()
   798  			if err != tt.err {
   799  				t.Fatalf("unexpected error: %v, want: %v", err, tt.err)
   800  			}
   801  
   802  			// Must be 0 on error or a fixed size otherwise.
   803  			if (tt.err != nil && l != 0) || (tt.raw != nil && l != SizeofSockaddrNFCLLCP) {
   804  				t.Fatalf("unexpected Socklen: %d", l)
   805  			}
   806  
   807  			if out != nil {
   808  				raw := (*RawSockaddrNFCLLCP)(out)
   809  				if !reflect.DeepEqual(raw, tt.raw) {
   810  					t.Fatalf("unexpected RawSockaddrNFCLLCP:\n got: %#v\nwant: %#v", raw, tt.raw)
   811  				}
   812  			}
   813  		})
   814  	}
   815  }
   816  
   817  func TestSockaddrVM_sockaddr(t *testing.T) {
   818  	tests := []struct {
   819  		name string
   820  		sa   *SockaddrVM
   821  		raw  *RawSockaddrVM
   822  		err  error
   823  	}{
   824  		{
   825  			name: "empty",
   826  			sa:   &SockaddrVM{},
   827  			raw: &RawSockaddrVM{
   828  				Family: AF_VSOCK,
   829  			},
   830  		},
   831  		{
   832  			name: "with CID, port and flags",
   833  			sa: &SockaddrVM{
   834  				CID:   VMADDR_CID_HOST,
   835  				Port:  VMADDR_PORT_ANY,
   836  				Flags: VMADDR_FLAG_TO_HOST,
   837  			},
   838  			raw: &RawSockaddrVM{
   839  				Family: AF_VSOCK,
   840  				Port:   VMADDR_PORT_ANY,
   841  				Cid:    VMADDR_CID_HOST,
   842  				Flags:  VMADDR_FLAG_TO_HOST,
   843  			},
   844  		},
   845  	}
   846  
   847  	for _, tt := range tests {
   848  		t.Run(tt.name, func(t *testing.T) {
   849  			out, l, err := tt.sa.sockaddr()
   850  			if err != tt.err {
   851  				t.Fatalf("unexpected error: %v, want: %v", err, tt.err)
   852  			}
   853  
   854  			// Must be 0 on error or a fixed size otherwise.
   855  			if (tt.err != nil && l != 0) || (tt.raw != nil && l != SizeofSockaddrVM) {
   856  				t.Fatalf("unexpected Socklen: %d", l)
   857  			}
   858  
   859  			if out != nil {
   860  				raw := (*RawSockaddrVM)(out)
   861  				if !reflect.DeepEqual(raw, tt.raw) {
   862  					t.Fatalf("unexpected RawSockaddrVM:\n got: %#v\nwant: %#v", raw, tt.raw)
   863  				}
   864  			}
   865  		})
   866  	}
   867  }
   868  
   869  // These helpers explicitly copy the contents of in into out to produce
   870  // the correct sockaddr structure, without relying on unsafe casting to
   871  // a type of a larger size.
   872  func sockaddrTIPCToAny(in RawSockaddrTIPC) *RawSockaddrAny {
   873  	var out RawSockaddrAny
   874  	copy(
   875  		(*(*[SizeofSockaddrAny]byte)(unsafe.Pointer(&out)))[:],
   876  		(*(*[SizeofSockaddrTIPC]byte)(unsafe.Pointer(&in)))[:],
   877  	)
   878  	return &out
   879  }
   880  
   881  func sockaddrL2TPIPToAny(in RawSockaddrL2TPIP) *RawSockaddrAny {
   882  	var out RawSockaddrAny
   883  	copy(
   884  		(*(*[SizeofSockaddrAny]byte)(unsafe.Pointer(&out)))[:],
   885  		(*(*[SizeofSockaddrL2TPIP]byte)(unsafe.Pointer(&in)))[:],
   886  	)
   887  	return &out
   888  }
   889  
   890  func sockaddrL2TPIP6ToAny(in RawSockaddrL2TPIP6) *RawSockaddrAny {
   891  	var out RawSockaddrAny
   892  	copy(
   893  		(*(*[SizeofSockaddrAny]byte)(unsafe.Pointer(&out)))[:],
   894  		(*(*[SizeofSockaddrL2TPIP6]byte)(unsafe.Pointer(&in)))[:],
   895  	)
   896  	return &out
   897  }
   898  
   899  func sockaddrUnixToAny(in RawSockaddrUnix) *RawSockaddrAny {
   900  	var out RawSockaddrAny
   901  	copy(
   902  		(*(*[SizeofSockaddrAny]byte)(unsafe.Pointer(&out)))[:],
   903  		(*(*[SizeofSockaddrUnix]byte)(unsafe.Pointer(&in)))[:],
   904  	)
   905  	return &out
   906  }
   907  
   908  func sockaddrIUCVToAny(in RawSockaddrIUCV) *RawSockaddrAny {
   909  	var out RawSockaddrAny
   910  	copy(
   911  		(*(*[SizeofSockaddrAny]byte)(unsafe.Pointer(&out)))[:],
   912  		(*(*[SizeofSockaddrUnix]byte)(unsafe.Pointer(&in)))[:],
   913  	)
   914  	return &out
   915  }
   916  
   917  func sockaddrCANToAny(in RawSockaddrCAN) *RawSockaddrAny {
   918  	var out RawSockaddrAny
   919  	copy(
   920  		(*(*[SizeofSockaddrAny]byte)(unsafe.Pointer(&out)))[:],
   921  		(*(*[SizeofSockaddrCAN]byte)(unsafe.Pointer(&in)))[:],
   922  	)
   923  	return &out
   924  }
   925  
   926  func sockaddrNFCToAny(in RawSockaddrNFC) *RawSockaddrAny {
   927  	var out RawSockaddrAny
   928  	copy(
   929  		(*(*[SizeofSockaddrAny]byte)(unsafe.Pointer(&out)))[:],
   930  		(*(*[SizeofSockaddrNFC]byte)(unsafe.Pointer(&in)))[:],
   931  	)
   932  	return &out
   933  }
   934  
   935  func sockaddrNFCLLCPToAny(in RawSockaddrNFCLLCP) *RawSockaddrAny {
   936  	var out RawSockaddrAny
   937  	copy(
   938  		(*(*[SizeofSockaddrAny]byte)(unsafe.Pointer(&out)))[:],
   939  		(*(*[SizeofSockaddrNFCLLCP]byte)(unsafe.Pointer(&in)))[:],
   940  	)
   941  	return &out
   942  }
   943  
   944  func sockaddrVMToAny(in RawSockaddrVM) *RawSockaddrAny {
   945  	var out RawSockaddrAny
   946  	copy(
   947  		(*(*[SizeofSockaddrAny]byte)(unsafe.Pointer(&out)))[:],
   948  		(*(*[SizeofSockaddrVM]byte)(unsafe.Pointer(&in)))[:],
   949  	)
   950  	return &out
   951  }