~lefteris-nikoltsios/+junk/samba-lp1016895

« back to all changes in this revision

Viewing changes to lib/socket_wrapper/socket_wrapper.c

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2011-12-21 13:18:04 UTC
  • mfrom: (0.39.21 sid)
  • Revision ID: package-import@ubuntu.com-20111221131804-xtlr39wx6njehxxr
Tags: 2:3.6.1-3ubuntu1
* Merge from Debian testing.  Remaining changes:
  + debian/patches/VERSION.patch:
    - set SAMBA_VERSION_SUFFIX to Ubuntu.
  + debian/patches/error-trans.fix-276472:
    - Add the translation of Unix Error code -ENOTSUP to NT Error Code
    - NT_STATUS_NOT_SUPPORTED to prevent the Permission denied error.
  + debian/smb.conf:
    - add "(Samba, Ubuntu)" to server string.
    - comment out the default [homes] share, and add a comment about
      "valid users = %S" to show users how to restrict access to
      \\server\username to only username.
    - Set 'usershare allow guests', so that usershare admins are 
      allowed to create public shares in addition to authenticated
      ones.
    - add map to guest = Bad user, maps bad username to guest access.
  + debian/samba-common.config:
    - Do not change priority to high if dhclient3 is installed.
    - Use priority medium instead of high for the workgroup question.
  + debian/control:
    - Don't build against or suggest ctdb.
    - Add dependency on samba-common-bin to samba.
  + Add ufw integration:
    - Created debian/samba.ufw.profile
    - debian/rules, debian/samba.dirs, debian/samba.files: install
      profile
    - debian/control: have samba suggest ufw
  + Add apport hook:
    - Created debian/source_samba.py.
    - debian/rules, debian/samba.dirs, debian/samba-common-bin.files: install
  + Switch to upstart:
    - Add debian/samba.{nmbd,smbd}.upstart.
  + debian/samba.logrotate, debian/samba-common.dhcp, debian/samba.if-up:
    - Make them upstart compatible
  + debian/samba.postinst: 
    - Avoid scary pdbedit warnings on first import.
  + debian/samba-common.postinst: Add more informative error message for
    the case where smb.conf was manually deleted
  + debian/patches/fix-debuglevel-name-conflict.patch: don't use 'debug_level'
    as a global variable name in an NSS module 
  + Dropped:
    - debian/patches/error-trans.fix-276472
    - debian/patches/fix-debuglevel-name-conflict.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
296
296
        switch(type) {
297
297
        case SOCKET_TYPE_CHAR_TCP:
298
298
        case SOCKET_TYPE_CHAR_UDP: {
299
 
                struct sockaddr_in *in2 = (struct sockaddr_in *)in;
300
 
                
 
299
                struct sockaddr_in *in2 = (struct sockaddr_in *)(void *)in;
 
300
 
301
301
                if ((*len) < sizeof(*in2)) {
302
302
                    errno = EINVAL;
303
303
                    return -1;
314
314
#ifdef HAVE_IPV6
315
315
        case SOCKET_TYPE_CHAR_TCP_V6:
316
316
        case SOCKET_TYPE_CHAR_UDP_V6: {
317
 
                struct sockaddr_in6 *in2 = (struct sockaddr_in6 *)in;
318
 
                
 
317
                struct sockaddr_in6 *in2 = (struct sockaddr_in6 *)(void *)in;
 
318
 
319
319
                if ((*len) < sizeof(*in2)) {
320
320
                        errno = EINVAL;
321
321
                        return -1;
352
352
        switch (inaddr->sa_family) {
353
353
        case AF_INET: {
354
354
                const struct sockaddr_in *in = 
355
 
                    (const struct sockaddr_in *)inaddr;
 
355
                    (const struct sockaddr_in *)(const void *)inaddr;
356
356
                unsigned int addr = ntohl(in->sin_addr.s_addr);
357
357
                char u_type = '\0';
358
358
                char b_type = '\0';
395
395
#ifdef HAVE_IPV6
396
396
        case AF_INET6: {
397
397
                const struct sockaddr_in6 *in = 
398
 
                    (const struct sockaddr_in6 *)inaddr;
399
 
                struct in6_addr cmp;
 
398
                    (const struct sockaddr_in6 *)(const void *)inaddr;
 
399
                struct in6_addr cmp1, cmp2;
400
400
 
401
401
                switch (si->type) {
402
402
                case SOCK_STREAM:
411
411
 
412
412
                prt = ntohs(in->sin6_port);
413
413
 
414
 
                cmp = in->sin6_addr;
415
 
                cmp.s6_addr[15] = 0;
416
 
                if (IN6_ARE_ADDR_EQUAL(swrap_ipv6(), &cmp)) {
 
414
                cmp1 = *swrap_ipv6();
 
415
                cmp2 = in->sin6_addr;
 
416
                cmp2.s6_addr[15] = 0;
 
417
                if (IN6_ARE_ADDR_EQUAL(&cmp1, &cmp2)) {
417
418
                        iface = in->sin6_addr.s6_addr[15];
418
419
                } else {
419
420
                        errno = ENETUNREACH;
460
461
        switch (si->family) {
461
462
        case AF_INET: {
462
463
                const struct sockaddr_in *in = 
463
 
                    (const struct sockaddr_in *)inaddr;
 
464
                    (const struct sockaddr_in *)(const void *)inaddr;
464
465
                unsigned int addr = ntohl(in->sin_addr.s_addr);
465
466
                char u_type = '\0';
466
467
                char d_type = '\0';
511
512
#ifdef HAVE_IPV6
512
513
        case AF_INET6: {
513
514
                const struct sockaddr_in6 *in = 
514
 
                    (const struct sockaddr_in6 *)inaddr;
515
 
                struct in6_addr cmp;
 
515
                    (const struct sockaddr_in6 *)(const void *)inaddr;
 
516
                struct in6_addr cmp1, cmp2;
516
517
 
517
518
                switch (si->type) {
518
519
                case SOCK_STREAM:
527
528
 
528
529
                prt = ntohs(in->sin6_port);
529
530
 
530
 
                cmp = in->sin6_addr;
531
 
                cmp.s6_addr[15] = 0;
 
531
                cmp1 = *swrap_ipv6();
 
532
                cmp2 = in->sin6_addr;
 
533
                cmp2.s6_addr[15] = 0;
532
534
                if (IN6_IS_ADDR_UNSPECIFIED(&in->sin6_addr)) {
533
535
                        iface = socket_wrapper_default_iface();
534
 
                } else if (IN6_ARE_ADDR_EQUAL(swrap_ipv6(), &cmp)) {
 
536
                } else if (IN6_ARE_ADDR_EQUAL(&cmp1, &cmp2)) {
535
537
                        iface = in->sin6_addr.s6_addr[15];
536
538
                } else {
537
539
                        errno = EADDRNOTAVAIL;
584
586
static int sockaddr_convert_to_un(struct socket_info *si, const struct sockaddr *in_addr, socklen_t in_len, 
585
587
                                  struct sockaddr_un *out_addr, int alloc_sock, int *bcast)
586
588
{
 
589
        struct sockaddr *out = (struct sockaddr *)(void *)out_addr;
587
590
        if (!out_addr)
588
591
                return 0;
589
592
 
590
 
        out_addr->sun_family = AF_UNIX;
 
593
        out->sa_family = AF_UNIX;
 
594
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
 
595
        out->sa_len = sizeof(*out_addr);
 
596
#endif
591
597
 
592
598
        switch (in_addr->sa_family) {
593
599
        case AF_INET:
610
616
        default:
611
617
                break;
612
618
        }
613
 
        
 
619
 
614
620
        errno = EAFNOSUPPORT;
615
621
        return -1;
616
622
}
622
628
                                    struct sockaddr *out_addr,
623
629
                                    socklen_t *out_addrlen)
624
630
{
 
631
        int ret;
 
632
 
625
633
        if (out_addr == NULL || out_addrlen == NULL) 
626
634
                return 0;
627
635
 
643
651
                        errno = ESOCKTNOSUPPORT;
644
652
                        return -1;
645
653
                }
646
 
                return convert_un_in(in_addr, out_addr, out_addrlen);
 
654
                ret = convert_un_in(in_addr, out_addr, out_addrlen);
 
655
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
 
656
                out_addr->sa_len = *out_addrlen;
 
657
#endif
 
658
                return ret;
647
659
        default:
648
660
                break;
649
661
        }
959
971
                ip->v6.ver_prio         = 0x60; /* version 4 and 5 * 32 bit words */
960
972
                ip->v6.flow_label_high  = 0x00;
961
973
                ip->v6.flow_label_low   = 0x0000;
962
 
                ip->v6.payload_length   = htons(wire_len - icmp_truncate_len);//TODO
 
974
                ip->v6.payload_length   = htons(wire_len - icmp_truncate_len); /* TODO */
963
975
                ip->v6.next_header      = protocol;
964
976
                memcpy(ip->v6.src_addr, src_in6->sin6_addr.s6_addr, 16);
965
977
                memcpy(ip->v6.dest_addr, dest_in6->sin6_addr.s6_addr, 16);
1009
1021
                        ip->v6.ver_prio         = 0x60; /* version 4 and 5 * 32 bit words */
1010
1022
                        ip->v6.flow_label_high  = 0x00;
1011
1023
                        ip->v6.flow_label_low   = 0x0000;
1012
 
                        ip->v6.payload_length   = htons(wire_len - icmp_truncate_len);//TODO
 
1024
                        ip->v6.payload_length   = htons(wire_len - icmp_truncate_len); /* TODO */
1013
1025
                        ip->v6.next_header      = protocol;
1014
1026
                        memcpy(ip->v6.src_addr, dest_in6->sin6_addr.s6_addr, 16);
1015
1027
                        memcpy(ip->v6.dest_addr, src_in6->sin6_addr.s6_addr, 16);
1494
1506
        memset(&un_addr, 0, sizeof(un_addr));
1495
1507
        memset(&un_my_addr, 0, sizeof(un_my_addr));
1496
1508
 
1497
 
        ret = real_accept(s, (struct sockaddr *)&un_addr, &un_addrlen);
 
1509
        ret = real_accept(s, (struct sockaddr *)(void *)&un_addr, &un_addrlen);
1498
1510
        if (ret == -1) {
1499
1511
                free(my_addr);
1500
1512
                return ret;
1526
1538
        child_si->peername = sockaddr_dup(my_addr, len);
1527
1539
 
1528
1540
        if (addr != NULL && addrlen != NULL) {
1529
 
            *addrlen = len;
1530
 
            if (*addrlen >= len)
1531
 
                memcpy(addr, my_addr, len);
1532
 
            *addrlen = 0;
 
1541
                size_t copy_len = MIN(*addrlen, len);
 
1542
                if (copy_len > 0) {
 
1543
                        memcpy(addr, my_addr, copy_len);
 
1544
                }
 
1545
                *addrlen = len;
1533
1546
        }
1534
1547
 
1535
 
        ret = real_getsockname(fd, (struct sockaddr *)&un_my_addr, &un_my_addrlen);
 
1548
        ret = real_getsockname(fd, (struct sockaddr *)(void *)&un_my_addr,
 
1549
                               &un_my_addrlen);
1536
1550
        if (ret == -1) {
1537
1551
                free(child_si);
1538
1552
                close(fd);
1659
1673
                         "%s/"SOCKET_FORMAT, socket_wrapper_dir(),
1660
1674
                         type, socket_wrapper_default_iface(), port);
1661
1675
                if (stat(un_addr.sun_path, &st) == 0) continue;
1662
 
                
1663
 
                ret = real_bind(si->fd, (struct sockaddr *)&un_addr, sizeof(un_addr));
 
1676
 
 
1677
                ret = real_bind(si->fd, (struct sockaddr *)(void *)&un_addr,
 
1678
                                sizeof(un_addr));
1664
1679
                if (ret == -1) return ret;
1665
1680
 
1666
1681
                si->tmp_path = strdup(un_addr.sun_path);
1685
1700
        int ret;
1686
1701
        struct sockaddr_un un_addr;
1687
1702
        struct socket_info *si = find_socket_info(s);
 
1703
        int bcast = 0;
1688
1704
 
1689
1705
        if (!si) {
1690
1706
                return real_connect(s, serv_addr, addrlen);
1700
1716
                return -1;
1701
1717
        }
1702
1718
 
1703
 
        ret = sockaddr_convert_to_un(si, (const struct sockaddr *)serv_addr, addrlen, &un_addr, 0, NULL);
 
1719
        ret = sockaddr_convert_to_un(si, serv_addr,
 
1720
                                     addrlen, &un_addr, 0, &bcast);
1704
1721
        if (ret == -1) return -1;
1705
1722
 
 
1723
        if (bcast) {
 
1724
                errno = ENETUNREACH;
 
1725
                return -1;
 
1726
        }
 
1727
 
1706
1728
        if (si->type == SOCK_DGRAM) {
1707
1729
                si->defer_connect = 1;
1708
1730
                ret = 0;
1709
1731
        } else {
1710
1732
                swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0);
1711
1733
 
1712
 
                ret = real_connect(s, (struct sockaddr *)&un_addr,
 
1734
                ret = real_connect(s, (struct sockaddr *)(void *)&un_addr,
1713
1735
                                   sizeof(struct sockaddr_un));
1714
1736
        }
1715
1737
 
1745
1767
        si->myname_len = addrlen;
1746
1768
        si->myname = sockaddr_dup(myaddr, addrlen);
1747
1769
 
1748
 
        ret = sockaddr_convert_to_un(si, (const struct sockaddr *)myaddr, addrlen, &un_addr, 1, &si->bcast);
 
1770
        ret = sockaddr_convert_to_un(si, myaddr, addrlen, &un_addr, 1, &si->bcast);
1749
1771
        if (ret == -1) return -1;
1750
1772
 
1751
1773
        unlink(un_addr.sun_path);
1752
1774
 
1753
 
        ret = real_bind(s, (struct sockaddr *)&un_addr,
 
1775
        ret = real_bind(s, (struct sockaddr *)(void *)&un_addr,
1754
1776
                        sizeof(struct sockaddr_un));
1755
1777
 
1756
1778
        if (ret == 0) {
1849
1871
        }
1850
1872
}
1851
1873
 
 
1874
_PUBLIC_ int swrap_ioctl(int s, int r, void *p)
 
1875
{
 
1876
        int ret;
 
1877
        struct socket_info *si = find_socket_info(s);
 
1878
        int value;
 
1879
 
 
1880
        if (!si) {
 
1881
                return real_ioctl(s, r, p);
 
1882
        }
 
1883
 
 
1884
        ret = real_ioctl(s, r, p);
 
1885
 
 
1886
        switch (r) {
 
1887
        case FIONREAD:
 
1888
                value = *((int *)p);
 
1889
                if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) {
 
1890
                        swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
 
1891
                } else if (value == 0) { /* END OF FILE */
 
1892
                        swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
 
1893
                }
 
1894
                break;
 
1895
        }
 
1896
 
 
1897
        return ret;
 
1898
}
 
1899
 
 
1900
static ssize_t swrap_sendmsg_before(struct socket_info *si,
 
1901
                                    struct msghdr *msg,
 
1902
                                    struct iovec *tmp_iov,
 
1903
                                    struct sockaddr_un *tmp_un,
 
1904
                                    const struct sockaddr_un **to_un,
 
1905
                                    const struct sockaddr **to,
 
1906
                                    int *bcast)
 
1907
{
 
1908
        size_t i, len = 0;
 
1909
        ssize_t ret;
 
1910
 
 
1911
        if (to_un) {
 
1912
                *to_un = NULL;
 
1913
        }
 
1914
        if (to) {
 
1915
                *to = NULL;
 
1916
        }
 
1917
        if (bcast) {
 
1918
                *bcast = 0;
 
1919
        }
 
1920
 
 
1921
        switch (si->type) {
 
1922
        case SOCK_STREAM:
 
1923
                if (!si->connected) {
 
1924
                        errno = ENOTCONN;
 
1925
                        return -1;
 
1926
                }
 
1927
 
 
1928
                if (msg->msg_iovlen == 0) {
 
1929
                        break;
 
1930
                }
 
1931
 
 
1932
                /*
 
1933
                 * cut down to 1500 byte packets for stream sockets,
 
1934
                 * which makes it easier to format PCAP capture files
 
1935
                 * (as the caller will simply continue from here)
 
1936
                 */
 
1937
 
 
1938
                for (i=0; i < msg->msg_iovlen; i++) {
 
1939
                        size_t nlen;
 
1940
                        nlen = len + msg->msg_iov[i].iov_len;
 
1941
                        if (nlen > 1500) {
 
1942
                                break;
 
1943
                        }
 
1944
                }
 
1945
                msg->msg_iovlen = i;
 
1946
                if (msg->msg_iovlen == 0) {
 
1947
                        *tmp_iov = msg->msg_iov[0];
 
1948
                        tmp_iov->iov_len = MIN(tmp_iov->iov_len, 1500);
 
1949
                        msg->msg_iov = tmp_iov;
 
1950
                        msg->msg_iovlen = 1;
 
1951
                }
 
1952
                break;
 
1953
 
 
1954
        case SOCK_DGRAM:
 
1955
                if (si->connected) {
 
1956
                        if (msg->msg_name) {
 
1957
                                errno = EISCONN;
 
1958
                                return -1;
 
1959
                        }
 
1960
                } else {
 
1961
                        const struct sockaddr *msg_name;
 
1962
                        msg_name = (const struct sockaddr *)msg->msg_name;
 
1963
 
 
1964
                        if (msg_name == NULL) {
 
1965
                                errno = ENOTCONN;
 
1966
                                return -1;
 
1967
                        }
 
1968
 
 
1969
 
 
1970
                        ret = sockaddr_convert_to_un(si, msg_name, msg->msg_namelen,
 
1971
                                                     tmp_un, 0, bcast);
 
1972
                        if (ret == -1) return -1;
 
1973
 
 
1974
                        if (to_un) {
 
1975
                                *to_un = tmp_un;
 
1976
                        }
 
1977
                        if (to) {
 
1978
                                *to = msg_name;
 
1979
                        }
 
1980
                        msg->msg_name = tmp_un;
 
1981
                        msg->msg_namelen = sizeof(*tmp_un);
 
1982
                }
 
1983
 
 
1984
                if (si->bound == 0) {
 
1985
                        ret = swrap_auto_bind(si, si->family);
 
1986
                        if (ret == -1) return -1;
 
1987
                }
 
1988
 
 
1989
                if (!si->defer_connect) {
 
1990
                        break;
 
1991
                }
 
1992
 
 
1993
                ret = sockaddr_convert_to_un(si, si->peername, si->peername_len,
 
1994
                                             tmp_un, 0, NULL);
 
1995
                if (ret == -1) return -1;
 
1996
 
 
1997
                ret = real_connect(si->fd, (struct sockaddr *)(void *)tmp_un,
 
1998
                                   sizeof(*tmp_un));
 
1999
 
 
2000
                /* to give better errors */
 
2001
                if (ret == -1 && errno == ENOENT) {
 
2002
                        errno = EHOSTUNREACH;
 
2003
                }
 
2004
 
 
2005
                if (ret == -1) {
 
2006
                        return ret;
 
2007
                }
 
2008
 
 
2009
                si->defer_connect = 0;
 
2010
                break;
 
2011
        default:
 
2012
                errno = EHOSTUNREACH;
 
2013
                return -1;
 
2014
        }
 
2015
 
 
2016
        return 0;
 
2017
}
 
2018
 
 
2019
static void swrap_sendmsg_after(struct socket_info *si,
 
2020
                                struct msghdr *msg,
 
2021
                                const struct sockaddr *to,
 
2022
                                ssize_t ret)
 
2023
{
 
2024
        int saved_errno = errno;
 
2025
        size_t i, len = 0;
 
2026
        uint8_t *buf;
 
2027
        off_t ofs = 0;
 
2028
        size_t avail = 0;
 
2029
        size_t remain;
 
2030
 
 
2031
        /* to give better errors */
 
2032
        if (ret == -1 && saved_errno == ENOENT) {
 
2033
                saved_errno = EHOSTUNREACH;
 
2034
        }
 
2035
 
 
2036
        for (i=0; i < msg->msg_iovlen; i++) {
 
2037
                avail += msg->msg_iov[i].iov_len;
 
2038
        }
 
2039
 
 
2040
        if (ret == -1) {
 
2041
                remain = MIN(80, avail);
 
2042
        } else {
 
2043
                remain = ret;
 
2044
        }
 
2045
 
 
2046
        /* we capture it as one single packet */
 
2047
        buf = (uint8_t *)malloc(remain);
 
2048
        if (!buf) {
 
2049
                /* we just not capture the packet */
 
2050
                errno = saved_errno;
 
2051
                return;
 
2052
        }
 
2053
 
 
2054
        for (i=0; i < msg->msg_iovlen; i++) {
 
2055
                size_t this_time = MIN(remain, msg->msg_iov[i].iov_len);
 
2056
                memcpy(buf + ofs,
 
2057
                       msg->msg_iov[i].iov_base,
 
2058
                       this_time);
 
2059
                ofs += this_time;
 
2060
                remain -= this_time;
 
2061
        }
 
2062
        len = ofs;
 
2063
 
 
2064
        switch (si->type) {
 
2065
        case SOCK_STREAM:
 
2066
                if (ret == -1) {
 
2067
                        swrap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
 
2068
                        swrap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
 
2069
                } else {
 
2070
                        swrap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
 
2071
                }
 
2072
                break;
 
2073
 
 
2074
        case SOCK_DGRAM:
 
2075
                if (si->connected) {
 
2076
                        to = si->peername;
 
2077
                }
 
2078
                if (ret == -1) {
 
2079
                        swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
 
2080
                        swrap_dump_packet(si, to, SWRAP_SENDTO_UNREACH, buf, len);
 
2081
                } else {
 
2082
                        swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
 
2083
                }
 
2084
                break;
 
2085
        }
 
2086
 
 
2087
        free(buf);
 
2088
        errno = saved_errno;
 
2089
}
 
2090
 
1852
2091
_PUBLIC_ ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
1853
2092
{
1854
2093
        struct sockaddr_un un_addr;
1863
2102
        }
1864
2103
 
1865
2104
        if (!from) {
1866
 
                from = (struct sockaddr *)&ss;
 
2105
                from = (struct sockaddr *)(void *)&ss;
1867
2106
                fromlen = &ss_len;
1868
2107
        }
1869
2108
 
1876
2115
 
1877
2116
        /* irix 6.4 forgets to null terminate the sun_path string :-( */
1878
2117
        memset(&un_addr, 0, sizeof(un_addr));
1879
 
        ret = real_recvfrom(s, buf, len, flags, (struct sockaddr *)&un_addr, &un_addrlen);
 
2118
        ret = real_recvfrom(s, buf, len, flags,
 
2119
                            (struct sockaddr *)(void *)&un_addr, &un_addrlen);
1880
2120
        if (ret == -1) 
1881
2121
                return ret;
1882
2122
 
1893
2133
 
1894
2134
_PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen)
1895
2135
{
 
2136
        struct msghdr msg;
 
2137
        struct iovec tmp;
1896
2138
        struct sockaddr_un un_addr;
1897
 
        int ret;
 
2139
        const struct sockaddr_un *to_un = NULL;
 
2140
        ssize_t ret;
1898
2141
        struct socket_info *si = find_socket_info(s);
1899
2142
        int bcast = 0;
1900
2143
 
1902
2145
                return real_sendto(s, buf, len, flags, to, tolen);
1903
2146
        }
1904
2147
 
1905
 
        if (si->connected) {
1906
 
                if (to) {
1907
 
                        errno = EISCONN;
1908
 
                        return -1;
1909
 
                }
1910
 
 
1911
 
                to = si->peername;
1912
 
                tolen = si->peername_len;
1913
 
        }
1914
 
 
1915
 
        switch (si->type) {
1916
 
        case SOCK_STREAM:
1917
 
                /* cut down to 1500 byte packets for stream sockets,
1918
 
                 * which makes it easier to format PCAP capture files
1919
 
                 * (as the caller will simply continue from here) */
1920
 
                len = MIN(len, 1500);
1921
 
        
1922
 
                ret = real_send(s, buf, len, flags);
1923
 
                break;
1924
 
        case SOCK_DGRAM:
1925
 
                if (si->bound == 0) {
1926
 
                        ret = swrap_auto_bind(si, si->family);
1927
 
                        if (ret == -1) return -1;
1928
 
                }
1929
 
                
1930
 
                ret = sockaddr_convert_to_un(si, to, tolen, &un_addr, 0, &bcast);
1931
 
                if (ret == -1) return -1;
1932
 
                
1933
 
                if (bcast) {
1934
 
                        struct stat st;
1935
 
                        unsigned int iface;
1936
 
                        unsigned int prt = ntohs(((const struct sockaddr_in *)to)->sin_port);
1937
 
                        char type;
1938
 
                        
1939
 
                        type = SOCKET_TYPE_CHAR_UDP;
1940
 
                        
1941
 
                        for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
1942
 
                                snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT, 
1943
 
                                         socket_wrapper_dir(), type, iface, prt);
1944
 
                                if (stat(un_addr.sun_path, &st) != 0) continue;
1945
 
                                
1946
 
                                /* ignore the any errors in broadcast sends */
1947
 
                                real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr));
1948
 
                        }
1949
 
                        
1950
 
                        swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
1951
 
                        
1952
 
                        return len;
1953
 
                }
1954
 
 
1955
 
                if (si->defer_connect) {
1956
 
                        ret = real_connect(s, (struct sockaddr *)&un_addr,
1957
 
                                           sizeof(un_addr));
1958
 
 
1959
 
                        /* to give better errors */
1960
 
                        if (ret == -1 && errno == ENOENT) {
1961
 
                                errno = EHOSTUNREACH;
1962
 
                        }
1963
 
 
1964
 
                        if (ret == -1) {
1965
 
                                return ret;
1966
 
                        }
1967
 
                        si->defer_connect = 0;
1968
 
                }
1969
 
 
1970
 
                ret = real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr));
1971
 
                break;
1972
 
        default:
1973
 
                ret = -1;
1974
 
                errno = EHOSTUNREACH;
1975
 
                break;
1976
 
        }
1977
 
                
1978
 
        /* to give better errors */
1979
 
        if (ret == -1 && errno == ENOENT) {
1980
 
                errno = EHOSTUNREACH;
1981
 
        }
1982
 
 
1983
 
        if (ret == -1) {
 
2148
        tmp.iov_base = discard_const_p(char, buf);
 
2149
        tmp.iov_len = len;
 
2150
 
 
2151
        ZERO_STRUCT(msg);
 
2152
        msg.msg_name = discard_const_p(struct sockaddr, to); /* optional address */
 
2153
        msg.msg_namelen = tolen;       /* size of address */
 
2154
        msg.msg_iov = &tmp;            /* scatter/gather array */
 
2155
        msg.msg_iovlen = 1;            /* # elements in msg_iov */
 
2156
#if 0 /* not available on solaris */
 
2157
        msg.msg_control = NULL;        /* ancillary data, see below */
 
2158
        msg.msg_controllen = 0;        /* ancillary data buffer len */
 
2159
        msg.msg_flags = 0;             /* flags on received message */
 
2160
#endif
 
2161
 
 
2162
        ret = swrap_sendmsg_before(si, &msg, &tmp, &un_addr, &to_un, &to, &bcast);
 
2163
        if (ret == -1) return -1;
 
2164
 
 
2165
        buf = msg.msg_iov[0].iov_base;
 
2166
        len = msg.msg_iov[0].iov_len;
 
2167
 
 
2168
        if (bcast) {
 
2169
                struct stat st;
 
2170
                unsigned int iface;
 
2171
                unsigned int prt = ntohs(((const struct sockaddr_in *)to)->sin_port);
 
2172
                char type;
 
2173
 
 
2174
                type = SOCKET_TYPE_CHAR_UDP;
 
2175
 
 
2176
                for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
 
2177
                        snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT,
 
2178
                                 socket_wrapper_dir(), type, iface, prt);
 
2179
                        if (stat(un_addr.sun_path, &st) != 0) continue;
 
2180
 
 
2181
                        /* ignore the any errors in broadcast sends */
 
2182
                        real_sendto(s, buf, len, flags,
 
2183
                                    (struct sockaddr *)(void *)&un_addr,
 
2184
                                    sizeof(un_addr));
 
2185
                }
 
2186
 
1984
2187
                swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
1985
 
                swrap_dump_packet(si, to, SWRAP_SENDTO_UNREACH, buf, len);
1986
 
        } else {
1987
 
                swrap_dump_packet(si, to, SWRAP_SENDTO, buf, ret);
1988
 
        }
1989
 
 
1990
 
        return ret;
1991
 
}
1992
 
 
1993
 
_PUBLIC_ int swrap_ioctl(int s, int r, void *p)
1994
 
{
1995
 
        int ret;
1996
 
        struct socket_info *si = find_socket_info(s);
1997
 
        int value;
1998
 
 
1999
 
        if (!si) {
2000
 
                return real_ioctl(s, r, p);
2001
 
        }
2002
 
 
2003
 
        ret = real_ioctl(s, r, p);
2004
 
 
2005
 
        switch (r) {
2006
 
        case FIONREAD:
2007
 
                value = *((int *)p);
2008
 
                if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) {
2009
 
                        swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
2010
 
                } else if (value == 0) { /* END OF FILE */
2011
 
                        swrap_dump_packet(si, NULL, SWRAP_PENDING_RST, NULL, 0);
2012
 
                }
2013
 
                break;
2014
 
        }
 
2188
 
 
2189
                return len;
 
2190
        }
 
2191
 
 
2192
        ret = real_sendto(s, buf, len, flags, msg.msg_name, msg.msg_namelen);
 
2193
 
 
2194
        swrap_sendmsg_after(si, &msg, to, ret);
2015
2195
 
2016
2196
        return ret;
2017
2197
}
2075
2255
 
2076
2256
_PUBLIC_ ssize_t swrap_send(int s, const void *buf, size_t len, int flags)
2077
2257
{
2078
 
        int ret;
 
2258
        struct msghdr msg;
 
2259
        struct iovec tmp;
 
2260
        struct sockaddr_un un_addr;
 
2261
        ssize_t ret;
2079
2262
        struct socket_info *si = find_socket_info(s);
2080
2263
 
2081
2264
        if (!si) {
2082
2265
                return real_send(s, buf, len, flags);
2083
2266
        }
2084
2267
 
2085
 
        if (si->type == SOCK_STREAM) {
2086
 
                /* cut down to 1500 byte packets for stream sockets,
2087
 
                 * which makes it easier to format PCAP capture files
2088
 
                 * (as the caller will simply continue from here) */
2089
 
                len = MIN(len, 1500);
2090
 
        }
2091
 
 
2092
 
        if (si->defer_connect) {
2093
 
                struct sockaddr_un un_addr;
2094
 
                int bcast = 0;
2095
 
 
2096
 
                if (si->bound == 0) {
2097
 
                        ret = swrap_auto_bind(si, si->family);
2098
 
                        if (ret == -1) return -1;
2099
 
                }
2100
 
 
2101
 
                ret = sockaddr_convert_to_un(si, si->peername, si->peername_len,
2102
 
                                             &un_addr, 0, &bcast);
2103
 
                if (ret == -1) return -1;
2104
 
 
2105
 
                ret = real_connect(s, (struct sockaddr *)&un_addr,
2106
 
                                   sizeof(un_addr));
2107
 
 
2108
 
                /* to give better errors */
2109
 
                if (ret == -1 && errno == ENOENT) {
2110
 
                        errno = EHOSTUNREACH;
2111
 
                }
2112
 
 
2113
 
                if (ret == -1) {
2114
 
                        return ret;
2115
 
                }
2116
 
                si->defer_connect = 0;
2117
 
        }
 
2268
        tmp.iov_base = discard_const_p(char, buf);
 
2269
        tmp.iov_len = len;
 
2270
 
 
2271
        ZERO_STRUCT(msg);
 
2272
        msg.msg_name = NULL;           /* optional address */
 
2273
        msg.msg_namelen = 0;           /* size of address */
 
2274
        msg.msg_iov = &tmp;            /* scatter/gather array */
 
2275
        msg.msg_iovlen = 1;            /* # elements in msg_iov */
 
2276
#if 0 /* not available on solaris */
 
2277
        msg.msg_control = NULL;        /* ancillary data, see below */
 
2278
        msg.msg_controllen = 0;        /* ancillary data buffer len */
 
2279
        msg.msg_flags = 0;             /* flags on received message */
 
2280
#endif
 
2281
 
 
2282
        ret = swrap_sendmsg_before(si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
 
2283
        if (ret == -1) return -1;
 
2284
 
 
2285
        buf = msg.msg_iov[0].iov_base;
 
2286
        len = msg.msg_iov[0].iov_len;
2118
2287
 
2119
2288
        ret = real_send(s, buf, len, flags);
2120
2289
 
2121
 
        if (ret == -1) {
2122
 
                swrap_dump_packet(si, NULL, SWRAP_SEND, buf, len);
2123
 
                swrap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
2124
 
        } else {
2125
 
                swrap_dump_packet(si, NULL, SWRAP_SEND, buf, ret);
2126
 
        }
 
2290
        swrap_sendmsg_after(si, &msg, NULL, ret);
2127
2291
 
2128
2292
        return ret;
2129
2293
}
2130
2294
 
2131
 
_PUBLIC_ ssize_t swrap_sendmsg(int s, const struct msghdr *msg, int flags)
 
2295
_PUBLIC_ ssize_t swrap_sendmsg(int s, const struct msghdr *omsg, int flags)
2132
2296
{
2133
 
        int ret;
2134
 
        uint8_t *buf;
2135
 
        off_t ofs = 0;
2136
 
        size_t i;
2137
 
        size_t remain;
2138
 
        
 
2297
        struct msghdr msg;
 
2298
        struct iovec tmp;
 
2299
        struct sockaddr_un un_addr;
 
2300
        const struct sockaddr_un *to_un = NULL;
 
2301
        const struct sockaddr *to = NULL;
 
2302
        ssize_t ret;
2139
2303
        struct socket_info *si = find_socket_info(s);
 
2304
        int bcast = 0;
2140
2305
 
2141
2306
        if (!si) {
2142
 
                return real_sendmsg(s, msg, flags);
2143
 
        }
2144
 
 
2145
 
        if (si->defer_connect) {
2146
 
                struct sockaddr_un un_addr;
2147
 
                int bcast = 0;
2148
 
 
2149
 
                if (si->bound == 0) {
2150
 
                        ret = swrap_auto_bind(si, si->family);
2151
 
                        if (ret == -1) return -1;
2152
 
                }
2153
 
 
2154
 
                ret = sockaddr_convert_to_un(si, si->peername, si->peername_len,
2155
 
                                             &un_addr, 0, &bcast);
2156
 
                if (ret == -1) return -1;
2157
 
 
2158
 
                ret = real_connect(s, (struct sockaddr *)&un_addr,
2159
 
                                   sizeof(un_addr));
2160
 
 
2161
 
                /* to give better errors */
2162
 
                if (ret == -1 && errno == ENOENT) {
2163
 
                        errno = EHOSTUNREACH;
2164
 
                }
2165
 
 
2166
 
                if (ret == -1) {
2167
 
                        return ret;
2168
 
                }
2169
 
                si->defer_connect = 0;
2170
 
        }
2171
 
 
2172
 
        ret = real_sendmsg(s, msg, flags);
2173
 
        remain = ret;
2174
 
                
2175
 
        /* we capture it as one single packet */
2176
 
        buf = (uint8_t *)malloc(ret);
2177
 
        if (!buf) {
2178
 
                /* we just not capture the packet */
2179
 
                errno = 0;
2180
 
                return ret;
2181
 
        }
2182
 
        
2183
 
        for (i=0; i < msg->msg_iovlen; i++) {
2184
 
                size_t this_time = MIN(remain, msg->msg_iov[i].iov_len);
2185
 
                memcpy(buf + ofs,
2186
 
                       msg->msg_iov[i].iov_base,
2187
 
                       this_time);
2188
 
                ofs += this_time;
2189
 
                remain -= this_time;
2190
 
        }
2191
 
        
2192
 
        swrap_dump_packet(si, NULL, SWRAP_SEND, buf, ret);
2193
 
        free(buf);
2194
 
        if (ret == -1) {
2195
 
                swrap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
2196
 
        }
 
2307
                return real_sendmsg(s, omsg, flags);
 
2308
        }
 
2309
 
 
2310
        tmp.iov_base = NULL;
 
2311
        tmp.iov_len = 0;
 
2312
 
 
2313
        msg = *omsg;
 
2314
#if 0
 
2315
        msg.msg_name = omsg->msg_name;             /* optional address */
 
2316
        msg.msg_namelen = omsg->msg_namelen;       /* size of address */
 
2317
        msg.msg_iov = omsg->msg_iov;               /* scatter/gather array */
 
2318
        msg.msg_iovlen = omsg->msg_iovlen;         /* # elements in msg_iov */
 
2319
        /* the following is not available on solaris */
 
2320
        msg.msg_control = omsg->msg_control;       /* ancillary data, see below */
 
2321
        msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */
 
2322
        msg.msg_flags = omsg->msg_flags;           /* flags on received message */
 
2323
#endif
 
2324
 
 
2325
        ret = swrap_sendmsg_before(si, &msg, &tmp, &un_addr, &to_un, &to, &bcast);
 
2326
        if (ret == -1) return -1;
 
2327
 
 
2328
        if (bcast) {
 
2329
                struct stat st;
 
2330
                unsigned int iface;
 
2331
                unsigned int prt = ntohs(((const struct sockaddr_in *)to)->sin_port);
 
2332
                char type;
 
2333
                size_t i, len = 0;
 
2334
                uint8_t *buf;
 
2335
                off_t ofs = 0;
 
2336
                size_t avail = 0;
 
2337
                size_t remain;
 
2338
 
 
2339
                for (i=0; i < msg.msg_iovlen; i++) {
 
2340
                        avail += msg.msg_iov[i].iov_len;
 
2341
                }
 
2342
 
 
2343
                len = avail;
 
2344
                remain = avail;
 
2345
 
 
2346
                /* we capture it as one single packet */
 
2347
                buf = (uint8_t *)malloc(remain);
 
2348
                if (!buf) {
 
2349
                        return -1;
 
2350
                }
 
2351
 
 
2352
                for (i=0; i < msg.msg_iovlen; i++) {
 
2353
                        size_t this_time = MIN(remain, msg.msg_iov[i].iov_len);
 
2354
                        memcpy(buf + ofs,
 
2355
                               msg.msg_iov[i].iov_base,
 
2356
                               this_time);
 
2357
                        ofs += this_time;
 
2358
                        remain -= this_time;
 
2359
                }
 
2360
 
 
2361
                type = SOCKET_TYPE_CHAR_UDP;
 
2362
 
 
2363
                for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) {
 
2364
                        snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT,
 
2365
                                 socket_wrapper_dir(), type, iface, prt);
 
2366
                        if (stat(un_addr.sun_path, &st) != 0) continue;
 
2367
 
 
2368
                        msg.msg_name = &un_addr;           /* optional address */
 
2369
                        msg.msg_namelen = sizeof(un_addr); /* size of address */
 
2370
 
 
2371
                        /* ignore the any errors in broadcast sends */
 
2372
                        real_sendmsg(s, &msg, flags);
 
2373
                }
 
2374
 
 
2375
                swrap_dump_packet(si, to, SWRAP_SENDTO, buf, len);
 
2376
                free(buf);
 
2377
 
 
2378
                return len;
 
2379
        }
 
2380
 
 
2381
        ret = real_sendmsg(s, &msg, flags);
 
2382
 
 
2383
        swrap_sendmsg_after(si, &msg, to, ret);
2197
2384
 
2198
2385
        return ret;
2199
2386
}
2208
2395
                return real_readv(s, vector, count);
2209
2396
        }
2210
2397
 
 
2398
        if (!si->connected) {
 
2399
                errno = ENOTCONN;
 
2400
                return -1;
 
2401
        }
 
2402
 
2211
2403
        if (si->type == SOCK_STREAM && count > 0) {
2212
2404
                /* cut down to 1500 byte packets for stream sockets,
2213
2405
                 * which makes it easier to format PCAP capture files
2214
2406
                 * (as the caller will simply continue from here) */
2215
2407
                size_t i, len = 0;
2216
 
                
 
2408
 
2217
2409
                for (i=0; i < count; i++) {
2218
2410
                        size_t nlen;
2219
2411
                        nlen = len + vector[i].iov_len;
2267
2459
 
2268
2460
int swrap_writev(int s, const struct iovec *vector, size_t count)
2269
2461
{
2270
 
        int ret;
 
2462
        struct msghdr msg;
 
2463
        struct iovec tmp;
 
2464
        struct sockaddr_un un_addr;
 
2465
        ssize_t ret;
2271
2466
        struct socket_info *si = find_socket_info(s);
2272
 
        struct iovec v;
2273
2467
 
2274
2468
        if (!si) {
2275
2469
                return real_writev(s, vector, count);
2276
2470
        }
2277
2471
 
2278
 
        if (si->type == SOCK_STREAM && count > 0) {
2279
 
                /* cut down to 1500 byte packets for stream sockets,
2280
 
                 * which makes it easier to format PCAP capture files
2281
 
                 * (as the caller will simply continue from here) */
2282
 
                size_t i, len = 0;
2283
 
 
2284
 
                for (i=0; i < count; i++) {
2285
 
                        size_t nlen;
2286
 
                        nlen = len + vector[i].iov_len;
2287
 
                        if (nlen > 1500) {
2288
 
                                break;
2289
 
                        }
2290
 
                }
2291
 
                count = i;
2292
 
                if (count == 0) {
2293
 
                        v = vector[0];
2294
 
                        v.iov_len = MIN(v.iov_len, 1500);
2295
 
                        vector = &v;
2296
 
                        count = 1;
2297
 
                }
2298
 
        }
2299
 
 
2300
 
        ret = real_writev(s, vector, count);
2301
 
        if (ret == -1) {
2302
 
                swrap_dump_packet(si, NULL, SWRAP_SEND_RST, NULL, 0);
2303
 
        } else {
2304
 
                uint8_t *buf;
2305
 
                off_t ofs = 0;
2306
 
                size_t i;
2307
 
                size_t remain = ret;
2308
 
 
2309
 
                /* we capture it as one single packet */
2310
 
                buf = (uint8_t *)malloc(ret);
2311
 
                if (!buf) {
2312
 
                        /* we just not capture the packet */
2313
 
                        errno = 0;
2314
 
                        return ret;
2315
 
                }
2316
 
 
2317
 
                for (i=0; i < count; i++) {
2318
 
                        size_t this_time = MIN(remain, vector[i].iov_len);
2319
 
                        memcpy(buf + ofs,
2320
 
                               vector[i].iov_base,
2321
 
                               this_time);
2322
 
                        ofs += this_time;
2323
 
                        remain -= this_time;
2324
 
                }
2325
 
 
2326
 
                swrap_dump_packet(si, NULL, SWRAP_SEND, buf, ret);
2327
 
                free(buf);
2328
 
        }
 
2472
        tmp.iov_base = NULL;
 
2473
        tmp.iov_len = 0;
 
2474
 
 
2475
        ZERO_STRUCT(msg);
 
2476
        msg.msg_name = NULL;           /* optional address */
 
2477
        msg.msg_namelen = 0;           /* size of address */
 
2478
        msg.msg_iov = discard_const_p(struct iovec, vector); /* scatter/gather array */
 
2479
        msg.msg_iovlen = count;        /* # elements in msg_iov */
 
2480
#if 0 /* not available on solaris */
 
2481
        msg.msg_control = NULL;        /* ancillary data, see below */
 
2482
        msg.msg_controllen = 0;        /* ancillary data buffer len */
 
2483
        msg.msg_flags = 0;             /* flags on received message */
 
2484
#endif
 
2485
 
 
2486
        ret = swrap_sendmsg_before(si, &msg, &tmp, &un_addr, NULL, NULL, NULL);
 
2487
        if (ret == -1) return -1;
 
2488
 
 
2489
        ret = real_writev(s, msg.msg_iov, msg.msg_iovlen);
 
2490
 
 
2491
        swrap_sendmsg_after(si, &msg, NULL, ret);
2329
2492
 
2330
2493
        return ret;
2331
2494
}