/*
 * dsock.c -- Darwin socket processing functions for libproc-based lsof
 */


/*
 * Portions Copyright 2005 Apple Computer, Inc.  All rights reserved.
 *
 * Copyright 2005 Purdue Research Foundation, West Lafayette, Indiana
 * 47907.  All rights reserved.
 *
 * Written by Allan Nathanson, Apple Computer, Inc., and Victor A.
 * Abell, Purdue University.
 *
 * This software is not subject to any license of the American Telephone
 * and Telegraph Company or the Regents of the University of California.
 *
 * Permission is granted to anyone to use this software for any purpose on
 * any computer system, and to alter it and redistribute it freely, subject
 * to the following restrictions:
 *
 * 1. Neither the authors, nor Apple Computer, Inc. nor Purdue University
 *    are responsible for any consequences of the use of this software.
 *
 * 2. The origin of this software must not be misrepresented, either
 *    by explicit claim or by omission.  Credit to the authors, Apple
 *    Computer, Inc. and Purdue University must appear in documentation
 *    and sources.
 *
 * 3. Altered versions must be plainly marked as such, and must not be
 *    misrepresented as being the original software.
 *
 * 4. This notice may not be removed or altered.
 */


#ifndef lint
static char copyright[] =
"@(#) Copyright 2005 Apple Computer, Inc. and Purdue Research Foundation.\nAll rights reserved.\n";
static char *rcsid = "$Id: dsock.c,v 1.6 2011/08/07 22:52:30 abe Exp $";
#endif


#include "lsof.h"


/*
 * IPv6_2_IPv4()  -- macro to define the address of an IPv4 address contained
 *                 in an IPv6 address
 */

#define	IPv6_2_IPv4(v6)	(((uint8_t *)((struct in6_addr *)v6)->s6_addr)+12)


/*
 * process_socket() -- process socket file
 */

static void
process_socket_common(si)
	struct socket_fdinfo *si;
{
	unsigned char *fa = (unsigned char *)NULL;
	int fam, fp, lp, unl;
	unsigned char *la = (unsigned char *)NULL;

/*
 * Enter basic socket values.
 */
	(void) snpf(Lf->type, sizeof(Lf->type), "sock");
	Lf->inp_ty = 2;
/*
 * Enter basic file information.
 */
	enter_file_info(&si->pfi);
/*
 * Enable size or offset display.
 */
	if (Fsize) {
	    if (Lf->access == 'r')
		Lf->sz = (SZOFFTYPE)si->psi.soi_rcv.sbi_cc;
	    else if (Lf->access == 'w')
		Lf->sz = (SZOFFTYPE)si->psi.soi_snd.sbi_cc;
	    else
		Lf->sz = (SZOFFTYPE)(si->psi.soi_rcv.sbi_cc
		       +	     si->psi.soi_snd.sbi_cc);
	    Lf->sz_def = 1;
	} else
	    Lf->off_def = 1;

#if	defined(HASTCPTPIQ)
/*
 * Enter send and receive queue sizes.
 */
	Lf->lts.rq = si->psi.soi_rcv.sbi_cc;
	Lf->lts.sq = si->psi.soi_snd.sbi_cc;
	Lf->lts.rqs = Lf->lts.sqs = (unsigned char)1;
#endif	/* defined(HASTCPTPIQ) */

#if	defined(HASSOOPT)
/*
 * Enter socket options.
 */
	Lf->lts.ltm = (unsigned int)(si->psi.soi_linger & 0xffff);
	Lf->lts.opt = (unsigned int)(si->psi.soi_options & 0xffff);
	Lf->lts.pqlen = (unsigned int)si->psi.soi_incqlen;
	Lf->lts.qlen = (unsigned int)si->psi.soi_qlen;
	Lf->lts.qlim = (unsigned int)si->psi.soi_qlimit;
	Lf->lts.rbsz = (unsigned long)si->psi.soi_rcv.sbi_mbmax;
	Lf->lts.sbsz = (unsigned long)si->psi.soi_snd.sbi_mbmax;
	Lf->lts.pqlens = Lf->lts.qlens = Lf->lts.qlims = Lf->lts.rbszs
		       = Lf->lts.sbszs = (unsigned char)1;
#endif	/* defined(HASSOOPT) */

#if	defined(HASSOSTATE)
/*
 * Enter socket state.
 */
	Lf->lts.ss = (unsigned int)si->psi.soi_state;
#endif	/* defined(HASSOSTATE) */

/*
 * Process socket by its associated domain family.
 */
	switch ((fam = si->psi.soi_family)) {
	case AF_INET:
	case AF_INET6:

	/*
	 * Process IPv[46] sockets.
	 */
	    (void) snpf(Lf->type, sizeof(Lf->type),
			(fam == AF_INET) ? "IPv4" : "IPv6");
	    if ((si->psi.soi_kind != SOCKINFO_IN) &&
		(si->psi.soi_kind != SOCKINFO_TCP))
	    {
		break;
	    }
	/*
	 * Process TCP state inclusions and exclusions, as required.
	 */
	    if ((si->psi.soi_kind == SOCKINFO_TCP) && (TcpStXn || TcpStIn)) {
		int tsnx = (int)si->psi.soi_proto.pri_tcp.tcpsi_state
			 + TcpStOff;

		if ((tsnx >= 0) && (tsnx < TcpNstates)) {
		    if (TcpStXn) {
			if (TcpStX[tsnx]) {
			    Lf->sf |= SELEXCLF;
			    return;
			}
		    }
		    if (TcpStIn) {
			if (TcpStI[tsnx])
			    TcpStI[tsnx] = 2;
			else {
			    Lf->sf |= SELEXCLF;
			    return;
			}
		    }
		}
	    }
	/*
	 * Process an Internet domain socket.
	 */
	    if (Fnet) {
		if (!FnetTy
		||  ((FnetTy == 4) && (fam == AF_INET))
		||  ((FnetTy == 6) && (fam == AF_INET6))
		)
		    Lf->sf |= SELNET;
	    }
	    printiproto(si->psi.soi_protocol);
	    if ((si->psi.soi_kind == SOCKINFO_TCP)
	    &&  si->psi.soi_proto.pri_tcp.tcpsi_tp)
	    {
		enter_dev_ch(print_kptr((KA_T)si->psi.soi_proto.pri_tcp.tcpsi_tp,
					(char *)NULL, 0));
	    } else
		enter_dev_ch(print_kptr((KA_T)si->psi.soi_pcb, (char *)NULL, 0));
	    if (fam == AF_INET) {

	    /*
	     * Enter IPv4 address information.
	     */
		if (si->psi.soi_kind == SOCKINFO_TCP) {

		/*
		 * Enter information for a TCP socket.
		 */
		    la = (unsigned char *)&si->psi.soi_proto.pri_tcp.tcpsi_ini.insi_laddr.ina_46.i46a_addr4;
		    lp = (int)ntohs(si->psi.soi_proto.pri_tcp.tcpsi_ini.insi_lport);
		    fa = (unsigned char *)&si->psi.soi_proto.pri_tcp.tcpsi_ini.insi_faddr.ina_46.i46a_addr4;
		    fp = (int)ntohs(si->psi.soi_proto.pri_tcp.tcpsi_ini.insi_fport);
		} else {

		/*
		 * Enter information for a non-TCP socket.
		 */
		    la = (unsigned char *)&si->psi.soi_proto.pri_in.insi_laddr.ina_46.i46a_addr4;
		    lp = (int)ntohs(si->psi.soi_proto.pri_in.insi_lport);
		    fa = (unsigned char *)&si->psi.soi_proto.pri_in.insi_faddr.ina_46.i46a_addr4;
		    fp = (int)ntohs(si->psi.soi_proto.pri_in.insi_fport);
		}
		if ((fa && (*fa == INADDR_ANY)) && !fp) {
		    fa = (unsigned char *)NULL;
		    fp = 0;
		}
	    } else {

	    /*
	     * Enter IPv6 address information
	     */
		int v4mapped = 0;

		if (si->psi.soi_kind == SOCKINFO_TCP)
		{

		/*
		 * Enter TCP socket information.
		 */
		    la = (unsigned char *)&si->psi.soi_proto.pri_tcp.tcpsi_ini.insi_laddr.ina_6;
		    lp = (int)ntohs(si->psi.soi_proto.pri_tcp.tcpsi_ini.insi_lport);
		    fa = (unsigned char *)&si->psi.soi_proto.pri_tcp.tcpsi_ini.insi_faddr.ina_6;
		    fp = (int)ntohs(si->psi.soi_proto.pri_tcp.tcpsi_ini.insi_fport);
		    if ((si->psi.soi_proto.pri_tcp.tcpsi_ini.insi_vflag & INI_IPV4) != 0)
			v4mapped = 1;
		} else {

		/*
		 * Enter non-TCP socket information.
		 */
		    la = (unsigned char *)&si->psi.soi_proto.pri_in.insi_laddr.ina_6;
		    lp = (int)ntohs(si->psi.soi_proto.pri_in.insi_lport);
		    fa = (unsigned char *)&si->psi.soi_proto.pri_in.insi_faddr.ina_6;
		    fp = (int)ntohs(si->psi.soi_proto.pri_in.insi_fport);
		    if ((si->psi.soi_proto.pri_in.insi_vflag & INI_IPV4) != 0)
			v4mapped = 1;
		}
		if (IN6_IS_ADDR_UNSPECIFIED((struct in6_addr *)fa) && !fp) {
		    fa = (unsigned char *)NULL;
		    fp = 0;
		}
		if (v4mapped) {

		/*
		 * Adjust IPv4 addresses mapped in IPv6 addresses.
		 */
		    fam = AF_INET;
		    if (la)
			la = (unsigned char *)IPv6_2_IPv4(la);
		    if (fa)
			fa = (unsigned char *)IPv6_2_IPv4(fa);
		}
	    }
	/*
	 * Enter local and remote addresses by address family.
	 */
	    if (fa || la)
		(void) ent_inaddr(la, lp, fa, fp, fam);
	    if (si->psi.soi_kind == SOCKINFO_TCP) {

	    /*
	     * Enter a TCP socket definition and its state.
	     */
		Lf->lts.type = 0;
		Lf->lts.state.i = (int)si->psi.soi_proto.pri_tcp.tcpsi_state;
	    /*
	     * Enter TCP options.
	     */

#if	defined(HASSOOPT)
		Lf->lts.kai = (unsigned int)si->psi.soi_proto.pri_tcp.tcpsi_timer[TCPT_KEEP];
#endif	/* defined(HASSOOPT) */

#if	defined(HASTCPOPT)
		Lf->lts.mss = (unsigned long)si->psi.soi_proto.pri_tcp.tcpsi_mss;
		Lf->lts.msss = (unsigned char)1;
		Lf->lts.topt = (unsigned int)si->psi.soi_proto.pri_tcp.tcpsi_flags;
#endif	/* defined(HASTCPOPT) */

	    }
	    break;
	case AF_UNIX:

	/*
	 * Process a UNIX domain socket.
	 */
	    (void) snpf(Lf->type, sizeof(Lf->type), "unix");
	    if (si->psi.soi_kind != SOCKINFO_UN)
		break;
	    if (Funix)
		Lf->sf |= SELUNX;
	    enter_dev_ch(print_kptr((KA_T)si->psi.soi_pcb, (char *)NULL, 0));
	/*
	 * Enter information on a UNIX domain socket that has no address bound
	 * to it, although it may be connected to another UNIX domain socket
	 * as a pipe.
	 */
	    if (si->psi.soi_proto.pri_un.unsi_addr.ua_sun.sun_family != AF_UNIX)
	    {
		if (si->psi.soi_proto.pri_un.unsi_addr.ua_sun.sun_family
		==  AF_UNSPEC)
		{
		    if (si->psi.soi_proto.pri_un.unsi_conn_pcb) {
			    (void) snpf(Namech, Namechl, "->%s",
				print_kptr((KA_T)si->psi.soi_proto.pri_un.unsi_conn_pcb, (char *)NULL, 0));
		    } else
			(void) snpf(Namech, Namechl, "->(none)");
		} else
		    (void) snpf(Namech, Namechl, "unknown sun_family (%d)",
			si->psi.soi_proto.pri_un.unsi_addr.ua_sun.sun_family);
		break;
	    }
	    if (si->psi.soi_proto.pri_un.unsi_addr.ua_sun.sun_path[0]) {
		unl = si->psi.soi_proto.pri_un.unsi_addr.ua_sun.sun_len - offsetof(struct sockaddr_un, sun_path);
		if ((unl < 0) || (unl >= sizeof(si->psi.soi_proto.pri_un.unsi_addr.ua_sun.sun_path)))
		    unl = sizeof(si->psi.soi_proto.pri_un.unsi_addr.ua_sun.sun_path) - 1;
		si->psi.soi_proto.pri_un.unsi_addr.ua_sun.sun_path[unl] = '\0';
		if (si->psi.soi_proto.pri_un.unsi_addr.ua_sun.sun_path[0]
		&&  Sfile
		&&  is_file_named(si->psi.soi_proto.pri_un.unsi_addr.ua_sun.sun_path, 0))
		    Lf->sf |= SELNM;
		if (si->psi.soi_proto.pri_un.unsi_addr.ua_sun.sun_path[0]
		&&  !Namech[0])
		    (void) snpf(Namech, Namechl, "%s", si->psi.soi_proto.pri_un.unsi_addr.ua_sun.sun_path);
	    } else
		(void) snpf(Namech, Namechl, "no address");
	    break;
	case AF_ROUTE:

	/*
	 * Process a ROUTE domain socket.
	 */
	    (void) snpf(Lf->type, sizeof(Lf->type), "rte");
	    if (!Fsize)
		Lf->off_def = 1;
	    break;
	case AF_NDRV:

	/*
	 * Process an NDRV domain socket.
	 */
	    (void) snpf(Lf->type, sizeof(Lf->type), "ndrv");
	    if (si->psi.soi_kind != SOCKINFO_NDRV)
		break;
	    enter_dev_ch(print_kptr((KA_T)si->psi.soi_pcb, (char *)NULL, 0));
	    si->psi.soi_proto.pri_ndrv.ndrvsi_if_name[sizeof(si->psi.soi_proto.pri_ndrv.ndrvsi_if_name) - 1] = '\0';
	    (void) snpf(Namech, Namechl, "-> %s%d",
			si->psi.soi_proto.pri_ndrv.ndrvsi_if_name,
			si->psi.soi_proto.pri_ndrv.ndrvsi_if_unit);
	    break;
	case pseudo_AF_KEY:

	/*
	 * Process an [internal] key-management function socket.
	 */
	    (void) snpf(Lf->type, sizeof(Lf->type), "key");
	    enter_dev_ch(print_kptr((KA_T)si->psi.soi_pcb, (char *)NULL, 0));
	    break;
	case AF_SYSTEM:

	/*
	 * Process a SYSTEM domain socket.
	 */
	    (void) snpf(Lf->type, sizeof(Lf->type), "systm");
	    if (si->psi.soi_kind != SOCKINFO_KERN_EVENT)
		break;
	    enter_dev_ch(print_kptr((KA_T)si->psi.soi_pcb, (char *)NULL, 0));
	    (void) snpf(Namech, Namechl, "[%x:%x:%x]",
			si->psi.soi_proto.pri_kern_event.kesi_vendor_code_filter,
			si->psi.soi_proto.pri_kern_event.kesi_class_filter,
			si->psi.soi_proto.pri_kern_event.kesi_subclass_filter);
	    break;
	case AF_PPP:

	/*
	 * Process a PPP domain socket.
	 */
	    (void) snpf(Lf->type, sizeof(Lf->type), "ppp");
	    enter_dev_ch(print_kptr((KA_T)si->psi.soi_pcb, (char *)NULL, 0));
	    break;
	default:
	    printunkaf(fam, 1);
	}
/*
 * If there are NAME column characters, enter them.
 */
	if (Namech[0])
	    enter_nm(Namech);
}


void
process_socket(pid, fd)
	int pid;			/* PID */
	int32_t fd;			/* FD */
{
	int nb;
	struct socket_fdinfo si;
/*
 * Get socket information.
 */
	nb = proc_pidfdinfo(pid, fd, PROC_PIDFDSOCKETINFO, &si, sizeof(si));
	if (nb <= 0) {
	    (void) err2nm("socket");
	    return;
	} else if (nb < sizeof(si)) {
	    (void) fprintf(stderr,
		"%s: PID %d, FD %d: proc_pidfdinfo(PROC_PIDFDSOCKETINFO);\n",
		Pn, pid, fd);
	    (void) fprintf(stderr,
		"      too few bytes; expected %ld, got %d\n",
		sizeof(si), nb);
	    Exit(1);
	}

	process_socket_common(&si);
}
