96 struct socklist socklist;
97
98 struct kmem_cache *socket_cache;
99
100 /*
101 * sockconf_lock protects the socket configuration (socket types and
102 * socket filters) which is changed via the sockconfig system call.
103 */
104 krwlock_t sockconf_lock;
105
106 static int sockfs_update(kstat_t *, int);
107 static int sockfs_snapshot(kstat_t *, void *, int);
108 extern smod_info_t *sotpi_smod_create(void);
109
110 extern void sendfile_init();
111
112 extern void nl7c_init(void);
113
114 extern int modrootloaded;
115
116 #define ADRSTRLEN (2 * sizeof (void *) + 1)
117 /*
118 * kernel structure for passing the sockinfo data back up to the user.
119 * the strings array allows us to convert AF_UNIX addresses into strings
120 * with a common method regardless of which n-bit kernel we're running.
121 */
122 struct k_sockinfo {
123 struct sockinfo ks_si;
124 char ks_straddr[3][ADRSTRLEN];
125 };
126
127 /*
128 * Translate from a device pathname (e.g. "/dev/tcp") to a vnode.
129 * Returns with the vnode held.
130 */
131 int
132 sogetvp(char *devpath, vnode_t **vpp, int uioflag)
133 {
134 struct snode *csp;
135 vnode_t *vp, *dvp;
136 major_t maj;
137 int error;
138
139 ASSERT(uioflag == UIO_SYSSPACE || uioflag == UIO_USERSPACE);
140
141 /*
142 * Lookup the underlying filesystem vnode.
143 */
144 error = lookupname(devpath, uioflag, FOLLOW, NULLVPP, &vp);
145 if (error)
146 return (error);
749 * The latter is needed since we always call fdbuf_free
750 * which performs a closef.
751 */
752 rp = (int *)rights;
753 for (i = 0; i < numfd; i++) {
754 if ((fd = ufalloc(0)) == -1)
755 goto cleanup;
756 /*
757 * We need pointer size alignment for fd_fds. On a LP64
758 * kernel, the required alignment is 8 bytes while
759 * the option headers and values are only 4 bytes
760 * aligned. So its safer to do a bcopy compared to
761 * assigning fdbuf->fd_fds[i] to fp.
762 */
763 bcopy((char *)&fdbuf->fd_fds[i], (char *)&fp, sizeof (fp));
764 mutex_enter(&fp->f_tlock);
765 fp->f_count++;
766 mutex_exit(&fp->f_tlock);
767 setf(fd, fp);
768 *rp++ = fd;
769 if (AU_AUDITING())
770 audit_fdrecv(fd, fp);
771 dprint(1, ("fdbuf_extract: [%d] = %d, %p refcnt %d\n",
772 i, fd, (void *)fp, fp->f_count));
773 }
774 return (0);
775
776 cleanup:
777 /*
778 * Undo whatever partial work the loop above has done.
779 */
780 {
781 int j;
782
783 rp = (int *)rights;
784 for (j = 0; j < i; j++) {
785 dprint(0,
786 ("fdbuf_extract: cleanup[%d] = %d\n", j, *rp));
787 (void) closeandsetf(*rp++, NULL);
788 }
1729 if (ksp != NULL) {
1730 ASSERT(zoneid == (zoneid_t)(uintptr_t)ksp->ks_private);
1731 kstat_delete(ksp);
1732 }
1733 }
1734
1735 /*
1736 * Zones:
1737 * Note that nactive is going to be different for each zone.
1738 * This means we require kstat to call sockfs_update and then sockfs_snapshot
1739 * for the same zone, or sockfs_snapshot will be taken into the wrong size
1740 * buffer. This is safe, but if the buffer is too small, user will not be
1741 * given details of all sockets. However, as this kstat has a ks_lock, kstat
1742 * driver will keep it locked between the update and the snapshot, so no
1743 * other process (zone) can currently get inbetween resulting in a wrong size
1744 * buffer allocation.
1745 */
1746 static int
1747 sockfs_update(kstat_t *ksp, int rw)
1748 {
1749 uint_t nactive = 0; /* # of active AF_UNIX sockets */
1750 struct sonode *so; /* current sonode on socklist */
1751 zoneid_t myzoneid = (zoneid_t)(uintptr_t)ksp->ks_private;
1752
1753 ASSERT((zoneid_t)(uintptr_t)ksp->ks_private == getzoneid());
1754
1755 if (rw == KSTAT_WRITE) { /* bounce all writes */
1756 return (EACCES);
1757 }
1758
1759 for (so = socklist.sl_list; so != NULL; so = SOTOTPI(so)->sti_next_so) {
1760 if (so->so_count != 0 && so->so_zoneid == myzoneid) {
1761 nactive++;
1762 }
1763 }
1764 ksp->ks_ndata = nactive;
1765 ksp->ks_data_size = nactive * sizeof (struct k_sockinfo);
1766
1767 return (0);
1768 }
1769
1770 static int
1771 sockfs_snapshot(kstat_t *ksp, void *buf, int rw)
1772 {
1773 int ns; /* # of sonodes we've copied */
1774 struct sonode *so; /* current sonode on socklist */
1775 struct k_sockinfo *pksi; /* where we put sockinfo data */
1776 t_uscalar_t sn_len; /* soa_len */
1777 zoneid_t myzoneid = (zoneid_t)(uintptr_t)ksp->ks_private;
1778 sotpi_info_t *sti;
1779
1780 ASSERT((zoneid_t)(uintptr_t)ksp->ks_private == getzoneid());
1781
1782 ksp->ks_snaptime = gethrtime();
1783
1784 if (rw == KSTAT_WRITE) { /* bounce all writes */
1785 return (EACCES);
1786 }
1787
1788 /*
1789 * for each sonode on the socklist, we massage the important
1790 * info into buf, in k_sockinfo format.
1791 */
1792 pksi = (struct k_sockinfo *)buf;
1793 ns = 0;
1794 for (so = socklist.sl_list; so != NULL; so = SOTOTPI(so)->sti_next_so) {
1795 /* only stuff active sonodes and the same zone: */
1796 if (so->so_count == 0 || so->so_zoneid != myzoneid) {
1797 continue;
1798 }
1799
1800 /*
1801 * If the sonode was activated between the update and the
1802 * snapshot, we're done - as this is only a snapshot.
1803 */
1804 if ((caddr_t)(pksi) >= (caddr_t)buf + ksp->ks_data_size) {
1805 break;
1806 }
1807
1808 sti = SOTOTPI(so);
1809 /* copy important info into buf: */
1810 pksi->ks_si.si_size = sizeof (struct k_sockinfo);
1811 pksi->ks_si.si_family = so->so_family;
1812 pksi->ks_si.si_type = so->so_type;
1813 pksi->ks_si.si_flag = so->so_flag;
1814 pksi->ks_si.si_state = so->so_state;
1815 pksi->ks_si.si_serv_type = sti->sti_serv_type;
1816 pksi->ks_si.si_ux_laddr_sou_magic =
1817 sti->sti_ux_laddr.soua_magic;
1818 pksi->ks_si.si_ux_faddr_sou_magic =
1819 sti->sti_ux_faddr.soua_magic;
1820 pksi->ks_si.si_laddr_soa_len = sti->sti_laddr.soa_len;
1821 pksi->ks_si.si_faddr_soa_len = sti->sti_faddr.soa_len;
1822 pksi->ks_si.si_szoneid = so->so_zoneid;
1823 pksi->ks_si.si_faddr_noxlate = sti->sti_faddr_noxlate;
1824
1825 mutex_enter(&so->so_lock);
1826
1827 if (sti->sti_laddr_sa != NULL) {
1828 ASSERT(sti->sti_laddr_sa->sa_data != NULL);
1829 sn_len = sti->sti_laddr_len;
1830 ASSERT(sn_len <= sizeof (short) +
1831 sizeof (pksi->ks_si.si_laddr_sun_path));
1832
1833 pksi->ks_si.si_laddr_family =
1834 sti->sti_laddr_sa->sa_family;
1835 if (sn_len != 0) {
1836 /* AF_UNIX socket names are NULL terminated */
1837 (void) strncpy(pksi->ks_si.si_laddr_sun_path,
1838 sti->sti_laddr_sa->sa_data,
1839 sizeof (pksi->ks_si.si_laddr_sun_path));
1840 sn_len = strlen(pksi->ks_si.si_laddr_sun_path);
1841 }
1842 pksi->ks_si.si_laddr_sun_path[sn_len] = 0;
1843 }
1844
1845 if (sti->sti_faddr_sa != NULL) {
1846 ASSERT(sti->sti_faddr_sa->sa_data != NULL);
1847 sn_len = sti->sti_faddr_len;
1848 ASSERT(sn_len <= sizeof (short) +
1849 sizeof (pksi->ks_si.si_faddr_sun_path));
1850
1851 pksi->ks_si.si_faddr_family =
1852 sti->sti_faddr_sa->sa_family;
1853 if (sn_len != 0) {
1854 (void) strncpy(pksi->ks_si.si_faddr_sun_path,
1855 sti->sti_faddr_sa->sa_data,
1856 sizeof (pksi->ks_si.si_faddr_sun_path));
1857 sn_len = strlen(pksi->ks_si.si_faddr_sun_path);
1858 }
1859 pksi->ks_si.si_faddr_sun_path[sn_len] = 0;
1860 }
1861
1862 mutex_exit(&so->so_lock);
1863
1864 (void) sprintf(pksi->ks_straddr[0], "%p", (void *)so);
1865 (void) sprintf(pksi->ks_straddr[1], "%p",
1866 (void *)sti->sti_ux_laddr.soua_vp);
1867 (void) sprintf(pksi->ks_straddr[2], "%p",
1868 (void *)sti->sti_ux_faddr.soua_vp);
1869
1870 ns++;
1871 pksi++;
1872 }
1873
1874 ksp->ks_ndata = ns;
1875 return (0);
1876 }
1877
1878 ssize_t
1879 soreadfile(file_t *fp, uchar_t *buf, u_offset_t fileoff, int *err, size_t size)
1880 {
1881 struct uio auio;
1882 struct iovec aiov[MSG_MAXIOVLEN];
1883 register vnode_t *vp;
1884 int ioflag, rwflag;
1885 ssize_t cnt;
1886 int error = 0;
1887 int iovcnt = 0;
1888 short fflag;
1889
1890 vp = fp->f_vnode;
1891 fflag = fp->f_flag;
|
96 struct socklist socklist;
97
98 struct kmem_cache *socket_cache;
99
100 /*
101 * sockconf_lock protects the socket configuration (socket types and
102 * socket filters) which is changed via the sockconfig system call.
103 */
104 krwlock_t sockconf_lock;
105
106 static int sockfs_update(kstat_t *, int);
107 static int sockfs_snapshot(kstat_t *, void *, int);
108 extern smod_info_t *sotpi_smod_create(void);
109
110 extern void sendfile_init();
111
112 extern void nl7c_init(void);
113
114 extern int modrootloaded;
115
116 /*
117 * Translate from a device pathname (e.g. "/dev/tcp") to a vnode.
118 * Returns with the vnode held.
119 */
120 int
121 sogetvp(char *devpath, vnode_t **vpp, int uioflag)
122 {
123 struct snode *csp;
124 vnode_t *vp, *dvp;
125 major_t maj;
126 int error;
127
128 ASSERT(uioflag == UIO_SYSSPACE || uioflag == UIO_USERSPACE);
129
130 /*
131 * Lookup the underlying filesystem vnode.
132 */
133 error = lookupname(devpath, uioflag, FOLLOW, NULLVPP, &vp);
134 if (error)
135 return (error);
738 * The latter is needed since we always call fdbuf_free
739 * which performs a closef.
740 */
741 rp = (int *)rights;
742 for (i = 0; i < numfd; i++) {
743 if ((fd = ufalloc(0)) == -1)
744 goto cleanup;
745 /*
746 * We need pointer size alignment for fd_fds. On a LP64
747 * kernel, the required alignment is 8 bytes while
748 * the option headers and values are only 4 bytes
749 * aligned. So its safer to do a bcopy compared to
750 * assigning fdbuf->fd_fds[i] to fp.
751 */
752 bcopy((char *)&fdbuf->fd_fds[i], (char *)&fp, sizeof (fp));
753 mutex_enter(&fp->f_tlock);
754 fp->f_count++;
755 mutex_exit(&fp->f_tlock);
756 setf(fd, fp);
757 *rp++ = fd;
758
759 /*
760 * Add the current pid to the list associated with this
761 * descriptor.
762 */
763 if (fp->f_vnode != NULL)
764 (void) VOP_IOCTL(fp->f_vnode, F_ASSOCI_PID,
765 (intptr_t)curproc->p_pidp->pid_id, FKIOCTL, kcred,
766 NULL, NULL);
767
768 if (AU_AUDITING())
769 audit_fdrecv(fd, fp);
770 dprint(1, ("fdbuf_extract: [%d] = %d, %p refcnt %d\n",
771 i, fd, (void *)fp, fp->f_count));
772 }
773 return (0);
774
775 cleanup:
776 /*
777 * Undo whatever partial work the loop above has done.
778 */
779 {
780 int j;
781
782 rp = (int *)rights;
783 for (j = 0; j < i; j++) {
784 dprint(0,
785 ("fdbuf_extract: cleanup[%d] = %d\n", j, *rp));
786 (void) closeandsetf(*rp++, NULL);
787 }
1728 if (ksp != NULL) {
1729 ASSERT(zoneid == (zoneid_t)(uintptr_t)ksp->ks_private);
1730 kstat_delete(ksp);
1731 }
1732 }
1733
1734 /*
1735 * Zones:
1736 * Note that nactive is going to be different for each zone.
1737 * This means we require kstat to call sockfs_update and then sockfs_snapshot
1738 * for the same zone, or sockfs_snapshot will be taken into the wrong size
1739 * buffer. This is safe, but if the buffer is too small, user will not be
1740 * given details of all sockets. However, as this kstat has a ks_lock, kstat
1741 * driver will keep it locked between the update and the snapshot, so no
1742 * other process (zone) can currently get inbetween resulting in a wrong size
1743 * buffer allocation.
1744 */
1745 static int
1746 sockfs_update(kstat_t *ksp, int rw)
1747 {
1748 uint_t n, nactive = 0; /* # of active AF_UNIX sockets */
1749 uint_t tsze = 0;
1750 struct sonode *so; /* current sonode on socklist */
1751 zoneid_t myzoneid = (zoneid_t)(uintptr_t)ksp->ks_private;
1752
1753 ASSERT((zoneid_t)(uintptr_t)ksp->ks_private == getzoneid());
1754
1755 if (rw == KSTAT_WRITE) { /* bounce all writes */
1756 return (EACCES);
1757 }
1758
1759 for (so = socklist.sl_list; so != NULL; so = SOTOTPI(so)->sti_next_so) {
1760 if (so->so_count != 0 && so->so_zoneid == myzoneid) {
1761
1762 nactive++;
1763
1764 mutex_enter(&so->so_pid_tree_lock);
1765 n = avl_numnodes(&so->so_pid_tree);
1766 mutex_exit(&so->so_pid_tree_lock);
1767
1768 tsze += sizeof (struct sockinfo);
1769 tsze += (n > 1) ? ((n - 1) * sizeof (pid_t)) : 0;
1770 }
1771 }
1772 ksp->ks_ndata = nactive;
1773 ksp->ks_data_size = tsze;
1774
1775 return (0);
1776 }
1777
1778 static int
1779 sockfs_snapshot(kstat_t *ksp, void *buf, int rw)
1780 {
1781 int ns; /* # of sonodes we've copied */
1782 struct sonode *so; /* current sonode on socklist */
1783 struct sockinfo *psi; /* where we put sockinfo data */
1784 t_uscalar_t sn_len; /* soa_len */
1785 zoneid_t myzoneid = (zoneid_t)(uintptr_t)ksp->ks_private;
1786 sotpi_info_t *sti;
1787
1788 uint_t sze;
1789 mblk_t *mblk;
1790 conn_pid_info_t *cpi;
1791
1792 ASSERT((zoneid_t)(uintptr_t)ksp->ks_private == getzoneid());
1793
1794 ksp->ks_snaptime = gethrtime();
1795
1796 if (rw == KSTAT_WRITE) { /* bounce all writes */
1797 return (EACCES);
1798 }
1799
1800 /*
1801 * for each sonode on the socklist, we massage the important
1802 * info into buf, in k_sockinfo format.
1803 */
1804 psi = (struct sockinfo *)buf;
1805 ns = 0;
1806 for (so = socklist.sl_list; so != NULL; so = SOTOTPI(so)->sti_next_so) {
1807 /* only stuff active sonodes and the same zone: */
1808 if (so->so_count == 0 || so->so_zoneid != myzoneid) {
1809 continue;
1810 }
1811
1812 mblk = so_get_sock_pid_mblk((sock_upper_handle_t)so);
1813 if (mblk == NULL) {
1814 continue;
1815 }
1816 cpi = (conn_pid_info_t *)mblk->b_datap->db_base;
1817 sze = sizeof (struct sockinfo);
1818 sze += (cpi->cpi_pids_cnt > 1) ?
1819 ((cpi->cpi_pids_cnt - 1) * sizeof (pid_t)) : 0;
1820
1821 /*
1822 * If the sonode was activated between the update and the
1823 * snapshot, we're done - as this is only a snapshot. We need
1824 * to make sure that we have space for this sockinfo. In the
1825 * time window between the update and the snapshot, the size of
1826 * sockinfo may change, as new pids are added/removed to/from
1827 * the list. We have to take that into consideration and only
1828 * include the sockinfo if we have enough space. That means the
1829 * number of entries we return by snapshot might not equal the
1830 * the number of entries calculated by update.
1831 */
1832 if (((caddr_t)(psi) + sze) >
1833 ((caddr_t)buf + ksp->ks_data_size)) {
1834 break;
1835 }
1836
1837 sti = SOTOTPI(so);
1838 /* copy important info into buf: */
1839 psi->si_size = sze;
1840 psi->si_family = so->so_family;
1841 psi->si_type = so->so_type;
1842 psi->si_flag = so->so_flag;
1843 psi->si_state = so->so_state;
1844 psi->si_serv_type = sti->sti_serv_type;
1845 psi->si_ux_laddr_sou_magic =
1846 sti->sti_ux_laddr.soua_magic;
1847 psi->si_ux_faddr_sou_magic =
1848 sti->sti_ux_faddr.soua_magic;
1849 psi->si_laddr_soa_len = sti->sti_laddr.soa_len;
1850 psi->si_faddr_soa_len = sti->sti_faddr.soa_len;
1851 psi->si_szoneid = so->so_zoneid;
1852 psi->si_faddr_noxlate = sti->sti_faddr_noxlate;
1853
1854
1855 mutex_enter(&so->so_lock);
1856
1857 if (sti->sti_laddr_sa != NULL) {
1858 ASSERT(sti->sti_laddr_sa->sa_data != NULL);
1859 sn_len = sti->sti_laddr_len;
1860 ASSERT(sn_len <= sizeof (short) +
1861 sizeof (psi->si_laddr_sun_path));
1862
1863 psi->si_laddr_family =
1864 sti->sti_laddr_sa->sa_family;
1865 if (sn_len != 0) {
1866 /* AF_UNIX socket names are NULL terminated */
1867 (void) strncpy(psi->si_laddr_sun_path,
1868 sti->sti_laddr_sa->sa_data,
1869 sizeof (psi->si_laddr_sun_path));
1870 sn_len = strlen(psi->si_laddr_sun_path);
1871 }
1872 psi->si_laddr_sun_path[sn_len] = 0;
1873 }
1874
1875 if (sti->sti_faddr_sa != NULL) {
1876 ASSERT(sti->sti_faddr_sa->sa_data != NULL);
1877 sn_len = sti->sti_faddr_len;
1878 ASSERT(sn_len <= sizeof (short) +
1879 sizeof (psi->si_faddr_sun_path));
1880
1881 psi->si_faddr_family =
1882 sti->sti_faddr_sa->sa_family;
1883 if (sn_len != 0) {
1884 (void) strncpy(psi->si_faddr_sun_path,
1885 sti->sti_faddr_sa->sa_data,
1886 sizeof (psi->si_faddr_sun_path));
1887 sn_len = strlen(psi->si_faddr_sun_path);
1888 }
1889 psi->si_faddr_sun_path[sn_len] = 0;
1890 }
1891
1892 mutex_exit(&so->so_lock);
1893
1894 (void) sprintf(psi->si_son_straddr, "%p", (void *)so);
1895 (void) sprintf(psi->si_lvn_straddr, "%p",
1896 (void *)sti->sti_ux_laddr.soua_vp);
1897 (void) sprintf(psi->si_fvn_straddr, "%p",
1898 (void *)sti->sti_ux_faddr.soua_vp);
1899
1900 psi->si_pids[0] = 0;
1901 if ((psi->si_pn_cnt = cpi->cpi_pids_cnt) > 0) {
1902 (void) memcpy(psi->si_pids, cpi->cpi_pids,
1903 psi->si_pn_cnt * sizeof (pid_t));
1904 }
1905
1906 freemsg(mblk);
1907
1908 psi = (struct sockinfo *)((caddr_t)psi + psi->si_size);
1909 ns++;
1910 }
1911
1912 ksp->ks_ndata = ns;
1913 return (0);
1914 }
1915
1916 ssize_t
1917 soreadfile(file_t *fp, uchar_t *buf, u_offset_t fileoff, int *err, size_t size)
1918 {
1919 struct uio auio;
1920 struct iovec aiov[MSG_MAXIOVLEN];
1921 register vnode_t *vp;
1922 int ioflag, rwflag;
1923 ssize_t cnt;
1924 int error = 0;
1925 int iovcnt = 0;
1926 short fflag;
1927
1928 vp = fp->f_vnode;
1929 fflag = fp->f_flag;
|