Exemple #1
0
int get_user4(	in_port_t lport,
				in_port_t fport,
				struct sockaddr_storage *laddr,
				struct sockaddr_storage *faddr)
{
	struct socket *sockp, sock;
	struct inpcbhead tcb;
	int ret;

	ret = getbuf(kinfo->nl[N_TCB].n_value, &tcb, sizeof(tcb));
	if (ret == -1)
		return (-1);

	sockp = getlist4(&tcb, lport, fport,
				&SIN4(laddr)->sin_addr, &SIN4(faddr)->sin_addr);

	if (sockp == NULL)
		return (-1);

	ret = getbuf((u_long) sockp, &sock, sizeof(sock));
	if (ret == -1)
		return (-1);

	return (sock.so_uid);
}
Exemple #2
0
/*
 * Converts the internet address plus port string in 'St'
 * into their network byte order representations.
 *
 * returns: - 0 -> conversion failed
 *          - 1 -> only address part returned (inaddrPt)
 *          - 2 -> address and port returned
 *
 */
static void getSockAdr(struct sockaddr *SaPt, socklen_t * SaLenPt, char *AddrSt, char *PortSt)
{
	struct sockaddr_in *Sin4;
	struct sockaddr_in6 *Sin6;

	if (strchr(AddrSt, ':') == NULL) {
		Sin4 = SIN4(SaPt);
		memset(Sin4, 0, sizeof(*Sin4));

		Sin4->sin_family = AF_INET;
		Sin4->sin_port = htons(atoi(PortSt));

		if (inet_pton(AF_INET, AddrSt, &Sin4->sin_addr) <= 0) {
			smclog(LOG_ERR, "inet_pton failed for address %s: %m", AddrSt);
			exit(255);
		}

		*SaLenPt = sizeof(struct sockaddr_in);
	} else {
		Sin6 = SIN6(SaPt);
		memset(Sin6, 0, sizeof(*Sin6));

		Sin6->sin6_family = AF_INET6;
		Sin6->sin6_port = htons(atoi(PortSt));

		if (inet_pton(AF_INET6, AddrSt, &Sin6->sin6_addr) <= 0) {
			smclog(LOG_ERR, "inet_pton failed for address %s: %m", AddrSt);
			exit(255);
		}

		*SaLenPt = sizeof(struct sockaddr_in6);
	}
}
Exemple #3
0
static void SetOif4(int Sock, char *ifname)
{
	struct ifreq IfReq;
	struct sockaddr_in *Sin4 = NULL;

	memset(&IfReq, 0, sizeof(IfReq));
	strncpy(IfReq.ifr_name, ifname, sizeof(IfReq.ifr_name));

	if (ioctl(Sock, SIOCGIFADDR, &IfReq) < 0) {
		smclog(LOG_ERR, "ioctl SIOCGIFADDR: %m");
		exit(255);
	}

	switch (IfReq.ifr_addr.sa_family) {
	case AF_INET:
		Sin4 = SIN4(&IfReq.ifr_addr);
		break;

	default:
		fprintf(stderr, "SetOif4 - invalid address family: %d\n", IfReq.ifr_addr.sa_family);
		exit(1);
	}

	if (setsockopt(Sock, IPPROTO_IP, IP_MULTICAST_IF, &Sin4->sin_addr, sizeof(struct in_addr))) {
		smclog(LOG_ERR, "set IP_MULTICAST_IF: %m");
		exit(255);
	}
}
Exemple #4
0
static struct socket *getlist4(	struct inpcbtable *tcbtablep,
								struct inpcbtable *ktcbtablep,
								in_port_t lport,
								in_port_t fport,
								const struct in_addr *laddr,
								const struct in_addr *faddr)
{
	struct inpcb *kpcbp, pcb;

	if (tcbtablep == NULL)
		return (NULL);

	kpcbp = (struct inpcb *) tcbtablep->inpt_queue.cqh_first;
	while (kpcbp != (struct inpcb *) ktcbtablep) {
		if (getbuf((u_long) kpcbp, &pcb, sizeof(struct inpcb)) == -1)
			break;

		if (opt_enabled(PROXY)) {
			if (faddr->s_addr == SIN4(&proxy)->sin_addr.s_addr &&
				laddr->s_addr != SIN4(&proxy)->sin_addr.s_addr &&
				pcb.inp_fport == fport &&
				pcb.inp_lport == lport)
			{
				return (pcb.inp_socket);
			}
		}

		if (pcb.inp_faddr.s_addr == faddr->s_addr &&
			pcb.inp_laddr.s_addr == laddr->s_addr &&
			pcb.inp_fport == fport &&
			pcb.inp_lport == lport)
		{
			return (pcb.inp_socket);
		}

		kpcbp = (struct inpcb *) pcb.inp_queue.cqe_next;
	}

	return (NULL);
}
Exemple #5
0
static struct socket *getlist4(	struct inpcbhead *pcbhead,
								in_port_t lport,
								in_port_t fport,
								const struct in_addr *laddr,
								const struct in_addr *faddr)
{
	struct inpcb *pcbp, pcb;

	if (pcbhead == NULL)
		return (NULL);

	pcbp = pcbhead->lh_first;
	while (pcbp != NULL) {
		if (getbuf((u_long) pcbp, &pcb, sizeof(struct inpcb)) == -1)
			break;

		if (opt_enabled(PROXY)) {
			if (faddr->s_addr == SIN4(&proxy)->sin_addr.s_addr &&
				laddr->s_addr != SIN4(&proxy)->sin_addr.s_addr &&
				pcb.inp_fport == fport &&
				pcb.inp_lport == lport)
			{
				return (pcb.inp_socket);
			}
		}

		if (pcb.inp_faddr.s_addr == faddr->s_addr &&
			pcb.inp_laddr.s_addr == laddr->s_addr &&
			pcb.inp_fport == fport &&
			pcb.inp_lport == lport)
		{
			return (pcb.inp_socket);
		}

		pcbp = pcb.inp_list.le_next;
	}

	return (NULL);
}
Exemple #6
0
int get_user4(	in_port_t lport,
				in_port_t fport,
				struct sockaddr_storage *laddr,
				struct sockaddr_storage *faddr)
{
	struct socket *sockp, sock;
	struct inpcbtable tcbtable;
	int ret;
#ifdef SO_UIDINFO
	struct uidinfo uidinfo;
#endif

	ret = getbuf(kinfo->nl[N_TCB].n_value, &tcbtable, sizeof(tcbtable));
	if (ret == -1)
		return (-1);

	sockp = getlist4(&tcbtable,
				(struct inpcbtable *) kinfo->nl[N_TCB].n_value,
				lport, fport, &SIN4(laddr)->sin_addr, &SIN4(faddr)->sin_addr);

	if (sockp == NULL)
		return (-1);

	if (getbuf((u_long) sockp, &sock, sizeof(sock)) == -1)
		return (-1);

#ifdef SO_UIDINFO
	if (sock.so_uidinfo == NULL)
		return (-1);

	if (getbuf((u_long) sock.so_uidinfo, &uidinfo, sizeof(uidinfo)) == -1)
		return (-1);

	return (uidinfo.ui_uid);
#else
	return (sock.so_uid);
#endif
}
Exemple #7
0
static struct socket *getlist(	void *arg,
								in_port_t lport,
								in_port_t fport,
								const struct sockaddr *laddr,
								const struct sockaddr *faddr)
{
	struct inpcb *pcbp = arg;
	struct inpcb *head;

	if (pcbp == NULL)
		return (NULL);

	head = pcbp->inp_prev;

	do {
		if (opt_enabled(PROXY)) {
			if (SIN4(faddr)->sin_addr.s_addr == SIN4(&proxy)->sin_addr.s_addr &&
				SIN4(laddr)->sin_addr.s_addr != SIN4(&proxy)->sin_addr.s_addr &&
				pcbp->inp_fport == fport &&
				pcbp->inp_lport == lport)
			{
				return (pcb.inp_socket);
			}
		}

		if (pcbp->inp_faddr.s_addr == SIN4(faddr)->sin_addr.s_addr &&
			pcbp->inp_laddr.s_addr == SIN4(laddr)->sin_addr.s_addr &&
			pcbp->inp_fport == fport &&
			pcbp->inp_lport == lport)
		{
			return (pcbp->inp_socket);
		}
	} while (pcbp->inp_next != head &&
		getbuf((u_long) pcbp->inp_next, pcbp, sizeof(struct inpcb)) != -1);

	return (NULL);
}
Exemple #8
0
int masq(	int sock,
			in_port_t lport,
			in_port_t fport,
			struct sockaddr_storage *laddr,
			struct sockaddr_storage *faddr)
{
	nat_t *np;
	nat_t nat;
	char os[24];
	char user[MAX_ULEN];
	struct sockaddr_storage ss;

	/*
	** Only IPv4 is supported right now..
	*/

	if (faddr->ss_family != AF_INET || laddr->ss_family != AF_INET)
		return (-1);

	if (getbuf(kinfo->nl[N_NATLIST].n_value, &np, sizeof(np)) == -1)
		return (-1);

	for (; np != NULL ; np = nat.nat_next) {
		int ret;
		in_port_t masq_lport;

		if (getbuf((u_long) np, &nat, sizeof(nat)) == -1) {
			debug("getbuf: %s", strerror(errno));
			break;
		}

		if (nat.nat_p != IPPROTO_TCP)
			continue;

		if (lport != nat.nat_outport)
			continue;

		if (fport != nat.nat_oport)
			continue;

		if (SIN4(laddr)->sin_addr.s_addr != nat.nat_outip.s_addr)
			continue;

		if (SIN4(faddr)->sin_addr.s_addr != nat.nat_oip.s_addr) {
			if (!opt_enabled(PROXY))
				continue;

			if (SIN4(faddr)->sin_addr.s_addr != SIN4(&proxy)->sin_addr.s_addr)
				continue;

			if (SIN4(laddr)->sin_addr.s_addr == SIN4(&proxy)->sin_addr.s_addr)
				continue;
		}

		lport = ntohs(lport);
		fport = ntohs(fport);
		masq_lport = ntohs(nat.nat_inport);

		sin_setv4(nat.nat_inip.s_addr, &ss);

		if (opt_enabled(FORWARD)) {
			ret = fwd_request(sock, lport, masq_lport, fport, &ss);

			if (ret == 0)
				return (0);
			else {
				char ipbuf[MAX_IPLEN];

				get_ip(&ss, ipbuf, sizeof(ipbuf));

				debug("Forward to %s (%d %d | %d %d) failed",
					ipbuf, lport, fport, nat.nat_inport, nat.nat_outport);
			}
		}

		ret = find_masq_entry(&ss, user, sizeof(user), os, sizeof(os));
		if (ret == 0) {
			char ipbuf[MAX_IPLEN];

			sockprintf(sock, "%d , %d : USERID : %s : %s\r\n",
				lport, fport, os, user);

			get_ip(faddr, ipbuf, sizeof(ipbuf));

			o_log(NORMAL,
				"[%s] (NAT) Successful lookup: %d , %d : %s",
				ipbuf, lport, fport, user);

			return (0);
		}
	}

	return (-1);
}
Exemple #9
0
static struct socket *getlist(	void *arg,
								in_port_t lport,
								in_port_t fport,
								const struct sockaddr *local,
								const struct sockaddr *remote)
{
	struct inpcb *head, pcbp;
	struct inpcbhead *pcbhead = arg;
	char *faddr, *laddr, *pfaddr, *pladdr;
	int alen;

	if (remote->sa_family != local->sa_family)
		return (NULL);
	switch (remote->sa_family) {
	case AF_INET:
		faddr = (char *)&SIN4(remote)->sin_addr;
		laddr = (char *)&SIN4(local)->sin_addr;
		break;
	case AF_INET6:
		faddr = (char *)&SIN6(remote)->sin6_addr;
		laddr = (char *)&SIN6(local)->sin6_addr;
		break;
	default:
		return (NULL);
	}

	head = pcbhead->lh_first;
	if (head == NULL)
		return (NULL);

	do {
		if (getbuf((u_long) head, &pcbp, sizeof(struct inpcb)) == -1)
			break;

		if (opt_enabled(PROXY) && remote->sa_family == AF_INET) {
			if (SIN4(remote)->sin_addr.s_addr == SIN4(&proxy)->sin_addr.s_addr &&
				SIN4(local)->sin_addr.s_addr != SIN4(&proxy)->sin_addr.s_addr &&
				pcbp.inp_fport == fport &&
				pcbp.inp_lport == lport)
			{
				return (pcbp.inp_socket);
			}
		}

		if (remote->sa_family == AF_INET)
		{
			pfaddr = (char *)&pcbp.inp_faddr;
			pladdr = (char *)&pcbp.inp_laddr;
			alen = sizeof(struct in_addr);
		}
		else if (remote->sa_family == AF_INET6)
		{
			pfaddr = (char *)&pcbp.in6p_faddr;
			pladdr = (char *)&pcbp.in6p_laddr;
			alen = sizeof(struct in6_addr);
		}
		else
			continue;
		if (memcmp(pfaddr, faddr, alen) == 0 &&
			memcmp(pladdr, laddr, alen) == 0 &&
			pcbp.inp_fport == fport &&
			pcbp.inp_lport == lport)
		{
			return (pcbp.inp_socket);
		}

		head = pcbp.inp_list.le_next;
	} while (head != NULL);

	return (NULL);
}
Exemple #10
0
int sock_listen(struct sockaddr_storage *ss, in_port_t listen_port) {
	int sock;
	struct addrinfo *cur;
	const int one = 1;

	if (ss == NULL)
		return (-1);

	cur = xcalloc(1, sizeof(*cur));
	cur->ai_family = ss->ss_family;

	switch (cur->ai_family) {
		case AF_INET6:
			cur->ai_addrlen = sizeof(struct sockaddr_in6);
			break;

		case AF_INET:
			cur->ai_addrlen = sizeof(struct sockaddr_in);
			break;

		default:
			debug("unknown family: %d", cur->ai_family);
			free(cur);
			return (-1);
	}

	cur->ai_addr = xmalloc(cur->ai_addrlen);
	memcpy(cur->ai_addr, ss, cur->ai_addrlen);

	if (cur->ai_family == AF_INET)
		SIN4(cur->ai_addr)->sin_port = htons(listen_port);
	else
		SIN6(cur->ai_addr)->sin6_port = htons(listen_port);

	sock = socket(cur->ai_family, SOCK_STREAM, 0);
	if (sock == -1) {
		debug("socket: %s", strerror(errno));
		goto done;
	}

	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) != 0) {
		debug("setsockopt: %s", strerror(errno));
		close(sock);
		sock = -1;
		goto done;
	}

	if (bind(sock, cur->ai_addr, cur->ai_addrlen) != 0) {
		debug("bind: %s", strerror(errno));
		close(sock);
		sock = -1;
		goto done;
	}

	if (listen(sock, SOMAXCONN) != 0) {
		debug("listen: %s", strerror(errno));
		close(sock);
		sock = -1;
		goto done;
	}

#ifndef WIN32
	if (fcntl(sock, F_SETFL, O_NONBLOCK) == -1) {
		debug("fcntl: %s", strerror(errno));
		close(sock);
		sock = -1;
	}
#endif

done:
	free(cur->ai_addr);
	free(cur);
	return (sock);
}
Exemple #11
0
void sin_set_port(struct sockaddr_storage *ss, in_port_t port) {
	if (ss->ss_family == AF_INET6)
		SIN6(ss)->sin6_port = port;

	SIN4(ss)->sin_port = port;
}