home *** CD-ROM | disk | FTP | other *** search
- /* History:
- 5/3/91 DJB various modifications
- 5/1/91 DJB baseline public domain
- */
-
- /*
-
- int getsocket(f,sbuf) struct socket *f; struct socketbuf *sbuf; looks up
- socket f (in kernel memory) and places its vital statistics into sbuf.
- sbuf->socktype is the general socket type, such as SOCK_STREAM.
- sbuf->strsockt is the name of the socket type, or 0 if the type is
- unknown. sbuf->flag{accept,reuse,head} are the accept, reuse, and head
- flags on the socket respectively. sbuf->family is the socket's address
- family, such as AF_INET; sbuf->famname is the name of the family, or 0
- if the family is unknown. sbuf->famname may be truncated to 30
- characters.
-
- sbuf->fsw is a family switch to control sbuf->fu: FSW_INET for AF_INET,
- FSW_UNIX for AF_UNIX, and FSW_UNK for other types.
-
- If sbuf->fsw is FSW_INET: sbuf->fu.inet has several members. proto is
- the Internet protocol, such as IPPROTO_TCP. strpro is the name for
- proto, or 0 if it is unknown. r0, r1, r2, r3 are the bytes (from network
- down to host) of the IP address of the remote host; rp is the remote
- port, for protocols where that is meaningful. l0, l1, l2, l3 and lp form
- the local address.
-
- If sbuf->fsw is FSW_UNIX: sbuf->fu.un has several members. node is the
- address of the filesystem node associated with the socket, if any. conn
- is the address of the connected node, if any. path is the bound pathname
- of the socket, if applicable; it may be either a character array or a
- pointer in future releases of this library. unpcb is the address of the
- socket's protocol control block.
-
- getsocket() returns 0 upon success, -1 upon error.
-
- */
-
- #include <stdio.h>
- #include "structinpcb.h"
- #include "structmbuf.h"
- #include "structprotosw.h"
- #include "structsocket.h"
- #include "structunpcb.h"
- #include "structxnode.h"
- #include "printfamily.h"
- #include "printprotoinet.h"
- #include "printsocktype.h"
- #include "kmem.h"
- #include <sys/un.h>
- #include "getsocket.h"
- #include "confdomain.h"
-
- getsocket(f,sbuf)
- struct socket *f;
- struct socketbuf *sbuf;
- {
- struct socket s;
- struct protosw psw;
- #ifdef DOMAIN
- struct domain dom;
- #endif
- int family;
-
- kmemcpy(&s,f,sizeof(s));
-
- /* XXX: state, follow head, error, pgrp */
- kmemcpy(&psw,s.so_proto,sizeof(psw));
- #ifdef DOMAIN
- kmemcpy(&dom,psw.pr_domain,sizeof(dom));
- family = dom.dom_family;
- #else
- family = psw.pr_family;
- #endif
-
- sbuf->socktype = s.so_type;
- sbuf->strsockt = printsocktype(s.so_type);
- sbuf->flagaccept = !!(s.so_options & SO_ACCEPTCONN);
- sbuf->flagreuse = !!(s.so_options & SO_REUSEADDR);
- sbuf->flaghead = !!(s.so_head);
- /* N.B. psw.pr_type always equals s.so_type */
- sbuf->family = family;
- #ifdef DOMAIN
- if (dom.dom_name && (family >= 0) && (family < 50))
- {
- char domname[50][30]; /* XXX: so I'm scum. so sue me. */
- kmemcpy(domname[family],dom.dom_name,sizeof(domname[family]));
- domname[family][29] = 0;
- sbuf->famname = domname[family];
- }
- else
- #endif
- sbuf->famname = printfamily(family);
- sbuf->fsw = FSW_UNK;
-
- if (family == AF_INET)
- {
- struct inpcb inp;
- unsigned char *a;
-
- sbuf->fsw = FSW_INET;
- sbuf->fu.inet.proto = psw.pr_protocol;
- sbuf->fu.inet.strpro = printprotoinet(psw.pr_protocol);
-
- /*XXX: do port lookups? */
- /*XXX: do host lookups? */
- kmemcpy(&inp,s.so_pcb,sizeof(inp));
- a = (unsigned char *) &inp.inp_faddr;
- sbuf->fu.inet.r0 = a[0]; sbuf->fu.inet.r1 = a[1];
- sbuf->fu.inet.r2 = a[2]; sbuf->fu.inet.r3 = a[3];
- a = (unsigned char *) &inp.inp_fport;
- sbuf->fu.inet.rp = a[0] * 256 + a[1];
- a = (unsigned char *) &inp.inp_laddr;
- sbuf->fu.inet.l0 = a[0]; sbuf->fu.inet.l1 = a[1];
- sbuf->fu.inet.l2 = a[2]; sbuf->fu.inet.l3 = a[3];
- a = (unsigned char *) &inp.inp_lport;
- sbuf->fu.inet.lp = a[0] * 256 + a[1];
- }
- else if (family == AF_UNIX)
- {
- struct unpcb unp;
-
- sbuf->fsw = FSW_UNIX;
- kmemcpy(&unp,s.so_pcb,sizeof(unp));
- sbuf->fu.un.unpcb = (char *) s.so_pcb;
- sbuf->fu.un.node = (char *) unp.unp_Xnode;
- sbuf->fu.un.conn = (char *) unp.unp_conn;
- sbuf->fu.un.path[0] = 0;
- if (unp.unp_addr)
- {
- struct sockaddr_un *sa;
- struct mbuf mb;
- kmemcpy((char *) &mb,(char *) unp.unp_addr,sizeof(mb));
- sa = (struct sockaddr_un *) (((char *) &mb) + mb.m_off);
- /* XXX: check that length is less than 108 */
- sprintf(sbuf->fu.un.path,
- " %.*s",mb.m_len - sizeof(sa->sun_family),sa->sun_path); /*XXX*/
- }
- }
- else
- ; /* XXX: other s.so_pcb's? */
- return 0;
- }
-