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