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 ---