+ so = fp->f_socket;
+ m = m_getclr(M_WAIT);
+ u.u_error =
+ (*so->so_proto->pr_usrreq)(so, PRU_SOCKADDR, 0, m, 0);
+ if (u.u_error)
+ goto bad;
+ if (copyout(mtod(m, caddr_t), (caddr_t)uap->asa, sizeof (struct sockaddr)))
+ u.u_error = EFAULT;
+bad:
+ m_freem(m);
+}
+
+sockname(aname, name, namelen)
+ struct mbuf **aname;
+ caddr_t name;
+ int namelen;
+{
+ register struct mbuf *m;
+
+ if (namelen > MLEN)
+ return (EINVAL);
+ m = m_get(M_WAIT);
+ m->m_len = namelen;
+ if (copyin(name, mtod(m, caddr_t), (u_int)namelen)) {
+ (void) m_free(m);
+ return (EFAULT);
+ }
+ *aname = m;
+ return (0);
+}
+
+sockopt(so, opt)
+ register struct socketopt *so;
+ caddr_t opt;
+{
+ register struct mbuf *m;
+
+ if (opt == 0) {
+ so->so_optlen = 0;
+ so->so_optdata = 0;
+ return (0);
+ }
+ if (copyin((caddr_t)opt, (caddr_t)so, sizeof (struct socketopt)))
+ return (EFAULT);
+ if (so->so_optlen < 0 || so->so_optlen > MLEN)
+ return (EINVAL);
+ m = m_get(M_WAIT);
+ m->m_len = so->so_optlen;
+ if (copyin(so->so_optdata, mtod(m, caddr_t), (u_int)m->m_len)) {
+ (void) m_free(m);
+ return (EFAULT);
+ }
+ so->so_optdata = mtod(m, caddr_t);
+ return (0);
+}