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 }