github.com/etecs-ru/go-sys-wineventlog@v0.0.0-20210227233244-4c3abb794018/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_MAX EAFNOSUPPORT", 210 rsa: &RawSockaddrAny{ 211 Addr: RawSockaddr{ 212 Family: AF_MAX, 213 }, 214 }, 215 err: EAFNOSUPPORT, 216 }, 217 // TODO: expand to support other families. 218 } 219 220 realSocketProtocol := socketProtocol 221 222 for _, tt := range tests { 223 t.Run(tt.name, func(t *testing.T) { 224 fd := int(0) 225 if tt.proto != nil { 226 socketProtocol = func(fd int) (int, error) { return *tt.proto, nil } 227 } else { 228 socketProtocol = realSocketProtocol 229 } 230 sa, err := anyToSockaddr(fd, tt.rsa) 231 if err != tt.err { 232 t.Fatalf("unexpected error: %v, want: %v", err, tt.err) 233 } 234 235 if !reflect.DeepEqual(sa, tt.sa) { 236 t.Fatalf("unexpected Sockaddr:\n got: %#v\nwant: %#v", sa, tt.sa) 237 } 238 }) 239 } 240 } 241 242 func TestSockaddrTIPC_sockaddr(t *testing.T) { 243 tests := []struct { 244 name string 245 sa *SockaddrTIPC 246 raw *RawSockaddrTIPC 247 err error 248 }{ 249 { 250 name: "no fields set", 251 sa: &SockaddrTIPC{}, 252 err: EINVAL, 253 }, 254 { 255 name: "ID", 256 sa: &SockaddrTIPC{ 257 Scope: 1, 258 Addr: &TIPCSocketAddr{ 259 Ref: 1, 260 Node: 2, 261 }, 262 }, 263 raw: &RawSockaddrTIPC{ 264 Family: AF_TIPC, 265 Addrtype: TIPC_SOCKET_ADDR, 266 Scope: 1, 267 Addr: (&TIPCSocketAddr{ 268 Ref: 1, 269 Node: 2, 270 }).tipcAddr(), 271 }, 272 }, 273 { 274 name: "NameSeq", 275 sa: &SockaddrTIPC{ 276 Scope: 2, 277 Addr: &TIPCServiceRange{ 278 Type: 1, 279 Lower: 2, 280 Upper: 3, 281 }, 282 }, 283 raw: &RawSockaddrTIPC{ 284 Family: AF_TIPC, 285 Addrtype: TIPC_SERVICE_RANGE, 286 Scope: 2, 287 Addr: (&TIPCServiceRange{ 288 Type: 1, 289 Lower: 2, 290 Upper: 3, 291 }).tipcAddr(), 292 }, 293 }, 294 { 295 name: "Name", 296 sa: &SockaddrTIPC{ 297 Scope: 3, 298 Addr: &TIPCServiceName{ 299 Type: 1, 300 Instance: 2, 301 Domain: 3, 302 }, 303 }, 304 raw: &RawSockaddrTIPC{ 305 Family: AF_TIPC, 306 Addrtype: TIPC_SERVICE_ADDR, 307 Scope: 3, 308 Addr: (&TIPCServiceName{ 309 Type: 1, 310 Instance: 2, 311 Domain: 3, 312 }).tipcAddr(), 313 }, 314 }, 315 } 316 317 for _, tt := range tests { 318 t.Run(tt.name, func(t *testing.T) { 319 out, l, err := tt.sa.sockaddr() 320 if err != tt.err { 321 t.Fatalf("unexpected error: %v, want: %v", err, tt.err) 322 } 323 324 // Must be 0 on error or a fixed size otherwise. 325 if (tt.err != nil && l != 0) || (tt.raw != nil && l != SizeofSockaddrTIPC) { 326 t.Fatalf("unexpected Socklen: %d", l) 327 } 328 if out == nil { 329 // No pointer to cast, return early. 330 return 331 } 332 333 raw := (*RawSockaddrTIPC)(out) 334 if !reflect.DeepEqual(raw, tt.raw) { 335 t.Fatalf("unexpected RawSockaddrTIPC:\n got: %#v\nwant: %#v", raw, tt.raw) 336 } 337 }) 338 } 339 } 340 341 func TestSockaddrL2TPIP_sockaddr(t *testing.T) { 342 tests := []struct { 343 name string 344 sa *SockaddrL2TPIP 345 raw *RawSockaddrL2TPIP 346 err error 347 }{ 348 { 349 name: "L2TPIP", 350 sa: &SockaddrL2TPIP{ 351 Addr: [4]byte{0xef, 0x10, 0x5b, 0xa2}, 352 ConnId: 0x1234abcd, 353 }, 354 raw: &RawSockaddrL2TPIP{ 355 Family: AF_INET, 356 Addr: [4]byte{0xef, 0x10, 0x5b, 0xa2}, 357 Conn_id: 0x1234abcd, 358 }, 359 }, 360 } 361 362 for _, tt := range tests { 363 t.Run(tt.name, func(t *testing.T) { 364 out, l, err := tt.sa.sockaddr() 365 if err != tt.err { 366 t.Fatalf("unexpected error: %v, want: %v", err, tt.err) 367 } 368 369 // Must be 0 on error or a fixed size otherwise. 370 if (tt.err != nil && l != 0) || (tt.raw != nil && l != SizeofSockaddrL2TPIP) { 371 t.Fatalf("unexpected Socklen: %d", l) 372 } 373 374 if out != nil { 375 raw := (*RawSockaddrL2TPIP)(out) 376 if !reflect.DeepEqual(raw, tt.raw) { 377 t.Fatalf("unexpected RawSockaddrL2TPIP:\n got: %#v\nwant: %#v", raw, tt.raw) 378 } 379 } 380 }) 381 } 382 } 383 384 func TestSockaddrL2TPIP6_sockaddr(t *testing.T) { 385 tests := []struct { 386 name string 387 sa *SockaddrL2TPIP6 388 raw *RawSockaddrL2TPIP6 389 err error 390 }{ 391 { 392 name: "L2TPIP6", 393 sa: &SockaddrL2TPIP6{ 394 Addr: [16]byte{ 395 0x20, 0x01, 0x0d, 0xb8, 396 0x85, 0xa3, 0x00, 0x00, 397 0x00, 0x00, 0x8a, 0x2e, 398 0x03, 0x70, 0x73, 0x34, 399 }, 400 ZoneId: 90210, 401 ConnId: 0x1234abcd, 402 }, 403 raw: &RawSockaddrL2TPIP6{ 404 Family: AF_INET6, 405 Addr: [16]byte{ 406 0x20, 0x01, 0x0d, 0xb8, 407 0x85, 0xa3, 0x00, 0x00, 408 0x00, 0x00, 0x8a, 0x2e, 409 0x03, 0x70, 0x73, 0x34, 410 }, 411 Scope_id: 90210, 412 Conn_id: 0x1234abcd, 413 }, 414 }, 415 } 416 417 for _, tt := range tests { 418 t.Run(tt.name, func(t *testing.T) { 419 out, l, err := tt.sa.sockaddr() 420 if err != tt.err { 421 t.Fatalf("unexpected error: %v, want: %v", err, tt.err) 422 } 423 424 // Must be 0 on error or a fixed size otherwise. 425 if (tt.err != nil && l != 0) || (tt.raw != nil && l != SizeofSockaddrL2TPIP6) { 426 t.Fatalf("unexpected Socklen: %d", l) 427 } 428 429 if out != nil { 430 raw := (*RawSockaddrL2TPIP6)(out) 431 if !reflect.DeepEqual(raw, tt.raw) { 432 t.Fatalf("unexpected RawSockaddrL2TPIP6:\n got: %#v\nwant: %#v", raw, tt.raw) 433 } 434 } 435 }) 436 } 437 } 438 439 func TestSockaddrUnix_sockaddr(t *testing.T) { 440 tests := []struct { 441 name string 442 sa *SockaddrUnix 443 raw *RawSockaddrUnix 444 slen _Socklen 445 err error 446 }{ 447 { 448 name: "unnamed", 449 sa: &SockaddrUnix{}, 450 raw: &RawSockaddrUnix{ 451 Family: AF_UNIX, 452 }, 453 slen: 2, // family (uint16) 454 }, 455 { 456 name: "abstract", 457 sa: &SockaddrUnix{ 458 Name: "@", 459 }, 460 raw: &RawSockaddrUnix{ 461 Family: AF_UNIX, 462 }, 463 slen: 3, // family (uint16) + NULL 464 }, 465 { 466 name: "named", 467 sa: &SockaddrUnix{ 468 Name: "gopher", 469 }, 470 raw: &RawSockaddrUnix{ 471 Family: AF_UNIX, 472 Path: [108]int8{'g', 'o', 'p', 'h', 'e', 'r'}, 473 }, 474 slen: _Socklen(3 + len("gopher")), // family (uint16) + len(gopher) 475 }, 476 { 477 name: "named too long", 478 sa: &SockaddrUnix{ 479 Name: strings.Repeat("A", 108), 480 }, 481 err: EINVAL, 482 }, 483 } 484 485 for _, tt := range tests { 486 t.Run(tt.name, func(t *testing.T) { 487 out, l, err := tt.sa.sockaddr() 488 if err != tt.err { 489 t.Fatalf("unexpected error: %v, want: %v", err, tt.err) 490 } 491 492 if l != tt.slen { 493 t.Fatalf("unexpected Socklen: %d, want %d", l, tt.slen) 494 } 495 if out == nil { 496 // No pointer to cast, return early. 497 return 498 } 499 500 raw := (*RawSockaddrUnix)(out) 501 if !reflect.DeepEqual(raw, tt.raw) { 502 t.Fatalf("unexpected RawSockaddrUnix:\n got: %#v\nwant: %#v", raw, tt.raw) 503 } 504 }) 505 } 506 } 507 508 func TestSockaddrIUCV_sockaddr(t *testing.T) { 509 tests := []struct { 510 name string 511 sa *SockaddrIUCV 512 raw *RawSockaddrIUCV 513 err error 514 }{ 515 { 516 name: "no fields set", 517 sa: &SockaddrIUCV{}, 518 raw: &RawSockaddrIUCV{ 519 Family: AF_IUCV, 520 Nodeid: [8]int8{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, 521 User_id: [8]int8{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, 522 Name: [8]int8{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, 523 }, 524 }, 525 { 526 name: "both fields set", 527 sa: &SockaddrIUCV{ 528 UserID: "USERID", 529 Name: "NAME", 530 }, 531 raw: &RawSockaddrIUCV{ 532 Family: AF_IUCV, 533 Nodeid: [8]int8{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, 534 User_id: [8]int8{'U', 'S', 'E', 'R', 'I', 'D', ' ', ' '}, 535 Name: [8]int8{'N', 'A', 'M', 'E', ' ', ' ', ' ', ' '}, 536 }, 537 }, 538 { 539 name: "too long userid", 540 sa: &SockaddrIUCV{ 541 UserID: "123456789", 542 }, 543 err: EINVAL, 544 }, 545 { 546 name: "too long name", 547 sa: &SockaddrIUCV{ 548 Name: "123456789", 549 }, 550 err: EINVAL, 551 }, 552 } 553 554 for _, tt := range tests { 555 t.Run(tt.name, func(t *testing.T) { 556 out, l, err := tt.sa.sockaddr() 557 if err != tt.err { 558 t.Fatalf("unexpected error: %v, want: %v", err, tt.err) 559 } 560 561 // Must be 0 on error or a fixed size otherwise. 562 if (tt.err != nil && l != 0) || (tt.raw != nil && l != SizeofSockaddrIUCV) { 563 t.Fatalf("unexpected Socklen: %d", l) 564 } 565 if out == nil { 566 // No pointer to cast, return early. 567 return 568 } 569 570 raw := (*RawSockaddrIUCV)(out) 571 if !reflect.DeepEqual(raw, tt.raw) { 572 t.Fatalf("unexpected RawSockaddrIUCV:\n got: %#v\nwant: %#v", raw, tt.raw) 573 } 574 }) 575 } 576 } 577 578 func TestSockaddrCAN_sockaddr(t *testing.T) { 579 tests := []struct { 580 name string 581 sa *SockaddrCAN 582 raw *RawSockaddrCAN 583 err error 584 }{ 585 { 586 name: "with ids", 587 sa: &SockaddrCAN{ 588 Ifindex: 12345678, 589 RxID: 0xAAAAAAAA, 590 TxID: 0xBBBBBBBB, 591 }, 592 raw: &RawSockaddrCAN{ 593 Family: AF_CAN, 594 Ifindex: 12345678, 595 Addr: [16]byte{ 596 0xAA, 0xAA, 0xAA, 0xAA, 597 0xBB, 0xBB, 0xBB, 0xBB, 598 0x0, 0x0, 0x0, 0x0, 599 0x0, 0x0, 0x0, 0x0, 600 }, 601 }, 602 }, 603 { 604 name: "negative ifindex", 605 sa: &SockaddrCAN{ 606 Ifindex: -1, 607 }, 608 err: EINVAL, 609 }, 610 } 611 612 for _, tt := range tests { 613 t.Run(tt.name, func(t *testing.T) { 614 out, l, err := tt.sa.sockaddr() 615 if err != tt.err { 616 t.Fatalf("unexpected error: %v, want: %v", err, tt.err) 617 } 618 619 // Must be 0 on error or a fixed size otherwise. 620 if (tt.err != nil && l != 0) || (tt.raw != nil && l != SizeofSockaddrCAN) { 621 t.Fatalf("unexpected Socklen: %d", l) 622 } 623 624 if out != nil { 625 raw := (*RawSockaddrCAN)(out) 626 if !reflect.DeepEqual(raw, tt.raw) { 627 t.Fatalf("unexpected RawSockaddrCAN:\n got: %#v\nwant: %#v", raw, tt.raw) 628 } 629 } 630 }) 631 } 632 } 633 634 // These helpers explicitly copy the contents of in into out to produce 635 // the correct sockaddr structure, without relying on unsafe casting to 636 // a type of a larger size. 637 func sockaddrTIPCToAny(in RawSockaddrTIPC) *RawSockaddrAny { 638 var out RawSockaddrAny 639 copy( 640 (*(*[SizeofSockaddrAny]byte)(unsafe.Pointer(&out)))[:], 641 (*(*[SizeofSockaddrTIPC]byte)(unsafe.Pointer(&in)))[:], 642 ) 643 return &out 644 } 645 646 func sockaddrL2TPIPToAny(in RawSockaddrL2TPIP) *RawSockaddrAny { 647 var out RawSockaddrAny 648 copy( 649 (*(*[SizeofSockaddrAny]byte)(unsafe.Pointer(&out)))[:], 650 (*(*[SizeofSockaddrL2TPIP]byte)(unsafe.Pointer(&in)))[:], 651 ) 652 return &out 653 } 654 655 func sockaddrL2TPIP6ToAny(in RawSockaddrL2TPIP6) *RawSockaddrAny { 656 var out RawSockaddrAny 657 copy( 658 (*(*[SizeofSockaddrAny]byte)(unsafe.Pointer(&out)))[:], 659 (*(*[SizeofSockaddrL2TPIP6]byte)(unsafe.Pointer(&in)))[:], 660 ) 661 return &out 662 } 663 664 func sockaddrUnixToAny(in RawSockaddrUnix) *RawSockaddrAny { 665 var out RawSockaddrAny 666 copy( 667 (*(*[SizeofSockaddrAny]byte)(unsafe.Pointer(&out)))[:], 668 (*(*[SizeofSockaddrUnix]byte)(unsafe.Pointer(&in)))[:], 669 ) 670 return &out 671 } 672 673 func sockaddrIUCVToAny(in RawSockaddrIUCV) *RawSockaddrAny { 674 var out RawSockaddrAny 675 copy( 676 (*(*[SizeofSockaddrAny]byte)(unsafe.Pointer(&out)))[:], 677 (*(*[SizeofSockaddrUnix]byte)(unsafe.Pointer(&in)))[:], 678 ) 679 return &out 680 } 681 682 func sockaddrCANToAny(in RawSockaddrCAN) *RawSockaddrAny { 683 var out RawSockaddrAny 684 copy( 685 (*(*[SizeofSockaddrAny]byte)(unsafe.Pointer(&out)))[:], 686 (*(*[SizeofSockaddrCAN]byte)(unsafe.Pointer(&in)))[:], 687 ) 688 return &out 689 }