Exemple #1
0
int
main(int argc, char **argv)
{
	int ch, col, ktrlen, size;
	pid_t do_pid = -1;
	void *m;
	int trpoints = ALL_POINTS;
	char *cp;

	(void) setlocale(LC_CTYPE, "");

	while ((ch = getopt(argc,argv,"f:djlm:np:RTt:")) != -1)
		switch((char)ch) {
		case 'f':
			tracefile = optarg;
			break;
		case 'j':
			fixedformat = 1;
			break;
		case 'd':
			decimal = 1;
			break;
		case 'l':
			tail = 1;
			break;
		case 'm':
			maxdata = atoi(optarg);
			break;
		case 'n':
			fancy = 0;
			break;
		case 'p':
			do_pid = strtoul(optarg, &cp, 0);
			if (*cp != 0)
				errx(1,"invalid number %s", optarg);
			break;
		case 'R':
			timestamp = 2;	/* relative timestamp */
			break;
		case 'T':
			timestamp = 1;
			break;
		case 't':
			trpoints = getpoints(optarg);
			if (trpoints < 0)
				errx(1, "unknown trace point in %s", optarg);
			break;
		default:
			usage();
		}

	if (argc > optind)
		usage();

	m = (void *)malloc(size = 1025);
	if (m == NULL)
		errx(1, "%s", strerror(ENOMEM));
	if (!freopen(tracefile, "r", stdin))
		err(1, "%s", tracefile);
	while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) {
		if (trpoints & (1 << ktr_header.ktr_type) &&
		    (do_pid == -1 || ktr_header.ktr_pid == do_pid))
			col = dumpheader(&ktr_header);
		else
			col = -1;
		if ((ktrlen = ktr_header.ktr_len) < 0)
			errx(1, "bogus length 0x%x", ktrlen);
		if (ktrlen > size) {
			m = (void *)realloc(m, ktrlen+1);
			if (m == NULL)
				errx(1, "%s", strerror(ENOMEM));
			size = ktrlen;
		}
		if (ktrlen && fread_tail(m, ktrlen, 1) == 0)
			errx(1, "data too short");
		if ((trpoints & (1<<ktr_header.ktr_type)) == 0)
			continue;
		if (col == -1)
			continue;
		switch (ktr_header.ktr_type) {
		case KTR_SYSCALL:
			ktrsyscall((struct ktr_syscall *)m);
			break;
		case KTR_SYSRET:
			ktrsysret((struct ktr_sysret *)m);
			break;
		case KTR_NAMEI:
			ktrnamei(m, ktrlen);
			break;
		case KTR_GENIO:
			ktrgenio((struct ktr_genio *)m, ktrlen);
			break;
		case KTR_PSIG:
			ktrpsig((struct ktr_psig *)m);
			break;
		case KTR_CSW:
			ktrcsw((struct ktr_csw *)m);
			break;
		case KTR_USER:
			ktruser(ktrlen, m);
			break;
		}
		if (tail)
			(void)fflush(stdout);
	}
	exit(0);
}
Exemple #2
0
int
recvit(struct proc *p, int s, struct msghdr *mp, caddr_t namelenp,
    register_t *retsize)
{
	struct file *fp;
	struct uio auio;
	struct iovec *iov;
	int i;
	size_t len;
	int error;
	struct mbuf *from = NULL, *control = NULL;
#ifdef KTRACE
	struct iovec *ktriov = NULL;
#endif

	if ((error = getsock(p->p_fd, s, &fp)) != 0)
		return (error);
	auio.uio_iov = mp->msg_iov;
	auio.uio_iovcnt = mp->msg_iovlen;
	auio.uio_segflg = UIO_USERSPACE;
	auio.uio_rw = UIO_READ;
	auio.uio_procp = p;
	auio.uio_offset = 0;			/* XXX */
	auio.uio_resid = 0;
	iov = mp->msg_iov;
	for (i = 0; i < mp->msg_iovlen; i++, iov++) {
		/* Don't allow sum > SSIZE_MAX */
		if (iov->iov_len > SSIZE_MAX ||
		    (auio.uio_resid += iov->iov_len) > SSIZE_MAX) {
			error = EINVAL;
			goto out;
		}
	}
#ifdef KTRACE
	if (KTRPOINT(p, KTR_GENIO)) {
		int iovlen = auio.uio_iovcnt * sizeof (struct iovec);

		ktriov = malloc(iovlen, M_TEMP, M_WAITOK);
		bcopy(auio.uio_iov, ktriov, iovlen);
	}
#endif
	len = auio.uio_resid;
	error = soreceive(fp->f_data, &from, &auio, NULL,
			  mp->msg_control ? &control : NULL,
			  &mp->msg_flags,
			  mp->msg_control ? mp->msg_controllen : 0);
	if (error) {
		if (auio.uio_resid != len && (error == ERESTART ||
		    error == EINTR || error == EWOULDBLOCK))
			error = 0;
	}
#ifdef KTRACE
	if (ktriov != NULL) {
		if (error == 0)
			ktrgenio(p, s, UIO_READ, ktriov, len - auio.uio_resid);
		free(ktriov, M_TEMP);
	}
#endif
	if (error)
		goto out;
	*retsize = len - auio.uio_resid;
	if (mp->msg_name) {
		socklen_t alen;

		if (from == NULL)
			alen = 0;
		else {
			alen = from->m_len;
			error = copyout(mtod(from, caddr_t), mp->msg_name,
			    MIN(alen, mp->msg_namelen));
			if (error)
				goto out;
#ifdef KTRACE
			if (KTRPOINT(p, KTR_STRUCT))
				ktrsockaddr(p, mtod(from, caddr_t), alen);
#endif
		}
		mp->msg_namelen = alen;
		if (namelenp &&
		    (error = copyout(&alen, namelenp, sizeof(alen)))) {
			goto out;
		}
	}
	if (mp->msg_control) {
		len = mp->msg_controllen;
		if (len <= 0 || control == NULL)
			len = 0;
		else {
			struct mbuf *m = control;
			caddr_t p = mp->msg_control;

			do {
				i = m->m_len;
				if (len < i) {
					mp->msg_flags |= MSG_CTRUNC;
					i = len;
				}
				error = copyout(mtod(m, caddr_t), p, i);
				if (m->m_next)
					i = ALIGN(i);
				p += i;
				len -= i;
				if (error != 0 || len <= 0)
					break;
			} while ((m = m->m_next) != NULL);
			len = p - (caddr_t)mp->msg_control;
		}
		mp->msg_controllen = len;
	}
	if (!error) {
		fp->f_rxfer++;
		fp->f_rbytes += *retsize;
	}
out:
	FRELE(fp, p);
	if (from)
		m_freem(from);
	if (control)
		m_freem(control);
	return (error);
}
/*
 * main ioctl syscall.
 *
 * ok, here we are in the biggy.  we have to do fix ups depending
 * on the ioctl command before and afterwards.
 */
int
netbsd32_ioctl(struct lwp *l, const struct netbsd32_ioctl_args *uap, register_t *retval)
{
	/* {
		syscallarg(int) fd;
		syscallarg(netbsd32_u_long) com;
		syscallarg(netbsd32_voidp) data;
	} */
	struct proc *p = l->l_proc;
	struct file *fp;
	struct filedesc *fdp;
	u_long com;
	int error = 0;
	u_int size, size32;
	void *data, *memp = NULL;
	void *data32, *memp32 = NULL;
	unsigned fd;
	fdfile_t *ff;
	int tmp;
#define STK_PARAMS	128
	u_long stkbuf[STK_PARAMS/sizeof(u_long)];
	u_long stkbuf32[STK_PARAMS/sizeof(u_long)];

	/*
	 * we need to translate some commands (_IOW) before calling sys_ioctl,
	 * some after (_IOR), and some both (_IOWR).
	 */
#if 0
	{
char *dirs[8] = { "NONE!", "VOID", "OUT", "VOID|OUT!", "IN", "VOID|IN!",
		"INOUT", "VOID|IN|OUT!" };

printf("netbsd32_ioctl(%d, %x, %x): %s group %c base %d len %d\n",
       SCARG(uap, fd), SCARG(uap, com), SCARG(uap, data),
       dirs[((SCARG(uap, com) & IOC_DIRMASK)>>29)],
       IOCGROUP(SCARG(uap, com)), IOCBASECMD(SCARG(uap, com)),
       IOCPARM_LEN(SCARG(uap, com)));
	}
#endif

	fdp = p->p_fd;
	fd = SCARG(uap, fd);
	if ((fp = fd_getfile(fd)) == NULL)
		return (EBADF);
	if ((fp->f_flag & (FREAD | FWRITE)) == 0) {
		error = EBADF;
		goto out;
	}

	ff = fdp->fd_ofiles[SCARG(uap, fd)];
	switch (com = SCARG(uap, com)) {
	case FIOCLEX:
		ff->ff_exclose = true;
		fdp->fd_exclose = true;
		goto out;

	case FIONCLEX:
		ff->ff_exclose = false;
		goto out;
	}

	/*
	 * Interpret high order word to find amount of data to be
	 * copied to/from the user's address space.
	 */
	size = 0;
	size32 = IOCPARM_LEN(com);
	if (size32 > IOCPARM_MAX) {
		error = ENOTTY;
		goto out;
	}
	if (size32 > sizeof(stkbuf)) {
		memp32 = kmem_alloc((size_t)size32, KM_SLEEP);
		data32 = memp32;
	} else
		data32 = (void *)stkbuf32;
	if (com&IOC_IN) {
		if (size32) {
			error = copyin(SCARG_P32(uap, data), data32, size32);
			if (error) {
				if (memp32)
					kmem_free(memp32, (size_t)size32);
				goto out;
			}
			ktrgenio(fd, UIO_WRITE, SCARG_P32(uap, data),
			    size32, 0);
		} else
			*(void **)data32 = SCARG_P32(uap, data);
	} else if ((com&IOC_OUT) && size32)
		/*
		 * Zero the buffer so the user always
		 * gets back something deterministic.
		 */
		memset(data32, 0, size32);
	else if (com&IOC_VOID)
		*(void **)data32 = SCARG_P32(uap, data);

	/*
	 * convert various structures, pointers, and other objects that
	 * change size from 32 bit -> 64 bit, for all ioctl commands.
	 */
	switch (SCARG(uap, com)) {
	case FIONBIO:
		mutex_enter(&fp->f_lock);
		if ((tmp = *(int *)data32) != 0)
			fp->f_flag |= FNONBLOCK;
		else
			fp->f_flag &= ~FNONBLOCK;
		mutex_exit(&fp->f_lock);
		error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (void *)&tmp);
		break;

	case FIOASYNC:
		mutex_enter(&fp->f_lock);
		if ((tmp = *(int *)data32) != 0)
			fp->f_flag |= FASYNC;
		else
			fp->f_flag &= ~FASYNC;
		mutex_exit(&fp->f_lock);
		error = (*fp->f_ops->fo_ioctl)(fp, FIOASYNC, (void *)&tmp);
		break;

	case DIOCGPART32:
		IOCTL_STRUCT_CONV_TO(DIOCGPART, partinfo);
#if 0	/* not implemented by anything */
	case DIOCRFORMAT32:
		IOCTL_STRUCT_CONV_TO(DIOCRFORMAT, format_op);
	case DIOCWFORMAT32:
		IOCTL_STRUCT_CONV_TO(DIOCWFORMAT, format_op);
#endif

/*
 * only a few ifreq syscalls need conversion and those are
 * all driver specific... XXX
 */
#if 0
	case SIOCGADDRROM3232:
		IOCTL_STRUCT_CONV_TO(SIOCGADDRROM32, ifreq);
	case SIOCGCHIPID32:
		IOCTL_STRUCT_CONV_TO(SIOCGCHIPID, ifreq);
	case SIOCSIFADDR32:
		IOCTL_STRUCT_CONV_TO(SIOCSIFADDR, ifreq);
	case OSIOCGIFADDR32:
		IOCTL_STRUCT_CONV_TO(OSIOCGIFADDR, ifreq);
	case SIOCGIFADDR32:
		IOCTL_STRUCT_CONV_TO(SIOCGIFADDR, ifreq);
	case SIOCSIFDSTADDR32:
		IOCTL_STRUCT_CONV_TO(SIOCSIFDSTADDR, ifreq);
	case OSIOCGIFDSTADDR32:
		IOCTL_STRUCT_CONV_TO(OSIOCGIFDSTADDR, ifreq);
	case SIOCGIFDSTADDR32:
		IOCTL_STRUCT_CONV_TO(SIOCGIFDSTADDR, ifreq);
	case OSIOCGIFBRDADDR32:
		IOCTL_STRUCT_CONV_TO(OSIOCGIFBRDADDR, ifreq);
	case SIOCGIFBRDADDR32:
		IOCTL_STRUCT_CONV_TO(SIOCGIFBRDADDR, ifreq);
	case SIOCSIFBRDADDR32:
		IOCTL_STRUCT_CONV_TO(SIOCSIFBRDADDR, ifreq);
	case OSIOCGIFNETMASK32:
		IOCTL_STRUCT_CONV_TO(OSIOCGIFNETMASK, ifreq);
	case SIOCGIFNETMASK32:
		IOCTL_STRUCT_CONV_TO(SIOCGIFNETMASK, ifreq);
	case SIOCSIFNETMASK32:
		IOCTL_STRUCT_CONV_TO(SIOCSIFNETMASK, ifreq);
	case SIOCGIFMETRIC32:
		IOCTL_STRUCT_CONV_TO(SIOCGIFMETRIC, ifreq);
	case SIOCSIFMETRIC32:
		IOCTL_STRUCT_CONV_TO(SIOCSIFMETRIC, ifreq);
	case SIOCDIFADDR32:
		IOCTL_STRUCT_CONV_TO(SIOCDIFADDR, ifreq);
	case SIOCADDMULTI32:
		IOCTL_STRUCT_CONV_TO(SIOCADDMULTI, ifreq);
	case SIOCDELMULTI32:
		IOCTL_STRUCT_CONV_TO(SIOCDELMULTI, ifreq);
	case SIOCSIFMEDIA32:
		IOCTL_STRUCT_CONV_TO(SIOCSIFMEDIA, ifreq);
	case SIOCSIFMTU32:
		IOCTL_STRUCT_CONV_TO(SIOCSIFMTU, ifreq);
	case SIOCGIFMTU32:
		IOCTL_STRUCT_CONV_TO(SIOCGIFMTU, ifreq);
	case BIOCGETIF32:
		IOCTL_STRUCT_CONV_TO(BIOCGETIF, ifreq);
	case BIOCSETIF32:
		IOCTL_STRUCT_CONV_TO(BIOCSETIF, ifreq);
	case SIOCPHASE132:
		IOCTL_STRUCT_CONV_TO(SIOCPHASE1, ifreq);
	case SIOCPHASE232:
		IOCTL_STRUCT_CONV_TO(SIOCPHASE2, ifreq);
#endif

	case OOSIOCGIFCONF32:
		IOCTL_STRUCT_CONV_TO(OOSIOCGIFCONF, ifconf);
	case OSIOCGIFCONF32:
		IOCTL_STRUCT_CONV_TO(OSIOCGIFCONF, ifconf);
	case SIOCGIFCONF32:
		IOCTL_STRUCT_CONV_TO(SIOCGIFCONF, ifconf);

	case SIOCGIFFLAGS32:
		IOCTL_STRUCT_CONV_TO(SIOCGIFFLAGS, ifreq);
	case SIOCSIFFLAGS32:
		IOCTL_STRUCT_CONV_TO(SIOCSIFFLAGS, ifreq);

	case SIOCGIFMEDIA32:
		IOCTL_STRUCT_CONV_TO(SIOCGIFMEDIA, ifmediareq);

	case SIOCSDRVSPEC32:
		IOCTL_STRUCT_CONV_TO(SIOCSDRVSPEC, ifdrv);

	case SIOCGETVIFCNT32:
		IOCTL_STRUCT_CONV_TO(SIOCGETVIFCNT, sioc_vif_req);

	case SIOCGETSGCNT32:
		IOCTL_STRUCT_CONV_TO(SIOCGETSGCNT, sioc_sg_req);

	default:
#ifdef NETBSD32_MD_IOCTL
		error = netbsd32_md_ioctl(fp, com, data32, l);
#else
		error = (*fp->f_ops->fo_ioctl)(fp, com, data32);
#endif
		break;
	}

	if (error == EPASSTHROUGH)
		error = ENOTTY;

	/*
	 * Copy any data to user, size was
	 * already set and checked above.
	 */
	if (error == 0 && (com&IOC_OUT) && size32) {
		error = copyout(data32, SCARG_P32(uap, data), size32);
		ktrgenio(fd, UIO_READ, SCARG_P32(uap, data),
		    size32, error);
	}

	/* if we malloced data, free it here */
	if (memp32)
		kmem_free(memp32, (size_t)size32);
	if (memp)
		kmem_free(memp, (size_t)size);
 out:
	fd_putfile(fd);
	return (error);
}
Exemple #4
0
int
sendit(struct proc *p, int s, struct msghdr *mp, int flags, register_t *retsize)
{
	struct file *fp;
	struct uio auio;
	struct iovec *iov;
	int i;
	struct mbuf *to, *control;
	size_t len;
	int error;
#ifdef KTRACE
	struct iovec *ktriov = NULL;
#endif

	to = NULL;

	if ((error = getsock(p->p_fd, s, &fp)) != 0)
		return (error);
	auio.uio_iov = mp->msg_iov;
	auio.uio_iovcnt = mp->msg_iovlen;
	auio.uio_segflg = UIO_USERSPACE;
	auio.uio_rw = UIO_WRITE;
	auio.uio_procp = p;
	auio.uio_offset = 0;			/* XXX */
	auio.uio_resid = 0;
	iov = mp->msg_iov;
	for (i = 0; i < mp->msg_iovlen; i++, iov++) {
		/* Don't allow sum > SSIZE_MAX */
		if (iov->iov_len > SSIZE_MAX ||
		    (auio.uio_resid += iov->iov_len) > SSIZE_MAX) {
			error = EINVAL;
			goto bad;
		}
	}
	if (mp->msg_name) {
		error = sockargs(&to, mp->msg_name, mp->msg_namelen,
		    MT_SONAME);
		if (error)
			goto bad;
#ifdef KTRACE
		if (KTRPOINT(p, KTR_STRUCT))
		 	ktrsockaddr(p, mtod(to, caddr_t), mp->msg_namelen);
#endif
	}
	if (mp->msg_control) {
		if (mp->msg_controllen < CMSG_ALIGN(sizeof(struct cmsghdr))) {
			error = EINVAL;
			goto bad;
		}
		error = sockargs(&control, mp->msg_control,
		    mp->msg_controllen, MT_CONTROL);
		if (error)
			goto bad;
	} else
		control = 0;
#ifdef KTRACE
	if (KTRPOINT(p, KTR_GENIO)) {
		int iovlen = auio.uio_iovcnt * sizeof (struct iovec);

		ktriov = malloc(iovlen, M_TEMP, M_WAITOK);
		bcopy(auio.uio_iov, ktriov, iovlen);
	}
#endif
	len = auio.uio_resid;
	error = sosend(fp->f_data, to, &auio, NULL, control, flags);
	if (error) {
		if (auio.uio_resid != len && (error == ERESTART ||
		    error == EINTR || error == EWOULDBLOCK))
			error = 0;
		if (error == EPIPE && (flags & MSG_NOSIGNAL) == 0)
			ptsignal(p, SIGPIPE, STHREAD);
	}
	if (error == 0) {
		*retsize = len - auio.uio_resid;
		fp->f_wxfer++;
		fp->f_wbytes += *retsize;
	}
#ifdef KTRACE
	if (ktriov != NULL) {
		if (error == 0)
			ktrgenio(p, s, UIO_WRITE, ktriov, *retsize);
		free(ktriov, M_TEMP);
	}
#endif
bad:
	FRELE(fp, p);
	if (to)
		m_freem(to);
	return (error);
}