Print this page
XXXX adding PID information to netstat output


  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                 }


1726 {
1727         kstat_t *ksp = (kstat_t *)arg;
1728 
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                 /* add curproc to the pid list associated with that file */
 759                 if (fp->f_vnode != NULL)
 760                         (void) VOP_IOCTL(fp->f_vnode, F_FORKED,
 761                             (intptr_t)curproc, FKIOCTL, kcred, NULL, NULL);
 762 
 763                 if (AU_AUDITING())
 764                         audit_fdrecv(fd, fp);
 765                 dprint(1, ("fdbuf_extract: [%d] = %d, %p refcnt %d\n",
 766                     i, fd, (void *)fp, fp->f_count));
 767         }
 768         return (0);
 769 
 770 cleanup:
 771         /*
 772          * Undo whatever partial work the loop above has done.
 773          */
 774         {
 775                 int j;
 776 
 777                 rp = (int *)rights;
 778                 for (j = 0; j < i; j++) {
 779                         dprint(0,
 780                             ("fdbuf_extract: cleanup[%d] = %d\n", j, *rp));
 781                         (void) closeandsetf(*rp++, NULL);
 782                 }


1720 {
1721         kstat_t *ksp = (kstat_t *)arg;
1722 
1723         if (ksp != NULL) {
1724                 ASSERT(zoneid == (zoneid_t)(uintptr_t)ksp->ks_private);
1725                 kstat_delete(ksp);
1726         }
1727 }
1728 
1729 /*
1730  * Zones:
1731  * Note that nactive is going to be different for each zone.
1732  * This means we require kstat to call sockfs_update and then sockfs_snapshot
1733  * for the same zone, or sockfs_snapshot will be taken into the wrong size
1734  * buffer. This is safe, but if the buffer is too small, user will not be
1735  * given details of all sockets. However, as this kstat has a ks_lock, kstat
1736  * driver will keep it locked between the update and the snapshot, so no
1737  * other process (zone) can currently get inbetween resulting in a wrong size
1738  * buffer allocation.
1739  */
1740 
1741 static int
1742 sockfs_update(kstat_t *ksp, int rw)
1743 {
1744         uint_t  n, nactive = 0;         /* # of active AF_UNIX sockets  */
1745         uint_t  tsze, sze;
1746         struct sonode   *so;            /* current sonode on socklist   */
1747         zoneid_t        myzoneid = (zoneid_t)(uintptr_t)ksp->ks_private;
1748 
1749         tsze = sze = 0;
1750 
1751         ASSERT((zoneid_t)(uintptr_t)ksp->ks_private == getzoneid());
1752 
1753         if (rw == KSTAT_WRITE) {        /* bounce all writes            */
1754                 return (EACCES);
1755         }
1756 
1757         for (so = socklist.sl_list; so != NULL; so = SOTOTPI(so)->sti_next_so) {
1758                 if (so->so_count != 0 && so->so_zoneid == myzoneid) {
1759 
1760                         nactive++;
1761 
1762                         mutex_enter(&so->so_pid_list_lock);
1763                         n = list_size(&so->so_pid_list);
1764                         mutex_exit(&so->so_pid_list_lock);
1765 
1766                         sze = sizeof (struct sockinfo);
1767                         sze += (n > 1)?((n - 1) * sizeof (conn_pid_node_t)):0;
1768                         tsze += sze;
1769 
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         conn_pid_node_list_hdr_t        *cph;
1790 
1791         ASSERT((zoneid_t)(uintptr_t)ksp->ks_private == getzoneid());
1792 
1793         ksp->ks_snaptime = gethrtime();
1794 
1795         if (rw == KSTAT_WRITE) {        /* bounce all writes            */
1796                 return (EACCES);
1797         }
1798 
1799         /*
1800          * for each sonode on the socklist, we massage the important
1801          * info into buf, in k_sockinfo format.
1802          */
1803         psi = (struct sockinfo *)buf;
1804         ns = 0;
1805         for (so = socklist.sl_list; so != NULL; so = SOTOTPI(so)->sti_next_so) {
1806                 /* only stuff active sonodes and the same zone:         */
1807                 if (so->so_count == 0 || so->so_zoneid != myzoneid) {
1808                         continue;
1809                 }
1810 
1811                 /* get the pidnode list associated with this sonode */
1812                 cph = so_get_sock_pid_list((sock_upper_handle_t)so);
1813 
1814                 /* calculate the size of this sockinfo structure */
1815                 sze = sizeof (struct sockinfo);
1816                 sze += (cph->cph_pn_cnt > 1)?
1817                         ((cph->cph_pn_cnt - 1) * sizeof (conn_pid_node_t)):0;
1818 
1819                 /*
1820                  * If the sonode was activated between the update and the
1821                  * snapshot, we're done - as this is only a snapshot. We need
1822                  * to make sure that we have space for this sockinfo.
1823                  */
1824                 if (((caddr_t)(psi) + sze) >
1825                         ((caddr_t)buf + ksp->ks_data_size)) {
1826                         break;
1827                 }
1828 
1829                 sti = SOTOTPI(so);
1830                 /* copy important info into buf:                        */
1831                 psi->si_size = sze;
1832                 psi->si_family = so->so_family;
1833                 psi->si_type = so->so_type;
1834                 psi->si_flag = so->so_flag;
1835                 psi->si_state = so->so_state;
1836                 psi->si_serv_type = sti->sti_serv_type;
1837                 psi->si_ux_laddr_sou_magic =
1838                     sti->sti_ux_laddr.soua_magic;
1839                 psi->si_ux_faddr_sou_magic =
1840                     sti->sti_ux_faddr.soua_magic;
1841                 psi->si_laddr_soa_len = sti->sti_laddr.soa_len;
1842                 psi->si_faddr_soa_len = sti->sti_faddr.soa_len;
1843                 psi->si_szoneid = so->so_zoneid;
1844                 psi->si_faddr_noxlate = sti->sti_faddr_noxlate;
1845 
1846 
1847                 mutex_enter(&so->so_lock);
1848 
1849                 if (sti->sti_laddr_sa != NULL) {
1850                         ASSERT(sti->sti_laddr_sa->sa_data != NULL);
1851                         sn_len = sti->sti_laddr_len;
1852                         ASSERT(sn_len <= sizeof (short) +
1853                             sizeof (psi->si_laddr_sun_path));
1854 
1855                         psi->si_laddr_family =
1856                             sti->sti_laddr_sa->sa_family;
1857                         if (sn_len != 0) {
1858                                 /* AF_UNIX socket names are NULL terminated */
1859                                 (void) strncpy(psi->si_laddr_sun_path,
1860                                     sti->sti_laddr_sa->sa_data,
1861                                     sizeof (psi->si_laddr_sun_path));
1862                                 sn_len = strlen(psi->si_laddr_sun_path);
1863                         }
1864                         psi->si_laddr_sun_path[sn_len] = 0;
1865                 }
1866 
1867                 if (sti->sti_faddr_sa != NULL) {
1868                         ASSERT(sti->sti_faddr_sa->sa_data != NULL);
1869                         sn_len = sti->sti_faddr_len;
1870                         ASSERT(sn_len <= sizeof (short) +
1871                             sizeof (psi->si_faddr_sun_path));
1872 
1873                         psi->si_faddr_family =
1874                             sti->sti_faddr_sa->sa_family;
1875                         if (sn_len != 0) {
1876                                 (void) strncpy(psi->si_faddr_sun_path,
1877                                     sti->sti_faddr_sa->sa_data,
1878                                     sizeof (psi->si_faddr_sun_path));
1879                                 sn_len = strlen(psi->si_faddr_sun_path);
1880                         }
1881                         psi->si_faddr_sun_path[sn_len] = 0;
1882                 }
1883 
1884                 mutex_exit(&so->so_lock);
1885 
1886                 (void) sprintf(psi->si_son_straddr, "%p", (void *)so);
1887                 (void) sprintf(psi->si_lvn_straddr, "%p",
1888                     (void *)sti->sti_ux_laddr.soua_vp);
1889                 (void) sprintf(psi->si_fvn_straddr, "%p",
1890                     (void *)sti->sti_ux_faddr.soua_vp);
1891 
1892                 if ((psi->si_pn_cnt = cph->cph_pn_cnt) > 0)
1893                         (void) memcpy(psi->si_pns, cph->cph_cpns,
1894                                 psi->si_pn_cnt * sizeof (conn_pid_node_t));
1895 
1896                 kmem_free(cph, cph->cph_tot_size);
1897 
1898                 psi = (struct sockinfo *)((char *)psi + psi->si_size);
1899                 ns++;

1900         }
1901 
1902         ksp->ks_ndata = ns;
1903         return (0);
1904 }
1905 
1906 ssize_t
1907 soreadfile(file_t *fp, uchar_t *buf, u_offset_t fileoff, int *err, size_t size)
1908 {
1909         struct uio auio;
1910         struct iovec aiov[MSG_MAXIOVLEN];
1911         register vnode_t *vp;
1912         int ioflag, rwflag;
1913         ssize_t cnt;
1914         int error = 0;
1915         int iovcnt = 0;
1916         short fflag;
1917 
1918         vp = fp->f_vnode;
1919         fflag = fp->f_flag;