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); }
/* * 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); } }
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); } }
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); }
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); }
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 }
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); }
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); }
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); }
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); }
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; }