github.com/HACKERALERT/Picocrypt/src/external/sys@v0.0.0-20210609020157-e519952f829f/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_MAX EAFNOSUPPORT",
   258  			rsa: &RawSockaddrAny{
   259  				Addr: RawSockaddr{
   260  					Family: AF_MAX,
   261  				},
   262  			},
   263  			err: EAFNOSUPPORT,
   264  		},
   265  		// TODO: expand to support other families.
   266  	}
   267  
   268  	realSocketProtocol := socketProtocol
   269  
   270  	for _, tt := range tests {
   271  		t.Run(tt.name, func(t *testing.T) {
   272  			fd := int(0)
   273  			if tt.proto != nil {
   274  				socketProtocol = func(fd int) (int, error) { return *tt.proto, nil }
   275  			} else {
   276  				socketProtocol = realSocketProtocol
   277  			}
   278  			sa, err := anyToSockaddr(fd, tt.rsa)
   279  			if err != tt.err {
   280  				t.Fatalf("unexpected error: %v, want: %v", err, tt.err)
   281  			}
   282  
   283  			if !reflect.DeepEqual(sa, tt.sa) {
   284  				t.Fatalf("unexpected Sockaddr:\n got: %#v\nwant: %#v", sa, tt.sa)
   285  			}
   286  		})
   287  	}
   288  }
   289  
   290  func TestSockaddrTIPC_sockaddr(t *testing.T) {
   291  	tests := []struct {
   292  		name string
   293  		sa   *SockaddrTIPC
   294  		raw  *RawSockaddrTIPC
   295  		err  error
   296  	}{
   297  		{
   298  			name: "no fields set",
   299  			sa:   &SockaddrTIPC{},
   300  			err:  EINVAL,
   301  		},
   302  		{
   303  			name: "ID",
   304  			sa: &SockaddrTIPC{
   305  				Scope: 1,
   306  				Addr: &TIPCSocketAddr{
   307  					Ref:  1,
   308  					Node: 2,
   309  				},
   310  			},
   311  			raw: &RawSockaddrTIPC{
   312  				Family:   AF_TIPC,
   313  				Addrtype: TIPC_SOCKET_ADDR,
   314  				Scope:    1,
   315  				Addr: (&TIPCSocketAddr{
   316  					Ref:  1,
   317  					Node: 2,
   318  				}).tipcAddr(),
   319  			},
   320  		},
   321  		{
   322  			name: "NameSeq",
   323  			sa: &SockaddrTIPC{
   324  				Scope: 2,
   325  				Addr: &TIPCServiceRange{
   326  					Type:  1,
   327  					Lower: 2,
   328  					Upper: 3,
   329  				},
   330  			},
   331  			raw: &RawSockaddrTIPC{
   332  				Family:   AF_TIPC,
   333  				Addrtype: TIPC_SERVICE_RANGE,
   334  				Scope:    2,
   335  				Addr: (&TIPCServiceRange{
   336  					Type:  1,
   337  					Lower: 2,
   338  					Upper: 3,
   339  				}).tipcAddr(),
   340  			},
   341  		},
   342  		{
   343  			name: "Name",
   344  			sa: &SockaddrTIPC{
   345  				Scope: 3,
   346  				Addr: &TIPCServiceName{
   347  					Type:     1,
   348  					Instance: 2,
   349  					Domain:   3,
   350  				},
   351  			},
   352  			raw: &RawSockaddrTIPC{
   353  				Family:   AF_TIPC,
   354  				Addrtype: TIPC_SERVICE_ADDR,
   355  				Scope:    3,
   356  				Addr: (&TIPCServiceName{
   357  					Type:     1,
   358  					Instance: 2,
   359  					Domain:   3,
   360  				}).tipcAddr(),
   361  			},
   362  		},
   363  	}
   364  
   365  	for _, tt := range tests {
   366  		t.Run(tt.name, func(t *testing.T) {
   367  			out, l, err := tt.sa.sockaddr()
   368  			if err != tt.err {
   369  				t.Fatalf("unexpected error: %v, want: %v", err, tt.err)
   370  			}
   371  
   372  			// Must be 0 on error or a fixed size otherwise.
   373  			if (tt.err != nil && l != 0) || (tt.raw != nil && l != SizeofSockaddrTIPC) {
   374  				t.Fatalf("unexpected Socklen: %d", l)
   375  			}
   376  			if out == nil {
   377  				// No pointer to cast, return early.
   378  				return
   379  			}
   380  
   381  			raw := (*RawSockaddrTIPC)(out)
   382  			if !reflect.DeepEqual(raw, tt.raw) {
   383  				t.Fatalf("unexpected RawSockaddrTIPC:\n got: %#v\nwant: %#v", raw, tt.raw)
   384  			}
   385  		})
   386  	}
   387  }
   388  
   389  func TestSockaddrL2TPIP_sockaddr(t *testing.T) {
   390  	tests := []struct {
   391  		name string
   392  		sa   *SockaddrL2TPIP
   393  		raw  *RawSockaddrL2TPIP
   394  		err  error
   395  	}{
   396  		{
   397  			name: "L2TPIP",
   398  			sa: &SockaddrL2TPIP{
   399  				Addr:   [4]byte{0xef, 0x10, 0x5b, 0xa2},
   400  				ConnId: 0x1234abcd,
   401  			},
   402  			raw: &RawSockaddrL2TPIP{
   403  				Family:  AF_INET,
   404  				Addr:    [4]byte{0xef, 0x10, 0x5b, 0xa2},
   405  				Conn_id: 0x1234abcd,
   406  			},
   407  		},
   408  	}
   409  
   410  	for _, tt := range tests {
   411  		t.Run(tt.name, func(t *testing.T) {
   412  			out, l, err := tt.sa.sockaddr()
   413  			if err != tt.err {
   414  				t.Fatalf("unexpected error: %v, want: %v", err, tt.err)
   415  			}
   416  
   417  			// Must be 0 on error or a fixed size otherwise.
   418  			if (tt.err != nil && l != 0) || (tt.raw != nil && l != SizeofSockaddrL2TPIP) {
   419  				t.Fatalf("unexpected Socklen: %d", l)
   420  			}
   421  
   422  			if out != nil {
   423  				raw := (*RawSockaddrL2TPIP)(out)
   424  				if !reflect.DeepEqual(raw, tt.raw) {
   425  					t.Fatalf("unexpected RawSockaddrL2TPIP:\n got: %#v\nwant: %#v", raw, tt.raw)
   426  				}
   427  			}
   428  		})
   429  	}
   430  }
   431  
   432  func TestSockaddrL2TPIP6_sockaddr(t *testing.T) {
   433  	tests := []struct {
   434  		name string
   435  		sa   *SockaddrL2TPIP6
   436  		raw  *RawSockaddrL2TPIP6
   437  		err  error
   438  	}{
   439  		{
   440  			name: "L2TPIP6",
   441  			sa: &SockaddrL2TPIP6{
   442  				Addr: [16]byte{
   443  					0x20, 0x01, 0x0d, 0xb8,
   444  					0x85, 0xa3, 0x00, 0x00,
   445  					0x00, 0x00, 0x8a, 0x2e,
   446  					0x03, 0x70, 0x73, 0x34,
   447  				},
   448  				ZoneId: 90210,
   449  				ConnId: 0x1234abcd,
   450  			},
   451  			raw: &RawSockaddrL2TPIP6{
   452  				Family: AF_INET6,
   453  				Addr: [16]byte{
   454  					0x20, 0x01, 0x0d, 0xb8,
   455  					0x85, 0xa3, 0x00, 0x00,
   456  					0x00, 0x00, 0x8a, 0x2e,
   457  					0x03, 0x70, 0x73, 0x34,
   458  				},
   459  				Scope_id: 90210,
   460  				Conn_id:  0x1234abcd,
   461  			},
   462  		},
   463  	}
   464  
   465  	for _, tt := range tests {
   466  		t.Run(tt.name, func(t *testing.T) {
   467  			out, l, err := tt.sa.sockaddr()
   468  			if err != tt.err {
   469  				t.Fatalf("unexpected error: %v, want: %v", err, tt.err)
   470  			}
   471  
   472  			// Must be 0 on error or a fixed size otherwise.
   473  			if (tt.err != nil && l != 0) || (tt.raw != nil && l != SizeofSockaddrL2TPIP6) {
   474  				t.Fatalf("unexpected Socklen: %d", l)
   475  			}
   476  
   477  			if out != nil {
   478  				raw := (*RawSockaddrL2TPIP6)(out)
   479  				if !reflect.DeepEqual(raw, tt.raw) {
   480  					t.Fatalf("unexpected RawSockaddrL2TPIP6:\n got: %#v\nwant: %#v", raw, tt.raw)
   481  				}
   482  			}
   483  		})
   484  	}
   485  }
   486  
   487  func TestSockaddrUnix_sockaddr(t *testing.T) {
   488  	tests := []struct {
   489  		name string
   490  		sa   *SockaddrUnix
   491  		raw  *RawSockaddrUnix
   492  		slen _Socklen
   493  		err  error
   494  	}{
   495  		{
   496  			name: "unnamed",
   497  			sa:   &SockaddrUnix{},
   498  			raw: &RawSockaddrUnix{
   499  				Family: AF_UNIX,
   500  			},
   501  			slen: 2, // family (uint16)
   502  		},
   503  		{
   504  			name: "abstract",
   505  			sa: &SockaddrUnix{
   506  				Name: "@",
   507  			},
   508  			raw: &RawSockaddrUnix{
   509  				Family: AF_UNIX,
   510  			},
   511  			slen: 3, // family (uint16) + NULL
   512  		},
   513  		{
   514  			name: "named",
   515  			sa: &SockaddrUnix{
   516  				Name: "gopher",
   517  			},
   518  			raw: &RawSockaddrUnix{
   519  				Family: AF_UNIX,
   520  				Path:   [108]int8{'g', 'o', 'p', 'h', 'e', 'r'},
   521  			},
   522  			slen: _Socklen(3 + len("gopher")), // family (uint16) + len(gopher)
   523  		},
   524  		{
   525  			name: "named too long",
   526  			sa: &SockaddrUnix{
   527  				Name: strings.Repeat("A", 108),
   528  			},
   529  			err: EINVAL,
   530  		},
   531  	}
   532  
   533  	for _, tt := range tests {
   534  		t.Run(tt.name, func(t *testing.T) {
   535  			out, l, err := tt.sa.sockaddr()
   536  			if err != tt.err {
   537  				t.Fatalf("unexpected error: %v, want: %v", err, tt.err)
   538  			}
   539  
   540  			if l != tt.slen {
   541  				t.Fatalf("unexpected Socklen: %d, want %d", l, tt.slen)
   542  			}
   543  			if out == nil {
   544  				// No pointer to cast, return early.
   545  				return
   546  			}
   547  
   548  			raw := (*RawSockaddrUnix)(out)
   549  			if !reflect.DeepEqual(raw, tt.raw) {
   550  				t.Fatalf("unexpected RawSockaddrUnix:\n got: %#v\nwant: %#v", raw, tt.raw)
   551  			}
   552  		})
   553  	}
   554  }
   555  
   556  func TestSockaddrIUCV_sockaddr(t *testing.T) {
   557  	tests := []struct {
   558  		name string
   559  		sa   *SockaddrIUCV
   560  		raw  *RawSockaddrIUCV
   561  		err  error
   562  	}{
   563  		{
   564  			name: "no fields set",
   565  			sa:   &SockaddrIUCV{},
   566  			raw: &RawSockaddrIUCV{
   567  				Family:  AF_IUCV,
   568  				Nodeid:  [8]int8{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
   569  				User_id: [8]int8{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
   570  				Name:    [8]int8{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
   571  			},
   572  		},
   573  		{
   574  			name: "both fields set",
   575  			sa: &SockaddrIUCV{
   576  				UserID: "USERID",
   577  				Name:   "NAME",
   578  			},
   579  			raw: &RawSockaddrIUCV{
   580  				Family:  AF_IUCV,
   581  				Nodeid:  [8]int8{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '},
   582  				User_id: [8]int8{'U', 'S', 'E', 'R', 'I', 'D', ' ', ' '},
   583  				Name:    [8]int8{'N', 'A', 'M', 'E', ' ', ' ', ' ', ' '},
   584  			},
   585  		},
   586  		{
   587  			name: "too long userid",
   588  			sa: &SockaddrIUCV{
   589  				UserID: "123456789",
   590  			},
   591  			err: EINVAL,
   592  		},
   593  		{
   594  			name: "too long name",
   595  			sa: &SockaddrIUCV{
   596  				Name: "123456789",
   597  			},
   598  			err: EINVAL,
   599  		},
   600  	}
   601  
   602  	for _, tt := range tests {
   603  		t.Run(tt.name, func(t *testing.T) {
   604  			out, l, err := tt.sa.sockaddr()
   605  			if err != tt.err {
   606  				t.Fatalf("unexpected error: %v, want: %v", err, tt.err)
   607  			}
   608  
   609  			// Must be 0 on error or a fixed size otherwise.
   610  			if (tt.err != nil && l != 0) || (tt.raw != nil && l != SizeofSockaddrIUCV) {
   611  				t.Fatalf("unexpected Socklen: %d", l)
   612  			}
   613  			if out == nil {
   614  				// No pointer to cast, return early.
   615  				return
   616  			}
   617  
   618  			raw := (*RawSockaddrIUCV)(out)
   619  			if !reflect.DeepEqual(raw, tt.raw) {
   620  				t.Fatalf("unexpected RawSockaddrIUCV:\n got: %#v\nwant: %#v", raw, tt.raw)
   621  			}
   622  		})
   623  	}
   624  }
   625  
   626  func TestSockaddrCAN_sockaddr(t *testing.T) {
   627  	tests := []struct {
   628  		name string
   629  		sa   *SockaddrCAN
   630  		raw  *RawSockaddrCAN
   631  		err  error
   632  	}{
   633  		{
   634  			name: "with ids",
   635  			sa: &SockaddrCAN{
   636  				Ifindex: 12345678,
   637  				RxID:    0xAAAAAAAA,
   638  				TxID:    0xBBBBBBBB,
   639  			},
   640  			raw: &RawSockaddrCAN{
   641  				Family:  AF_CAN,
   642  				Ifindex: 12345678,
   643  				Addr: [16]byte{
   644  					0xAA, 0xAA, 0xAA, 0xAA,
   645  					0xBB, 0xBB, 0xBB, 0xBB,
   646  					0x0, 0x0, 0x0, 0x0,
   647  					0x0, 0x0, 0x0, 0x0,
   648  				},
   649  			},
   650  		},
   651  		{
   652  			name: "negative ifindex",
   653  			sa: &SockaddrCAN{
   654  				Ifindex: -1,
   655  			},
   656  			err: EINVAL,
   657  		},
   658  	}
   659  
   660  	for _, tt := range tests {
   661  		t.Run(tt.name, func(t *testing.T) {
   662  			out, l, err := tt.sa.sockaddr()
   663  			if err != tt.err {
   664  				t.Fatalf("unexpected error: %v, want: %v", err, tt.err)
   665  			}
   666  
   667  			// Must be 0 on error or a fixed size otherwise.
   668  			if (tt.err != nil && l != 0) || (tt.raw != nil && l != SizeofSockaddrCAN) {
   669  				t.Fatalf("unexpected Socklen: %d", l)
   670  			}
   671  
   672  			if out != nil {
   673  				raw := (*RawSockaddrCAN)(out)
   674  				if !reflect.DeepEqual(raw, tt.raw) {
   675  					t.Fatalf("unexpected RawSockaddrCAN:\n got: %#v\nwant: %#v", raw, tt.raw)
   676  				}
   677  			}
   678  		})
   679  	}
   680  }
   681  
   682  func TestSockaddrNFC_sockaddr(t *testing.T) {
   683  	tests := []struct {
   684  		name string
   685  		sa   *SockaddrNFC
   686  		raw  *RawSockaddrNFC
   687  		err  error
   688  	}{
   689  		{
   690  			name: "NFC RAW",
   691  			sa: &SockaddrNFC{
   692  				DeviceIdx:   12345678,
   693  				TargetIdx:   87654321,
   694  				NFCProtocol: 0xBBBBBBBB,
   695  			},
   696  			raw: &RawSockaddrNFC{
   697  				Sa_family:    AF_NFC,
   698  				Dev_idx:      12345678,
   699  				Target_idx:   87654321,
   700  				Nfc_protocol: 0xBBBBBBBB,
   701  			},
   702  		},
   703  	}
   704  
   705  	for _, tt := range tests {
   706  		t.Run(tt.name, func(t *testing.T) {
   707  			out, l, err := tt.sa.sockaddr()
   708  			if err != tt.err {
   709  				t.Fatalf("unexpected error: %v, want: %v", err, tt.err)
   710  			}
   711  
   712  			// Must be 0 on error or a fixed size otherwise.
   713  			if (tt.err != nil && l != 0) || (tt.raw != nil && l != SizeofSockaddrNFC) {
   714  				t.Fatalf("unexpected Socklen: %d", l)
   715  			}
   716  
   717  			if out != nil {
   718  				raw := (*RawSockaddrNFC)(out)
   719  				if !reflect.DeepEqual(raw, tt.raw) {
   720  					t.Fatalf("unexpected RawSockaddrNFC:\n got: %#v\nwant: %#v", raw, tt.raw)
   721  				}
   722  			}
   723  		})
   724  	}
   725  }
   726  
   727  func TestSockaddrNFCLLCP_sockaddr(t *testing.T) {
   728  	tests := []struct {
   729  		name string
   730  		sa   *SockaddrNFCLLCP
   731  		raw  *RawSockaddrNFCLLCP
   732  		err  error
   733  	}{
   734  		{
   735  			name: "valid",
   736  			sa: &SockaddrNFCLLCP{
   737  				DeviceIdx:      12345678,
   738  				TargetIdx:      87654321,
   739  				NFCProtocol:    0xBBBBBBBB,
   740  				DestinationSAP: 55,
   741  				SourceSAP:      56,
   742  				ServiceName:    "test service",
   743  			},
   744  			raw: &RawSockaddrNFCLLCP{
   745  				Sa_family:        AF_NFC,
   746  				Dev_idx:          12345678,
   747  				Target_idx:       87654321,
   748  				Nfc_protocol:     0xBBBBBBBB,
   749  				Dsap:             55,
   750  				Ssap:             56,
   751  				Service_name:     [63]uint8{'t', 'e', 's', 't', ' ', 's', 'e', 'r', 'v', 'i', 'c', 'e'},
   752  				Service_name_len: 12,
   753  			},
   754  		},
   755  		{
   756  			name: "too long service name",
   757  			sa: &SockaddrNFCLLCP{
   758  				DeviceIdx:      12345678,
   759  				TargetIdx:      87654321,
   760  				NFCProtocol:    0xBBBBBBBB,
   761  				DestinationSAP: 55,
   762  				SourceSAP:      56,
   763  				ServiceName:    "too long too long too long too long too long too long too long too long too long",
   764  			},
   765  			err: EINVAL,
   766  		},
   767  	}
   768  
   769  	for _, tt := range tests {
   770  		t.Run(tt.name, func(t *testing.T) {
   771  			out, l, err := tt.sa.sockaddr()
   772  			if err != tt.err {
   773  				t.Fatalf("unexpected error: %v, want: %v", err, tt.err)
   774  			}
   775  
   776  			// Must be 0 on error or a fixed size otherwise.
   777  			if (tt.err != nil && l != 0) || (tt.raw != nil && l != SizeofSockaddrNFCLLCP) {
   778  				t.Fatalf("unexpected Socklen: %d", l)
   779  			}
   780  
   781  			if out != nil {
   782  				raw := (*RawSockaddrNFCLLCP)(out)
   783  				if !reflect.DeepEqual(raw, tt.raw) {
   784  					t.Fatalf("unexpected RawSockaddrNFCLLCP:\n got: %#v\nwant: %#v", raw, tt.raw)
   785  				}
   786  			}
   787  		})
   788  	}
   789  }
   790  
   791  // These helpers explicitly copy the contents of in into out to produce
   792  // the correct sockaddr structure, without relying on unsafe casting to
   793  // a type of a larger size.
   794  func sockaddrTIPCToAny(in RawSockaddrTIPC) *RawSockaddrAny {
   795  	var out RawSockaddrAny
   796  	copy(
   797  		(*(*[SizeofSockaddrAny]byte)(unsafe.Pointer(&out)))[:],
   798  		(*(*[SizeofSockaddrTIPC]byte)(unsafe.Pointer(&in)))[:],
   799  	)
   800  	return &out
   801  }
   802  
   803  func sockaddrL2TPIPToAny(in RawSockaddrL2TPIP) *RawSockaddrAny {
   804  	var out RawSockaddrAny
   805  	copy(
   806  		(*(*[SizeofSockaddrAny]byte)(unsafe.Pointer(&out)))[:],
   807  		(*(*[SizeofSockaddrL2TPIP]byte)(unsafe.Pointer(&in)))[:],
   808  	)
   809  	return &out
   810  }
   811  
   812  func sockaddrL2TPIP6ToAny(in RawSockaddrL2TPIP6) *RawSockaddrAny {
   813  	var out RawSockaddrAny
   814  	copy(
   815  		(*(*[SizeofSockaddrAny]byte)(unsafe.Pointer(&out)))[:],
   816  		(*(*[SizeofSockaddrL2TPIP6]byte)(unsafe.Pointer(&in)))[:],
   817  	)
   818  	return &out
   819  }
   820  
   821  func sockaddrUnixToAny(in RawSockaddrUnix) *RawSockaddrAny {
   822  	var out RawSockaddrAny
   823  	copy(
   824  		(*(*[SizeofSockaddrAny]byte)(unsafe.Pointer(&out)))[:],
   825  		(*(*[SizeofSockaddrUnix]byte)(unsafe.Pointer(&in)))[:],
   826  	)
   827  	return &out
   828  }
   829  
   830  func sockaddrIUCVToAny(in RawSockaddrIUCV) *RawSockaddrAny {
   831  	var out RawSockaddrAny
   832  	copy(
   833  		(*(*[SizeofSockaddrAny]byte)(unsafe.Pointer(&out)))[:],
   834  		(*(*[SizeofSockaddrUnix]byte)(unsafe.Pointer(&in)))[:],
   835  	)
   836  	return &out
   837  }
   838  
   839  func sockaddrCANToAny(in RawSockaddrCAN) *RawSockaddrAny {
   840  	var out RawSockaddrAny
   841  	copy(
   842  		(*(*[SizeofSockaddrAny]byte)(unsafe.Pointer(&out)))[:],
   843  		(*(*[SizeofSockaddrCAN]byte)(unsafe.Pointer(&in)))[:],
   844  	)
   845  	return &out
   846  }
   847  
   848  func sockaddrNFCToAny(in RawSockaddrNFC) *RawSockaddrAny {
   849  	var out RawSockaddrAny
   850  	copy(
   851  		(*(*[SizeofSockaddrAny]byte)(unsafe.Pointer(&out)))[:],
   852  		(*(*[SizeofSockaddrNFC]byte)(unsafe.Pointer(&in)))[:],
   853  	)
   854  	return &out
   855  }
   856  
   857  func sockaddrNFCLLCPToAny(in RawSockaddrNFCLLCP) *RawSockaddrAny {
   858  	var out RawSockaddrAny
   859  	copy(
   860  		(*(*[SizeofSockaddrAny]byte)(unsafe.Pointer(&out)))[:],
   861  		(*(*[SizeofSockaddrNFCLLCP]byte)(unsafe.Pointer(&in)))[:],
   862  	)
   863  	return &out
   864  }