u_char * find_nodeID(void) { int i; struct sockaddr *sa; char *ptr; u_char *myNodeIDtmp = 0; struct ifi_info *ifi, *ifihead; /* * Get interface info for all inet4 interfaces * and don't return aliases. */ for (ifihead = ifi = get_ifi_info(AF_INET, 0); ifi != NULL; ifi = ifi->ifi_next) { printf("%s: <", ifi->ifi_name); if (ifi->ifi_flags & IFF_UP) printf("UP "); if (ifi->ifi_flags & IFF_BROADCAST) printf("BCAST "); if (ifi->ifi_flags & IFF_MULTICAST) printf("MCAST "); if (ifi->ifi_flags & IFF_LOOPBACK) printf("LOOP "); if (ifi->ifi_flags & IFF_POINTOPOINT) printf("P2P "); printf(">\n"); if ( (i = ifi->ifi_hlen) > 0) { ptr = ifi->ifi_haddr; do { printf("%s%x", (i == ifi->ifi_hlen) ? " " : ":", *ptr++); } while (--i > 0); } /* * We update myNodeIDtmp in block separate from above * since the above is just a debug clause and may be * compiled out eventually. -lkw */ if ( ifi->ifi_hlen > 0) { myNodeIDtmp = max_haddr(myNodeIDtmp, ifi->ifi_haddr); } if ( (sa = ifi->ifi_addr) != NULL) printf(" IP addr: %s\n", sock_ntop(sa, sa->sa_len)); if ( (sa = ifi->ifi_brdaddr) != NULL) printf(" broadcast addr: %s\n", sock_ntop(sa, sa->sa_len)); if ( (sa = ifi->ifi_dstaddr) != NULL) printf(" destination addr: %s\n", sock_ntop(sa, sa->sa_len)); } fprintf(stderr, "My node id:"); print_nodeID(myNodeIDtmp); return myNodeIDtmp; }
//============================================================================= void Metaserver::HandleClientShake(SA *pcliaddr, ClientShakeMsg &msg) { int active; unsigned int handshake; list<Handshake>::iterator i; char *presentation; SAIN *sa; Handshake search_for; sa = (SAIN *)pcliaddr; handshake = msg.GetHandshake(); search_for.SetValues(sa->sin_addr.s_addr, handshake, 0); i = FindByHS(mClientHandshakes.begin(), mClientHandshakes.end(), search_for); if(i != mClientHandshakes.end()) { #ifdef DEBUG presentation = sock_ntop(pcliaddr, sizeof(SA)); debug_msg("Received valid handshake from %s", PolishedPresentation(presentation)); #endif mClientHandshakes.erase(i); i = FindByAddr(mActiveClients.begin(), mActiveClients.end(), search_for); if(i == mActiveClients.end()) { search_for.SetValues(sa->sin_addr.s_addr, 0, time(NULL)); mActiveClients.push_back(search_for); if((active = mActiveClients.size()) > mPeakActiveClients) mPeakActiveClients = active; #ifdef DEBUG presentation = sock_ntop(pcliaddr, sizeof(SA)); debug_msg("Added new active client at %s", PolishedPresentation(presentation)); #endif } else { (*i).SetTimestamp(time(NULL)); #ifdef DEBUG presentation = sock_ntop(pcliaddr, sizeof(SA)); debug_msg("Updated existing client at %s", PolishedPresentation(presentation)); #endif } } else { presentation = sock_ntop(pcliaddr, sizeof(SA)); warning_msg("Bogus CLIENTSHAKE packet received from: %s", PolishedPresentation(presentation)); } }
void udp_cli(FILE* fp,int sockfd, const struct sockaddr*cliaddr, socklen_t len){ int n; struct sockaddr *pre; socklen_t plen; pre= (struct sockaddr *)malloc(len); char sendline[MAXSIZE], recvline[MAXSIZE+1]; while( fgets( sendline,MAXSIZE, fp) !=NULL){ sendto(sockfd,sendline,strlen(sendline), 0, cliaddr, len); bzero(&sendline,sizeof(sendline)); plen=len; n=recvfrom(sockfd,recvline,MAXSIZE, 0,pre,&plen); if(len !=plen || memcmp(cliaddr,pre,len) !=0 ){ // std::cout<<pre->sa_data<<plen<<std::endl; printf("asdasd"); printf("replay from %s (ignored)",sock_ntop(pre,plen)); continue; } recvline[n]='\0'; fputs(recvline,stdout); bzero(recvline,sizeof(recvline)); } }
//============================================================================= void Metaserver::HandleClientKeepalive(SA *pcliaddr, socklen_t socketlen) { unsigned int handshake = random(); int active; Handshake hs; #ifdef DEBUG char *presentation; #endif SAIN *sa = (SAIN *)pcliaddr; hs.SetValues(sa->sin_addr.s_addr, handshake, time(NULL)); mClientHandshakes.push_back(hs); if((active = mClientHandshakes.size()) > mPeakPendingClientHandshakes) mPeakPendingClientHandshakes = active; HandshakeMsg msg(handshake); sendto(mListenSocket, msg.GetPackedBuffer(), msg.GetPackedBufferLength(), 0, pcliaddr, socketlen); #ifdef DEBUG presentation = sock_ntop(pcliaddr, sizeof(SA)); debug_msg("Received client keepalive from %s", PolishedPresentation(presentation)); #endif }
static int loop(int s, socklen_t sa_len){ static struct sockaddr *sa = NULL; char *buf = NULL; socklen_t len; ssize_t n; int status = 0; sa = malloc(sa_len); if(sa == NULL) err(1, "Error from malloc()"); buf = malloc(g.size); if(buf == NULL) err(1, "Error from malloc()"); while(status == 0){ len = sa_len; memset(buf, '\0', g.size); n = recvfrom(s, buf, g.size - 1, 0, sa, &len); if(n == -1) status = -1; else fprintf(stdout, "%s %s\n", sock_ntop(sa), buf); } if(status == -1) err(1, "Error from recvfrom()"); return(status); }
int main(int argc, char *argv[]) { int sockfd; struct ifi_info *ifi; unsigned char *ptr; struct arpreq arpreq; struct sockaddr_in *sin; if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) err_sys("socket error"); for (ifi = get_ifi_info(AF_INET, 0); ifi; ifi = ifi->ifi_next) { printf("%s: ", sock_ntop(ifi->ifi_addr, sizeof(struct sockaddr_in))); sin = (struct sockaddr_in *)&arpreq.arp_pa; memcpy(sin, ifi->ifi_addr, sizeof(struct sockaddr_in)); if (ioctl(sockfd, SIOCGARP, &arpreq) < 0) { err_ret("ioctl SIOCGARP"); continue; } ptr = &arpreq.arp_ha.sa_data[0]; printf("%x:%x:%x:%x:%x:%x\n", *ptr, *(ptr + 1), *(ptr + 2), *(ptr + 3), *(ptr + 4), *(ptr + 5)); } exit(0); }
int main(int argc, char **argv) { int sockfd; socklen_t len; struct sockaddr_in cliaddr, servaddr; if (argc != 2) err_quit("usage: udpcli <IPaddress>"); if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) err_sys("socket error"); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(SERV_PORT); if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) < 0) err_sys("inet_pton error"); if (connect(sockfd, (SA *)&servaddr, sizeof(servaddr)) < 0) err_sys("connect error"); len = sizeof(cliaddr); if (getsockname(sockfd, (SA *)&cliaddr, &len) < 0) err_sys("getsockname error"); printf("local address %s\n", sock_ntop((SA *)&cliaddr, len)); exit(0); }
char *Sock_ntop(const struct sockaddr *sa, socklen_t salen) { char *ptr; if ( (ptr = sock_ntop(sa, salen)) == NULL) err_msg("sock_ntop error"); /* inet_ntop() sets errno */ return (ptr); }
void proxy_reply(int cmd, struct sockaddr *sa, u_int16_t port) { int i, r; switch (cmd) { case CMD_PORT: r = snprintf(linebuf, sizeof linebuf, "PORT %s,%u,%u\r\n", sock_ntop(sa), port / 256, port % 256); break; case CMD_PASV: r = snprintf(linebuf, sizeof linebuf, "227 Entering Passive Mode (%s,%u,%u)\r\n", sock_ntop(sa), port / 256, port % 256); break; case CMD_EPRT: if (sa->sa_family == AF_INET) r = snprintf(linebuf, sizeof linebuf, "EPRT |1|%s|%u|\r\n", sock_ntop(sa), port); else if (sa->sa_family == AF_INET6) r = snprintf(linebuf, sizeof linebuf, "EPRT |2|%s|%u|\r\n", sock_ntop(sa), port); break; case CMD_EPSV: r = snprintf(linebuf, sizeof linebuf, "229 Entering Extended Passive Mode (|||%u|)\r\n", port); break; } if (r < 0 || r >= sizeof linebuf) { logmsg(LOG_ERR, "proxy_reply failed: %d", r); linebuf[0] = '\0'; linelen = 0; return; } linelen = (size_t)r; if (cmd == CMD_PORT || cmd == CMD_PASV) { /* Replace dots in IP address with commas. */ for (i = 0; i < linelen; i++) if (linebuf[i] == '.') linebuf[i] = ','; } }
char * Sock_ntop (const struct sockaddr *sa, socklen_t salen) { char *ptr; if ((ptr = sock_ntop(sa, salen)) == NULL) err_sys ("sock_ntop error"); return ptr; }
char * Sock_ntop(const struct sockaddr *sa, socklen_t salen) { char *ptr; static char str[128]; if ( (ptr = sock_ntop(sa, salen, str, sizeof(str))) == NULL) err_sys("sock_ntop error"); /* inet_ntop() sets errno */ return(ptr); }
/****************************************************************************** *Function: Sock_ntop *Description: change socket network address to presentation format, * sock_ntop wrapper *Input: sa(socket address) / salen(socket addr struct length) *Output: none *Return: socket address string *Date: 2016/3/2 ******************************************************************************/ char * Sock_ntop(const struct sockaddr *sa, socklen_t salen) { char *str; str = sock_ntop(sa, salen); if(str == NULL) err_sys("sock_ntop error"); // inet_ntop() sets errno return str; }
char * Sock_ntop(const struct sockaddr *sa, socklen_t salen) { char *ptr; if ( (ptr = sock_ntop(sa, salen)) == NULL) { syslog(LOG_INFO,"sock_ntop error"); /* inet_ntop() sets errno */ werrno = ENET; return (NULL); } return(ptr); }
//============================================================================= void Metaserver::HandleTerminate(SA *pcliaddr) { list<Handshake>::iterator i; char *presentation; SAIN *sa; Handshake search_for; sa = (SAIN *)pcliaddr; search_for.SetValues(sa->sin_addr.s_addr, 0, 0); i = FindByAddr(mActiveServers.begin(), mActiveServers.end(), search_for); if(i != mActiveServers.end()) { #ifdef DEBUG presentation = sock_ntop(pcliaddr, sizeof(SA)); debug_msg("Received termination from server at %s", PolishedPresentation(presentation)); #endif mActiveServers.erase(i); if(mExecute[0] != '\0') { int res = system(mExecute); if (res == -1) { err_sys("fork"); } else { int status = WEXITSTATUS(res); if (status != 0) { warning_msg("error running %s: %d", mExecute, status); } } } } else { presentation = sock_ntop(pcliaddr, sizeof(SA)); warning_msg("Received TERMINATION packet for unlisted server from: " "%s", PolishedPresentation(presentation)); } }
void recv_all(int recvfd, socklen_t salen) { int n; char line[MAXLINE + 1]; socklen_t len; struct sockaddr *safrom; safrom = (struct sockaddr *) malloc(salen); for ( ; ; ) { len = salen; n = recvfrom(recvfd, line, MAXLINE, 0, safrom, &len); line[n] = 0; printf("from %s: %s", sock_ntop(safrom, len), line); } }
int main(int argc, char **argv) { int listenfd, connfd; socklen_t addrlen, len; struct sockaddr *cliaddr; char buff[MAXLINE]; time_t ticks; if (argc < 2 || argc > 3) { fprintf(stderr, "usage: daytimetcpsrv2 [ <host> ] <service or port>\n"); exit(1); } daemon_init(argv[0], 0); if (argc == 2) listenfd = tcp_listen(NULL, argv[1], &addrlen); else listenfd = tcp_listen(argv[1], argv[2], &addrlen); if ((cliaddr = malloc(addrlen)) == NULL) { syslog(LOG_ERR, "malloc error: %m"); exit(1); } for ( ; ; ) { len = addrlen; if ((connfd = accept(listenfd, cliaddr, &len)) < 0) { syslog(LOG_ERR, "accept error: %m"); exit(1); } syslog(LOG_INFO, "connection from %s\n", sock_ntop(cliaddr, len)); ticks = time(NULL); snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks)); if (write(connfd, buff, strlen(buff)) != strlen(buff)) { syslog(LOG_ERR, "write error: %m"); exit(1); } if (close(connfd) < 0) { syslog(LOG_ERR, "close error: %m"); exit(1); } } }
int main(int argc, char **argv) { int i, listenfd, connfd; socklen_t addrlen, len; struct sockaddr *cliaddr; char buff[MAXLINE]; time_t ticks; if (argc == 2) { listenfd = tcp_listen(NULL, argv[1], &addrlen); } else if (argc == 3) { listenfd = tcp_listen(argv[1], argv[2], &addrlen); } else { fprintf(stderr, "usage: daytimetcpsrv2 [ <host> ] <service or port>\n"); exit(1); } if ((cliaddr = malloc(addrlen)) == NULL) { perror("malloc error"); exit(1); } for ( ; ; ) { len = addrlen; if ((connfd = accept(listenfd, cliaddr, &len)) < 0) { perror("accept error"); exit(1); } printf("connection from %s\n", sock_ntop(cliaddr, len)); ticks = time(NULL); snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks)); for (i = 0; i < strlen(buff); i++) { if (send(connfd, &buff[i], 1, MSG_EOR) != 1) { perror("send error"); exit(1); } } if (close(connfd) == -1) { perror("close error"); exit(1); } } }
void KSGNetUtil::GetLocalIP(std::list<std::string>&ip_list) { struct ifi_info *ifi, *ifihead; struct sockaddr *sa; u_char *ptr; char * ip_addr; int i, family, doaliases; family = AF_INET; doaliases = 1; for(ifi = ifihead = get_ifi_info(family,doaliases); ifi != NULL; ifi = ifi->ifi_next) { if((sa = ifi->ifi_addr) != NULL) { ip_addr = strdup(sock_ntop(sa,sizeof(*sa))); ip_list.push_back(std::string(ip_addr)); } } free_ifi_info(ifihead); }
static void recv_all(int recvfd, socklen_t salen) { int n; char line[MAXLINE+1]; socklen_t len; struct sockaddr *safrom; char *host_name = NULL; safrom = malloc(salen); for (;;) { len = salen; n = recvfrom(recvfd, line, MAXLINE, 0, safrom, &len); assert(n >= 0); line[n] = 0; host_name = sock_ntop(safrom); assert(host_name != NULL); printf("from %s: %s", host_name, line); } }
int KSGNetUtil::GetMacByIP(const std::string ip, std::string &mac) { struct ifi_info *ifi, *ifihead; struct sockaddr *sa; u_char *ptr; char mac_str[20] = ""; std::string ipaddr; int i,j,ret, family, doaliases; family = AF_INET; doaliases = 1; ret = -1; for(ifi = ifihead = get_ifi_info(family,doaliases); ifi != NULL; ifi = ifi->ifi_next) { if((sa = ifi->ifi_addr) != NULL) { ipaddr = sock_ntop(sa,sizeof(*sa)); if(ipaddr == ip) { if(( i = ifi->ifi_hlen) > 0) { ptr = ifi->ifi_haddr; j = 0; do{ j += sprintf(mac_str+j,"%s%02X",(i == ifi->ifi_hlen) ? " " : "-", *ptr++); }while(--i>0); mac = mac_str; } ret = 0; break; } } } free_ifi_info(ifihead); return ret; }
int main(int argc, char **argv) { int listenfd, connfd; socklen_t len; char buff[MAXLINE]; time_t ticks; struct sockaddr_storage cliaddr; if (argc != 2) err_quit("usage: daytimetcpsrv1 <service or port#>"); listenfd = Tcp_listen(NULL, argv[1], NULL); for ( ; ; ) { len = sizeof(cliaddr); connfd = accept(listenfd, (SA *)&cliaddr, &len); if(connfd < 0) { err_quit("accept"); } printf("connection from %s\n", sock_ntop((SA *)&cliaddr, len)); // 另外一种打印方式 char host[NI_MAXHOST], serv[NI_MAXSERV]; if (getnameinfo((SA *)&cliaddr, len, host, NI_MAXHOST, serv, NI_MAXSERV, NI_NUMERICHOST | NI_NUMERICSERV) == 0) printf("connect from %s.%s\n", host, serv); ticks = time(NULL); snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks)); if(write(connfd, buff, strlen(buff)) < 0) { err_quit("write"); } close(connfd); } }
int main(int argc, char *argv[]) { int sockfd; socklen_t len; struct sockaddr_in cliaddr, servaddr; const int on = 1; if (argc != 2 && argc != 3) err_quit("usage: udpcli_srcaddr <IPaddress> [broadcast_flag]"); sockfd = socket(AF_INET, SOCK_DGRAM, 0); /* * If we use a broadcast address, we need to set SO_BROADCAST. * Otherwise, Linux will return EPERM on attempts to connect * or send via a socket. */ if (argc == 3) setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(SERV_PORT); inet_pton(AF_INET, argv[1], &servaddr.sin_addr); if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) == -1) { perror("connect() error"); exit(2); } len = sizeof(cliaddr); getsockname(sockfd, (SA *) &cliaddr, &len); printf("local address %s\n", sock_ntop((SA *) &cliaddr, len)); exit(0); }
int main(int argc, char *argv[]) { struct rlimit rlp; struct addrinfo hints, *res; struct event ev_sighup, ev_sigint, ev_sigterm; int ch, error, listenfd, on; const char *errstr; /* Defaults. */ anonymous_only = 0; daemonize = 1; fixed_proxy = NULL; fixed_server = NULL; fixed_server_port = "21"; ipv6_mode = 0; listen_ip = NULL; listen_port = "8021"; loglevel = LOG_NOTICE; max_sessions = 100; qname = NULL; rfc_mode = 0; tagname = NULL; timeout = 24 * 3600; verbose = 0; /* Other initialization. */ id_count = 1; session_count = 0; while ((ch = getopt(argc, argv, "6Aa:b:D:dm:P:p:q:R:rT:t:v")) != -1) { switch (ch) { case '6': ipv6_mode = 1; break; case 'A': anonymous_only = 1; break; case 'a': fixed_proxy = optarg; break; case 'b': listen_ip = optarg; break; case 'D': loglevel = strtonum(optarg, LOG_EMERG, LOG_DEBUG, &errstr); if (errstr) errx(1, "loglevel %s", errstr); break; case 'd': daemonize = 0; break; case 'm': max_sessions = strtonum(optarg, 1, 500, &errstr); if (errstr) errx(1, "max sessions %s", errstr); break; case 'P': fixed_server_port = optarg; break; case 'p': listen_port = optarg; break; case 'q': if (strlen(optarg) >= PF_QNAME_SIZE) errx(1, "queuename too long"); qname = optarg; break; case 'R': fixed_server = optarg; break; case 'r': rfc_mode = 1; break; case 'T': if (strlen(optarg) >= PF_TAG_NAME_SIZE) errx(1, "tagname too long"); tagname = optarg; break; case 't': timeout = strtonum(optarg, 0, 86400, &errstr); if (errstr) errx(1, "timeout %s", errstr); break; case 'v': verbose++; if (verbose > 2) usage(); break; default: usage(); } } if (listen_ip == NULL) listen_ip = ipv6_mode ? "::1" : "127.0.0.1"; /* Check for root to save the user from cryptic failure messages. */ if (getuid() != 0) errx(1, "needs to start as root"); /* Raise max. open files limit to satisfy max. sessions. */ rlp.rlim_cur = rlp.rlim_max = (2 * max_sessions) + 10; if (setrlimit(RLIMIT_NOFILE, &rlp) == -1) err(1, "setrlimit"); if (fixed_proxy) { memset(&hints, 0, sizeof hints); hints.ai_flags = AI_NUMERICHOST; hints.ai_family = ipv6_mode ? AF_INET6 : AF_INET; hints.ai_socktype = SOCK_STREAM; error = getaddrinfo(fixed_proxy, NULL, &hints, &res); if (error) errx(1, "getaddrinfo fixed proxy address failed: %s", gai_strerror(error)); memcpy(&fixed_proxy_ss, res->ai_addr, res->ai_addrlen); logmsg(LOG_INFO, "using %s to connect to servers", sock_ntop(sstosa(&fixed_proxy_ss))); freeaddrinfo(res); } if (fixed_server) { memset(&hints, 0, sizeof hints); hints.ai_family = ipv6_mode ? AF_INET6 : AF_INET; hints.ai_socktype = SOCK_STREAM; error = getaddrinfo(fixed_server, fixed_server_port, &hints, &res); if (error) errx(1, "getaddrinfo fixed server address failed: %s", gai_strerror(error)); memcpy(&fixed_server_ss, res->ai_addr, res->ai_addrlen); logmsg(LOG_INFO, "using fixed server %s", sock_ntop(sstosa(&fixed_server_ss))); freeaddrinfo(res); } /* Setup listener. */ memset(&hints, 0, sizeof hints); hints.ai_flags = AI_NUMERICHOST | AI_PASSIVE; hints.ai_family = ipv6_mode ? AF_INET6 : AF_INET; hints.ai_socktype = SOCK_STREAM; error = getaddrinfo(listen_ip, listen_port, &hints, &res); if (error) errx(1, "getaddrinfo listen address failed: %s", gai_strerror(error)); if ((listenfd = socket(res->ai_family, SOCK_STREAM, IPPROTO_TCP)) == -1) errx(1, "socket failed"); on = 1; if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof on) != 0) err(1, "setsockopt failed"); if (bind(listenfd, (struct sockaddr *)res->ai_addr, (socklen_t)res->ai_addrlen) != 0) err(1, "bind failed"); if (listen(listenfd, TCP_BACKLOG) != 0) err(1, "listen failed"); freeaddrinfo(res); /* Initialize pf. */ init_filter(qname, tagname, verbose); if (daemonize) { if (daemon(0, 0) == -1) err(1, "cannot daemonize"); openlog(__progname, LOG_PID | LOG_NDELAY, LOG_DAEMON); } /* Use logmsg for output from here on. */ if (!drop_privs()) { logmsg(LOG_ERR, "cannot drop privileges: %s", strerror(errno)); exit(1); } event_init(); /* Setup signal handler. */ signal(SIGPIPE, SIG_IGN); signal_set(&ev_sighup, SIGHUP, handle_signal, NULL); signal_set(&ev_sigint, SIGINT, handle_signal, NULL); signal_set(&ev_sigterm, SIGTERM, handle_signal, NULL); signal_add(&ev_sighup, NULL); signal_add(&ev_sigint, NULL); signal_add(&ev_sigterm, NULL); event_set(&listen_ev, listenfd, EV_READ, handle_connection, NULL); event_add(&listen_ev, NULL); evtimer_set(&pause_accept_ev, handle_connection, NULL); logmsg(LOG_NOTICE, "listening on %s port %s", listen_ip, listen_port); /* Vroom, vroom. */ event_dispatch(); logmsg(LOG_ERR, "event_dispatch error: %s", strerror(errno)); exit_daemon(); /* NOTREACHED */ return (1); }
//============================================================================= void Metaserver::HandleServerShake(SA *pcliaddr, const ServerShakeMsg &msg) { int active; unsigned int handshake; list<Handshake>::iterator i; char *presentation; SAIN *sa; Handshake search_for; sa = (SAIN *)pcliaddr; handshake = msg.GetHandshake(); search_for.SetValues(sa->sin_addr.s_addr, handshake, 0); i = FindByHS(mServerHandshakes.begin(), mServerHandshakes.end(), search_for); if(i != mServerHandshakes.end()) { #ifdef DEBUG presentation = sock_ntop(pcliaddr, sizeof(SA)); debug_msg("Received valid server handshake from %s", PolishedPresentation(presentation)); #endif mServerHandshakes.erase(i); i = FindByAddr(mActiveServers.begin(), mActiveServers.end(), search_for); if(i == mActiveServers.end()) { search_for.SetValues(sa->sin_addr.s_addr, 0, time(NULL)); mActiveServers.push_back(search_for); if(mExecute[0] != '\0') { int res = system(mExecute); if (res == -1) { err_sys("fork"); } else { int status = WEXITSTATUS(res); if (status != 0) { warning_msg("error running %s: %d", mExecute, status); } } } if((active = mActiveServers.size()) > mPeakActiveServers) mPeakActiveServers = active; #ifdef DEBUG presentation = sock_ntop(pcliaddr, sizeof(SA)); debug_msg("Added new active server at %s", PolishedPresentation(presentation)); #endif } else { (*i).SetTimestamp(time(NULL)); #ifdef DEBUG presentation = sock_ntop(pcliaddr, sizeof(SA)); debug_msg("Updated existing active server at %s", PolishedPresentation(presentation)); #endif } } else { presentation = sock_ntop(pcliaddr, sizeof(SA)); warning_msg("Bogus SERVERSHAKE packet received from: %s", PolishedPresentation(presentation)); } }
int main(int argc, char **argv) { int sendfd, recvfd; const int on = 1; socklen_t salen; struct sockaddr *sasend, *sarecv; int result; int onoff = 0; if (argc != 3) { printf("usage: ./multicasting <IP-multicast-address> <port#> <>"); exit(1); } sendfd = udp_sender(argv[1], argv[2], &sasend, &salen); recvfd = socket(sasend->sa_family, SOCK_DGRAM, 0); assert(recvfd > 2); // Now IP from iface // int fd; // struct ifreq ifr; // fd = socket(AF_INET, SOCK_DGRAM, 0); // /* I want to get an IPv4 IP address */ // ifr.ifr_addr.sa_family = AF_INET; // /* I want IP address attached to "eth0" */ // strncpy(ifr.ifr_name, "enp0s25", IFNAMSIZ-1); // ioctl(fd, SIOCGIFADDR, &ifr); // close(fd); /* display result */ //printf("%s\n", inet_ntoa( ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr) ); // I don't want default iface but wlo1 result = setsockopt(recvfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); assert(result >= 0); sarecv = malloc(salen); assert(sarecv != NULL); memcpy(sarecv, sasend, salen); result = bind(recvfd, sarecv, salen); assert(result >= 0); char *src_host = sock_ntop(sarecv); printf("src_host = %s\n", src_host); char *dst_host = sock_ntop(sasend); printf("dst_host = %s\n", dst_host); result = mcast_join(recvfd, sasend, salen); assert(result >= 0); result = setsockopt(sendfd, IPPROTO_IP, IP_MULTICAST_LOOP, &onoff, sizeof(onoff)); assert(result >= 0); // struct in_addr interface_addr;// = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr; // interface_addr.s_addr = htonl(IP_SRC_ADDR_ENP); // result = setsockopt(recvfd, IPPROTO_IP, IP_MULTICAST_IF, &interface_addr, sizeof(interface_addr)); // assert(result >= 0); if (fork() == 0) recv_all(recvfd, salen); send_all(sendfd, sasend, salen); return 0; }
void print_routing(char *proto) { int mib[6]; int i = 0; int rt_len; int if_len; int if_num; char *rt_buf; char *if_buf; char *next; char *lim; struct rt_msghdr *rtm; struct if_msghdr *ifm; struct if_msghdr **ifm_table; struct ifa_msghdr *ifam; struct sockaddr *sa; struct sockaddr *sa1; struct sockaddr *rti_info[RTAX_MAX]; struct sockaddr **if_table; struct rt_metrics rm; char fbuf[50]; /* keep a copy of statistics here for future use */ static unsigned *base_stats = NULL ; static unsigned base_len = 0 ; /* Get the routing table */ mib[0] = CTL_NET; mib[1] = PF_ROUTE; mib[2] = 0; mib[3] = 0; mib[4] = NET_RT_DUMP; mib[5] = 0; /*Estimate the size of table */ if (sysctl(mib, 6, NULL, &rt_len, NULL, 0) == -1) { perror("sysctl size"); exit(-1); } if ((rt_buf = (char *)malloc(rt_len)) == NULL) { perror("malloc"); exit(-1); } /* Now get it. */ if (sysctl(mib, 6, rt_buf, &rt_len, NULL, 0) == -1) { perror("sysctl get"); exit(-1); } /* Get the interfaces table */ mib[0] = CTL_NET; mib[1] = PF_ROUTE; mib[2] = 0; mib[3] = 0; mib[4] = NET_RT_IFLIST; mib[5] = 0; /* Estimate the size of table */ if (sysctl(mib, 6, NULL, &if_len, NULL, 0) == -1) { perror("sysctl size"); exit(-1); } if ((if_buf = (char *)malloc(if_len)) == NULL) { perror("malloc"); exit(-1); } /* Now get it. */ if (sysctl(mib, 6, if_buf, &if_len, NULL, 0) == -1) { perror("sysctl get"); exit(-1); } lim = if_buf + if_len; i = 0; for (next = if_buf, i = 0; next < lim; next += ifm->ifm_msglen) { ifm = (struct if_msghdr *)next; i++; } if_num = i; if_table = (struct sockaddr **)calloc(i, sizeof(struct sockaddr)); ifm_table = (struct if_msghdr **)calloc(i, sizeof(struct if_msghdr)); if (iflag) { printf("\nInterface table:\n"); printf("----------------\n"); printf("Name Mtu Network Address " "Ipkts Ierrs Opkts Oerrs Coll\n"); } /* scan the list and store base values */ i = 0 ; for (next = if_buf; next < lim; next += ifm->ifm_msglen) { ifm = (struct if_msghdr *)next; i++ ; } if (base_stats == NULL || i != base_len) { base_stats = calloc(i*5, sizeof(unsigned)); base_len = i ; } i = 0; for (next = if_buf; next < lim; next += ifm->ifm_msglen) { ifm = (struct if_msghdr *)next; if_table[i] = (struct sockaddr *)(ifm + 1); ifm_table[i] = ifm; sa = if_table[i]; if (iflag && sa->sa_family == AF_LINK) { struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa; unsigned *bp = &base_stats[i*5]; printf("%-4s %-5d <Link> ", sock_ntop(if_table[i], if_table[i]->sa_len), ifm->ifm_data.ifi_mtu); if (sdl->sdl_alen == 6) { unsigned char *p = sdl->sdl_data + sdl->sdl_nlen; printf("%02x:%02x:%02x:%02x:%02x:%02x ", p[0], p[1], p[2], p[3], p[4], p[5]); } else printf(" "); printf("%9d%6d%9d%6d%6d\n", ifm->ifm_data.ifi_ipackets - bp[0], ifm->ifm_data.ifi_ierrors - bp[1], ifm->ifm_data.ifi_opackets - bp[2], ifm->ifm_data.ifi_oerrors - bp[3], ifm->ifm_data.ifi_collisions -bp[4]); if (delta > 0) { bp[0] = ifm->ifm_data.ifi_ipackets ; bp[1] = ifm->ifm_data.ifi_ierrors ; bp[2] = ifm->ifm_data.ifi_opackets ; bp[3] = ifm->ifm_data.ifi_oerrors ; bp[4] = ifm->ifm_data.ifi_collisions ; } } i++; } if (!rflag) { free(rt_buf); free(if_buf); free(if_table); free(ifm_table); return; } /* Now dump the routing table */ printf("\nRouting table:\n"); printf("--------------\n"); printf ("Destination Gateway Flags Netif Use\n"); lim = rt_buf + rt_len; for (next = rt_buf; next < lim; next += rtm->rtm_msglen) { rtm = (struct rt_msghdr *)next; sa = (struct sockaddr *)(rtm + 1); get_rtaddrs(rtm->rtm_addrs, sa, rti_info); if ((sa = rti_info[RTAX_DST]) != NULL) { sprintf(fbuf, "%s", sock_ntop(sa, sa->sa_len)); if (((sa1 = rti_info[RTAX_NETMASK]) != NULL) && sa1->sa_family == 255) { strcat(fbuf, sock_ntop(sa1, sa1->sa_len)); } printf("%-19s", fbuf); } if ((sa = rti_info[RTAX_GATEWAY]) != NULL) { printf("%-19s", sock_ntop(sa, sa->sa_len)); } memset(fbuf, 0, sizeof(fbuf)); get_flags(fbuf, rtm->rtm_flags); printf("%-10s", fbuf); for (i = 0; i < if_num; i++) { ifm = ifm_table[i]; if ((ifm->ifm_index == rtm->rtm_index) && (ifm->ifm_data.ifi_type > 0)) { sa = if_table[i]; break; } } if (ifm->ifm_type == RTM_IFINFO) { get_rtaddrs(ifm->ifm_addrs, sa, rti_info); printf(" %s", Sock_ntop(sa, sa->sa_len)); } else if (ifm->ifm_type == RTM_NEWADDR) { ifam = (struct ifa_msghdr *)ifm_table[rtm->rtm_index - 1]; sa = (struct sockaddr *)(ifam + 1); get_rtaddrs(ifam->ifam_addrs, sa, rti_info); printf(" %s", Sock_ntop(sa, sa->sa_len)); } /* printf(" %u", rtm->rtm_use); */ printf("\n"); } free(rt_buf); free(if_buf); free(if_table); free(ifm_table); }
int main(int argc, char *argv[]) { int c, fd = 0, on = 1, out_fd = 0, peer, reqsize = 0; int transwait = DEFTRANSWAIT; char *p; struct tftphdr *tp; struct passwd *pw; size_t cbuflen; char *cbuf; char req[PKTSIZE]; struct cmsghdr *cmsg; struct msghdr msg; struct iovec iov; struct sockaddr_storage from, proxy, server, proxy_to_server, s_in; struct sockaddr_in sock_out; socklen_t j; in_port_t bindport; openlog(__progname, LOG_PID | LOG_NDELAY, LOG_DAEMON); while ((c = getopt(argc, argv, "vw:")) != -1) switch (c) { case 'v': verbose++; break; case 'w': transwait = strtoll(optarg, &p, 10); if (transwait < 1) { syslog(LOG_ERR, "invalid -w value"); exit(1); } break; default: usage(); break; } /* open /dev/pf */ init_filter(NULL, verbose); tzset(); pw = getpwnam(NOPRIV_USER); if (!pw) { syslog(LOG_ERR, "no such user %s: %m", NOPRIV_USER); exit(1); } if (chroot(CHROOT_DIR) || chdir("/")) { syslog(LOG_ERR, "chroot %s: %m", CHROOT_DIR); exit(1); } #ifdef __NetBSD__ if (setgroups(1, &pw->pw_gid) || setgid(pw->pw_gid) || setuid(pw->pw_uid)) { syslog(LOG_ERR, "can't revoke privs: %m"); exit(1); } #else if (setgroups(1, &pw->pw_gid) || setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) { syslog(LOG_ERR, "can't revoke privs: %m"); exit(1); } #endif /* !__NetBSD__ */ /* non-blocking io */ if (ioctl(fd, FIONBIO, &on) < 0) { syslog(LOG_ERR, "ioctl(FIONBIO): %m"); exit(1); } if (setsockopt(fd, IPPROTO_IP, IP_RECVDSTADDR, &on, sizeof(on)) == -1) { syslog(LOG_ERR, "setsockopt(IP_RECVDSTADDR): %m"); exit(1); } j = sizeof(s_in); if (getsockname(fd, (struct sockaddr *)&s_in, &j) == -1) { syslog(LOG_ERR, "getsockname: %m"); exit(1); } bindport = ((struct sockaddr_in *)&s_in)->sin_port; /* req will be pushed back out at the end, unchanged */ j = sizeof(from); if ((reqsize = recvfrom(fd, req, sizeof(req), MSG_PEEK, (struct sockaddr *)&from, &j)) < 0) { syslog(LOG_ERR, "recvfrom: %m"); exit(1); } bzero(&msg, sizeof(msg)); iov.iov_base = req; iov.iov_len = sizeof(req); msg.msg_name = &from; msg.msg_namelen = sizeof(from); msg.msg_iov = &iov; msg.msg_iovlen = 1; cbuflen = CMSG_SPACE(sizeof(struct sockaddr_storage)); if ((cbuf = malloc(cbuflen)) == NULL) { syslog(LOG_ERR, "malloc: %m"); exit(1); } msg.msg_control = cbuf; msg.msg_controllen = cbuflen; if (recvmsg(fd, &msg, 0) < 0) { syslog(LOG_ERR, "recvmsg: %m"); exit(1); } close(fd); close(1); peer = socket(from.ss_family, SOCK_DGRAM, 0); if (peer < 0) { syslog(LOG_ERR, "socket: %m"); exit(1); } memset(&s_in, 0, sizeof(s_in)); s_in.ss_family = from.ss_family; s_in.ss_len = from.ss_len; /* get local address if possible */ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) { if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_RECVDSTADDR) { memcpy(&((struct sockaddr_in *)&s_in)->sin_addr, CMSG_DATA(cmsg), sizeof(struct in_addr)); break; } } if (bind(peer, (struct sockaddr *)&s_in, s_in.ss_len) < 0) { syslog(LOG_ERR, "bind: %m"); exit(1); } if (connect(peer, (struct sockaddr *)&from, from.ss_len) < 0) { syslog(LOG_ERR, "connect: %m"); exit(1); } tp = (struct tftphdr *)req; if (!(ntohs(tp->th_opcode) == RRQ || ntohs(tp->th_opcode) == WRQ)) { /* not a tftp request, bail */ if (verbose) { syslog(LOG_WARNING, "not a valid tftp request"); exit(1); } else /* exit 0 so inetd doesn't log anything */ exit(0); } j = sizeof(struct sockaddr_storage); if (getsockname(fd, (struct sockaddr *)&proxy, &j) == -1) { syslog(LOG_ERR, "getsockname: %m"); exit(1); } ((struct sockaddr_in *)&proxy)->sin_port = bindport; /* find the un-rdr'd server and port the client wanted */ if (server_lookup((struct sockaddr *)&from, (struct sockaddr *)&proxy, (struct sockaddr *)&server, IPPROTO_UDP) != 0) { syslog(LOG_ERR, "pf connection lookup failed (no rdr?)"); exit(1); } /* establish a new outbound connection to the remote server */ if ((out_fd = socket(((struct sockaddr *)&from)->sa_family, SOCK_DGRAM, IPPROTO_UDP)) < 0) { syslog(LOG_ERR, "couldn't create new socket"); exit(1); } bzero((char *)&sock_out, sizeof(sock_out)); sock_out.sin_family = from.ss_family; sock_out.sin_port = htons(pick_proxy_port()); if (bind(out_fd, (struct sockaddr *)&sock_out, sizeof(sock_out)) < 0) { syslog(LOG_ERR, "couldn't bind to new socket: %m"); exit(1); } if (connect(out_fd, (struct sockaddr *)&server, ((struct sockaddr *)&server)->sa_len) < 0 && errno != EINPROGRESS) { syslog(LOG_ERR, "couldn't connect to remote server: %m"); exit(1); } j = sizeof(struct sockaddr_storage); if ((getsockname(out_fd, (struct sockaddr *)&proxy_to_server, &j)) < 0) { syslog(LOG_ERR, "getsockname: %m"); exit(1); } if (verbose) syslog(LOG_INFO, "%s:%d -> %s:%d/%s:%d -> %s:%d \"%s %s\"", sock_ntop((struct sockaddr *)&from), ntohs(((struct sockaddr_in *)&from)->sin_port), sock_ntop((struct sockaddr *)&proxy), ntohs(((struct sockaddr_in *)&proxy)->sin_port), sock_ntop((struct sockaddr *)&proxy_to_server), ntohs(((struct sockaddr_in *)&proxy_to_server)->sin_port), sock_ntop((struct sockaddr *)&server), ntohs(((struct sockaddr_in *)&server)->sin_port), opcode(ntohs(tp->th_opcode)), tp->th_stuff); /* get ready to add rdr and pass rules */ if (prepare_commit(1) == -1) { syslog(LOG_ERR, "couldn't prepare pf commit"); exit(1); } /* rdr from server to us on our random port -> client on its port */ if (add_rdr(1, (struct sockaddr *)&server, (struct sockaddr *)&proxy_to_server, ntohs(sock_out.sin_port), (struct sockaddr *)&from, ntohs(((struct sockaddr_in *)&from)->sin_port), IPPROTO_UDP) == -1) { syslog(LOG_ERR, "couldn't add rdr"); exit(1); } /* explicitly allow the packets to return back to the client (which pf * will see post-rdr) */ if (add_filter(1, PF_IN, (struct sockaddr *)&server, (struct sockaddr *)&from, ntohs(((struct sockaddr_in *)&from)->sin_port), IPPROTO_UDP) == -1) { syslog(LOG_ERR, "couldn't add pass in"); exit(1); } if (add_filter(1, PF_OUT, (struct sockaddr *)&server, (struct sockaddr *)&from, ntohs(((struct sockaddr_in *)&from)->sin_port), IPPROTO_UDP) == -1) { syslog(LOG_ERR, "couldn't add pass out"); exit(1); } /* and just in case, to pass out from us to the server */ if (add_filter(1, PF_OUT, (struct sockaddr *)&proxy_to_server, (struct sockaddr *)&server, ntohs(((struct sockaddr_in *)&server)->sin_port), IPPROTO_UDP) == -1) { syslog(LOG_ERR, "couldn't add pass out"); exit(1); } if (do_commit() == -1) { syslog(LOG_ERR, "couldn't commit pf rules"); exit(1); } /* forward the initial tftp request and start the insanity */ if (send(out_fd, tp, reqsize, 0) < 0) { syslog(LOG_ERR, "couldn't forward tftp packet: %m"); exit(1); } /* allow the transfer to start to establish a state */ sleep(transwait); /* delete our rdr rule and clean up */ prepare_commit(1); do_commit(); return(0); }
void dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen) { int icmpfd, maxfdp1; char sendline[MAXLINE], recvline[MAXLINE + 1]; fd_set rset; ssize_t n; struct timeval tv; struct icmpd_err icmpd_err; struct sockaddr_un sun; if (sock_bind_wild(sockfd, pservaddr->sa_family) < 0) { perror("sock_bind_wild error"); exit(1); } if ((icmpfd = socket(AF_LOCAL, SOCK_STREAM, 0)) < 0) { perror("socket error"); exit(1); } sun.sun_family = AF_LOCAL; strcpy(sun.sun_path, ICMPD_PATH); if (connect(icmpfd, (SA *)&sun, sizeof(sun)) < 0) { perror("connect error"); exit(1); } if (write_fd(icmpfd, "1", 1, sockfd) < 0) { perror("write_fd error"); exit(1); } if ((n = read(icmpfd, recvline, 1)) == -1) { perror("read error"); exit(1); } if (n != 1 || recvline[0] != '1') { fprintf(stderr, "error creating icmp socket, n = %d, char = %c\n", n, recvline[0]); exit(1); } FD_ZERO(&rset); maxfdp1 = max(sockfd, icmpfd) + 1; /* end dgcli011 */ /* include dgcli012 */ while (fgets(sendline, MAXLINE, fp) != NULL) { n = strlen(sendline); if (sendto(sockfd, sendline, n, 0, pservaddr, servlen) != n) { perror("sendto error"); exit(1); } tv.tv_sec = 5; tv.tv_usec = 0; FD_SET(sockfd, &rset); FD_SET(icmpfd, &rset); if ( (n = select(maxfdp1, &rset, NULL, NULL, &tv)) < 0) { perror("select error"); exit(1); } else if (n == 0) { fprintf(stderr, "socket timeout\n"); continue; } if (FD_ISSET(sockfd, &rset)) { if ((n = recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL)) < 0) { perror("recvfrom error"); exit(1); } recvline[n] = 0; /* null terminate */ if (fputs(recvline, stdout) == EOF) { perror("fputs error"); exit(1); } } if (FD_ISSET(icmpfd, &rset)) { if ( (n = read(icmpfd, &icmpd_err, sizeof(icmpd_err))) < 0) { perror("read error"); exit(1); } else if (n == 0) { fprintf(stderr, "ICMP daemon terminated\n"); exit(1); } else if (n != sizeof(icmpd_err)) { fprintf(stderr, "n = %d, expected %d\n", n, sizeof(icmpd_err)); exit(1); } printf("ICMP error: dest = %s, %s, type = %d, code = %d\n", sock_ntop(&icmpd_err.icmpd_dest, icmpd_err.icmpd_len), strerror(icmpd_err.icmpd_errno), icmpd_err.icmpd_type, icmpd_err.icmpd_code); } } }
void handle_connection(const int listen_fd, short event, void *arg) { struct sockaddr_storage tmp_ss; struct sockaddr *client_sa, *server_sa, *fixed_server_sa; struct sockaddr *proxy_to_server_sa; struct session *s; socklen_t len; int client_fd, fc, on; event_add(&listen_ev, NULL); if ((event & EV_TIMEOUT)) /* accept() is no longer paused. */ return; /* * We _must_ accept the connection, otherwise libevent will keep * coming back, and we will chew up all CPU. */ client_sa = sstosa(&tmp_ss); len = sizeof(struct sockaddr_storage); if ((client_fd = accept(listen_fd, client_sa, &len)) < 0) { logmsg(LOG_CRIT, "accept() failed: %s", strerror(errno)); /* * Pause accept if we are out of file descriptors, or * libevent will haunt us here too. */ if (errno == ENFILE || errno == EMFILE) { struct timeval pause = { 1, 0 }; event_del(&listen_ev); evtimer_add(&pause_accept_ev, &pause); } else if (errno != EWOULDBLOCK && errno != EINTR && errno != ECONNABORTED) logmsg(LOG_CRIT, "accept() failed: %s", strerror(errno)); return; } /* Refuse connection if the maximum is reached. */ if (session_count >= max_sessions) { logmsg(LOG_ERR, "client limit (%d) reached, refusing " "connection from %s", max_sessions, sock_ntop(client_sa)); close(client_fd); return; } /* Allocate session and copy back the info from the accept(). */ s = init_session(); if (s == NULL) { logmsg(LOG_CRIT, "init_session failed"); close(client_fd); return; } s->client_fd = client_fd; memcpy(sstosa(&s->client_ss), client_sa, client_sa->sa_len); /* Cast it once, and be done with it. */ client_sa = sstosa(&s->client_ss); server_sa = sstosa(&s->server_ss); proxy_to_server_sa = sstosa(&s->proxy_ss); fixed_server_sa = sstosa(&fixed_server_ss); /* Log id/client early to ease debugging. */ logmsg(LOG_DEBUG, "#%d accepted connection from %s", s->id, sock_ntop(client_sa)); /* * Find out the real server and port that the client wanted. */ len = sizeof(struct sockaddr_storage); if (getsockname(s->client_fd, server_sa, &len) < 0) { logmsg(LOG_CRIT, "#%d getsockname failed: %s", s->id, strerror(errno)); goto fail; } len = sizeof(s->client_rd); if (getsockopt(s->client_fd, SOL_SOCKET, SO_RTABLE, &s->client_rd, &len) && errno != ENOPROTOOPT) { logmsg(LOG_CRIT, "#%d getsockopt failed: %s", s->id, strerror(errno)); goto fail; } if (fixed_server) { memcpy(sstosa(&s->orig_server_ss), server_sa, server_sa->sa_len); memcpy(server_sa, fixed_server_sa, fixed_server_sa->sa_len); } /* XXX: check we are not connecting to ourself. */ /* * Setup socket and connect to server. */ if ((s->server_fd = socket(server_sa->sa_family, SOCK_STREAM, IPPROTO_TCP)) < 0) { logmsg(LOG_CRIT, "#%d server socket failed: %s", s->id, strerror(errno)); goto fail; } if (fixed_proxy && bind(s->server_fd, sstosa(&fixed_proxy_ss), fixed_proxy_ss.ss_len) != 0) { logmsg(LOG_CRIT, "#%d cannot bind fixed proxy address: %s", s->id, strerror(errno)); goto fail; } /* Use non-blocking connect(), see CONNECT_TIMEOUT below. */ if ((fc = fcntl(s->server_fd, F_GETFL)) == -1 || fcntl(s->server_fd, F_SETFL, fc | O_NONBLOCK) == -1) { logmsg(LOG_CRIT, "#%d cannot mark socket non-blocking: %s", s->id, strerror(errno)); goto fail; } if (connect(s->server_fd, server_sa, server_sa->sa_len) < 0 && errno != EINPROGRESS) { logmsg(LOG_CRIT, "#%d proxy cannot connect to server %s: %s", s->id, sock_ntop(server_sa), strerror(errno)); goto fail; } len = sizeof(struct sockaddr_storage); if ((getsockname(s->server_fd, proxy_to_server_sa, &len)) < 0) { logmsg(LOG_CRIT, "#%d getsockname failed: %s", s->id, strerror(errno)); goto fail; } logmsg(LOG_INFO, "#%d FTP session %d/%d started: client %s to server " "%s via proxy %s", s->id, session_count, max_sessions, sock_ntop(client_sa), sock_ntop(server_sa), sock_ntop(proxy_to_server_sa)); /* Keepalive is nice, but don't care if it fails. */ on = 1; setsockopt(s->client_fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof on); setsockopt(s->server_fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof on); /* * Setup buffered events. */ s->client_bufev = bufferevent_new(s->client_fd, &client_read, NULL, &client_error, s); if (s->client_bufev == NULL) { logmsg(LOG_CRIT, "#%d bufferevent_new client failed", s->id); goto fail; } bufferevent_settimeout(s->client_bufev, timeout, 0); bufferevent_enable(s->client_bufev, EV_READ | EV_TIMEOUT); s->server_bufev = bufferevent_new(s->server_fd, &server_read, NULL, &server_error, s); if (s->server_bufev == NULL) { logmsg(LOG_CRIT, "#%d bufferevent_new server failed", s->id); goto fail; } bufferevent_settimeout(s->server_bufev, CONNECT_TIMEOUT, 0); bufferevent_enable(s->server_bufev, EV_READ | EV_TIMEOUT); return; fail: end_session(s); }