linux_socket.c (552afd9c120e6b11dbb1acf319bd71a4e9f2b913) | linux_socket.c (e140eb430ccdc7b0fd43a93838242f43a469c634) |
---|---|
1/*- 2 * Copyright (c) 1995 S�ren Schmidt 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 388 unchanged lines hidden (view full) --- 397bad: 398 if (to) 399 FREE(to, M_SONAME); 400 return (error); 401} 402 403/* Return 0 if IP_HDRINCL is set for the given socket. */ 404static int | 1/*- 2 * Copyright (c) 1995 S�ren Schmidt 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 388 unchanged lines hidden (view full) --- 397bad: 398 if (to) 399 FREE(to, M_SONAME); 400 return (error); 401} 402 403/* Return 0 if IP_HDRINCL is set for the given socket. */ 404static int |
405linux_check_hdrincl(struct thread *td, caddr_t *sg, int s) | 405linux_check_hdrincl(struct thread *td, int s) |
406{ | 406{ |
407 struct getsockopt_args /* { 408 int s; 409 int level; 410 int name; 411 void * __restrict val; 412 socklen_t * __restrict avalsize; 413 } */ bsd_args; 414 void * __restrict val; 415 socklen_t * __restrict valsize; | |
416 int error, optval, size_val; 417 | 407 int error, optval, size_val; 408 |
418 val = stackgap_alloc(sg, sizeof(size_val)); 419 valsize = stackgap_alloc(sg, sizeof(socklen_t)); 420 421 size_val = sizeof(val); 422 if ((error = copyout(&size_val, valsize, sizeof(size_val)))) | 409 size_val = sizeof(optval); 410 error = kern_getsockopt(td, s, IPPROTO_IP, IP_HDRINCL, 411 &optval, UIO_SYSSPACE, &size_val); 412 if (error) |
423 return (error); 424 | 413 return (error); 414 |
425 bsd_args.s = s; 426 bsd_args.level = IPPROTO_IP; 427 bsd_args.name = IP_HDRINCL; 428 bsd_args.val = val; 429 bsd_args.avalsize = valsize; 430 if ((error = getsockopt(td, &bsd_args))) 431 return (error); 432 433 if ((error = copyin(val, &optval, sizeof(optval)))) 434 return (error); 435 | |
436 return (optval == 0); 437} 438 439struct linux_sendto_args { 440 int s; 441 void *msg; 442 int len; 443 int flags; --- 12 unchanged lines hidden (view full) --- 456 * linux_ip_copysize defines how many bytes we should copy 457 * from the beginning of the IP packet before we customize it for BSD. 458 * It should include all the fields we modify (ip_len and ip_off) 459 * and be as small as possible to minimize copying overhead. 460 */ 461#define linux_ip_copysize 8 462 463 struct ip *packet; | 415 return (optval == 0); 416} 417 418struct linux_sendto_args { 419 int s; 420 void *msg; 421 int len; 422 int flags; --- 12 unchanged lines hidden (view full) --- 435 * linux_ip_copysize defines how many bytes we should copy 436 * from the beginning of the IP packet before we customize it for BSD. 437 * It should include all the fields we modify (ip_len and ip_off) 438 * and be as small as possible to minimize copying overhead. 439 */ 440#define linux_ip_copysize 8 441 442 struct ip *packet; |
443 caddr_t sg = stackgap_init(); |
|
464 struct msghdr msg; 465 struct iovec aiov[2]; 466 int error; 467 468 /* Check the packet isn't too small before we mess with it */ 469 if (linux_args->len < linux_ip_copysize) 470 return (EINVAL); 471 --- 38 unchanged lines hidden (view full) --- 510linux_socket(struct thread *td, struct linux_socket_args *args) 511{ 512 struct linux_socket_args linux_args; 513 struct socket_args /* { 514 int domain; 515 int type; 516 int protocol; 517 } */ bsd_args; | 444 struct msghdr msg; 445 struct iovec aiov[2]; 446 int error; 447 448 /* Check the packet isn't too small before we mess with it */ 449 if (linux_args->len < linux_ip_copysize) 450 return (EINVAL); 451 --- 38 unchanged lines hidden (view full) --- 490linux_socket(struct thread *td, struct linux_socket_args *args) 491{ 492 struct linux_socket_args linux_args; 493 struct socket_args /* { 494 int domain; 495 int type; 496 int protocol; 497 } */ bsd_args; |
518 struct setsockopt_args /* { 519 int s; 520 int level; 521 int name; 522 caddr_t val; 523 int valsize; 524 } */ bsd_setsockopt_args; | |
525 int error; 526 int retval_socket; 527 528 if ((error = copyin(args, &linux_args, sizeof(linux_args)))) 529 return (error); 530 531 bsd_args.protocol = linux_args.protocol; 532 bsd_args.type = linux_args.type; 533 bsd_args.domain = linux_to_bsd_domain(linux_args.domain); 534 if (bsd_args.domain == -1) 535 return (EINVAL); 536 537 retval_socket = socket(td, &bsd_args); 538 if (bsd_args.type == SOCK_RAW 539 && (bsd_args.protocol == IPPROTO_RAW || bsd_args.protocol == 0) 540 && bsd_args.domain == AF_INET 541 && retval_socket >= 0) { 542 /* It's a raw IP socket: set the IP_HDRINCL option. */ | 498 int error; 499 int retval_socket; 500 501 if ((error = copyin(args, &linux_args, sizeof(linux_args)))) 502 return (error); 503 504 bsd_args.protocol = linux_args.protocol; 505 bsd_args.type = linux_args.type; 506 bsd_args.domain = linux_to_bsd_domain(linux_args.domain); 507 if (bsd_args.domain == -1) 508 return (EINVAL); 509 510 retval_socket = socket(td, &bsd_args); 511 if (bsd_args.type == SOCK_RAW 512 && (bsd_args.protocol == IPPROTO_RAW || bsd_args.protocol == 0) 513 && bsd_args.domain == AF_INET 514 && retval_socket >= 0) { 515 /* It's a raw IP socket: set the IP_HDRINCL option. */ |
543 caddr_t sg; 544 int *hdrincl; | 516 int hdrincl; |
545 | 517 |
546 sg = stackgap_init(); 547 hdrincl = (int *)stackgap_alloc(&sg, sizeof(*hdrincl)); 548 *hdrincl = 1; 549 bsd_setsockopt_args.s = td->td_retval[0]; 550 bsd_setsockopt_args.level = IPPROTO_IP; 551 bsd_setsockopt_args.name = IP_HDRINCL; 552 bsd_setsockopt_args.val = (caddr_t)hdrincl; 553 bsd_setsockopt_args.valsize = sizeof(*hdrincl); 554 /* We ignore any error returned by setsockopt() */ 555 setsockopt(td, &bsd_setsockopt_args); 556 /* Copy back the return value from socket() */ 557 td->td_retval[0] = bsd_setsockopt_args.s; | 518 hdrincl = 1; 519 /* We ignore any error returned by kern_setsockopt() */ 520 kern_setsockopt(td, td->td_retval[0], IPPROTO_IP, IP_HDRINCL, 521 &hdrincl, UIO_SYSSPACE, sizeof(hdrincl)); |
558 } 559#ifdef INET6 560 /* 561 * Linux AF_INET6 socket has IPV6_V6ONLY setsockopt set to 0 by 562 * default and some apps depend on this. So, set V6ONLY to 0 563 * for Linux apps if the sysctl value is set to 1. 564 */ 565 if (bsd_args.domain == PF_INET6 && retval_socket >= 0 566#ifndef KLD_MODULE 567 /* 568 * XXX: Avoid undefined symbol error with an IPv4 only 569 * kernel. 570 */ 571 && ip6_v6only 572#endif 573 ) { | 522 } 523#ifdef INET6 524 /* 525 * Linux AF_INET6 socket has IPV6_V6ONLY setsockopt set to 0 by 526 * default and some apps depend on this. So, set V6ONLY to 0 527 * for Linux apps if the sysctl value is set to 1. 528 */ 529 if (bsd_args.domain == PF_INET6 && retval_socket >= 0 530#ifndef KLD_MODULE 531 /* 532 * XXX: Avoid undefined symbol error with an IPv4 only 533 * kernel. 534 */ 535 && ip6_v6only 536#endif 537 ) { |
574 caddr_t sg; 575 int *v6only; | 538 int v6only; |
576 | 539 |
577 sg = stackgap_init(); 578 v6only = (int *)stackgap_alloc(&sg, sizeof(*v6only)); 579 *v6only = 0; 580 bsd_setsockopt_args.s = td->td_retval[0]; 581 bsd_setsockopt_args.level = IPPROTO_IPV6; 582 bsd_setsockopt_args.name = IPV6_V6ONLY; 583 bsd_setsockopt_args.val = (caddr_t)v6only; 584 bsd_setsockopt_args.valsize = sizeof(*v6only); | 540 v6only = 0; |
585 /* We ignore any error returned by setsockopt() */ | 541 /* We ignore any error returned by setsockopt() */ |
586 setsockopt(td, &bsd_setsockopt_args); 587 /* Copy back the return value from socket() */ 588 td->td_retval[0] = bsd_setsockopt_args.s; | 542 kern_setsockopt(td, td->td_retval[0], IPPROTO_IPV6, IPV6_V6ONLY, 543 &v6only, UIO_SYSSPACE, sizeof(v6only)); |
589 } 590#endif 591 592 return (retval_socket); 593} 594 595struct linux_bind_args { 596 int s; --- 314 unchanged lines hidden (view full) --- 911} 912 913static int 914linux_sendto(struct thread *td, struct linux_sendto_args *args) 915{ 916 struct linux_sendto_args linux_args; 917 struct msghdr msg; 918 struct iovec aiov; | 544 } 545#endif 546 547 return (retval_socket); 548} 549 550struct linux_bind_args { 551 int s; --- 314 unchanged lines hidden (view full) --- 866} 867 868static int 869linux_sendto(struct thread *td, struct linux_sendto_args *args) 870{ 871 struct linux_sendto_args linux_args; 872 struct msghdr msg; 873 struct iovec aiov; |
919 caddr_t sg = stackgap_init(); | |
920 int error; 921 922 if ((error = copyin(args, &linux_args, sizeof(linux_args)))) 923 return (error); 924 | 874 int error; 875 876 if ((error = copyin(args, &linux_args, sizeof(linux_args)))) 877 return (error); 878 |
925 if (linux_check_hdrincl(td, &sg, linux_args.s) == 0) | 879 if (linux_check_hdrincl(td, linux_args.s) == 0) |
926 /* IP_HDRINCL set, tweak the packet before sending */ | 880 /* IP_HDRINCL set, tweak the packet before sending */ |
927 return (linux_sendto_hdrincl(td, &sg, &linux_args)); | 881 return (linux_sendto_hdrincl(td, &linux_args)); |
928 929 msg.msg_name = linux_args.to; 930 msg.msg_namelen = linux_args.tolen; 931 msg.msg_iov = &aiov; 932 msg.msg_iovlen = 1; 933 msg.msg_control = NULL; 934 msg.msg_flags = 0; 935 aiov.iov_base = linux_args.msg; --- 290 unchanged lines hidden --- | 882 883 msg.msg_name = linux_args.to; 884 msg.msg_namelen = linux_args.tolen; 885 msg.msg_iov = &aiov; 886 msg.msg_iovlen = 1; 887 msg.msg_control = NULL; 888 msg.msg_flags = 0; 889 aiov.iov_base = linux_args.msg; --- 290 unchanged lines hidden --- |