int rcmd_af(char **ahost, int rport, const char *locuser, const char *remuser, const char *cmd, int *fd2p, int af) { struct addrinfo hints, *res, *ai; struct sockaddr_storage from; fd_set reads; sigset_t oldmask, newmask; pid_t pid; int s, aport, lport, timo, error; char c, *p; int refused, nres; char num[8]; static char canonnamebuf[MAXDNAME]; /* is it proper here? */ /* call rcmdsh() with specified remote shell if appropriate. */ if (!issetugid() && (p = getenv("RSH"))) { struct servent *sp = getservbyname("shell", "tcp"); if (sp && sp->s_port == rport) return (rcmdsh(ahost, rport, locuser, remuser, cmd, p)); } /* use rsh(1) if non-root and remote port is shell. */ if (geteuid()) { struct servent *sp = getservbyname("shell", "tcp"); if (sp && sp->s_port == rport) return (rcmdsh(ahost, rport, locuser, remuser, cmd, NULL)); } pid = getpid(); memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_CANONNAME; hints.ai_family = af; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = 0; snprintf(num, sizeof(num), "%d", ntohs(rport)); error = getaddrinfo(*ahost, num, &hints, &res); if (error) { fprintf(stderr, "rcmd: getaddrinfo: %s\n", gai_strerror(error)); if (error == EAI_SYSTEM) fprintf(stderr, "rcmd: getaddrinfo: %s\n", strerror(errno)); return (-1); } if (res->ai_canonname && strlen(res->ai_canonname) + 1 < sizeof(canonnamebuf)) { strncpy(canonnamebuf, res->ai_canonname, sizeof(canonnamebuf)); *ahost = canonnamebuf; } nres = 0; for (ai = res; ai; ai = ai->ai_next) nres++; ai = res; refused = 0; sigemptyset(&newmask); sigaddset(&newmask, SIGURG); _sigprocmask(SIG_BLOCK, (const sigset_t *)&newmask, &oldmask); for (timo = 1, lport = IPPORT_RESERVED - 1;;) { s = rresvport_af(&lport, ai->ai_family); if (s < 0) { if (errno != EAGAIN && ai->ai_next) { ai = ai->ai_next; continue; } if (errno == EAGAIN) fprintf(stderr, "rcmd: socket: All ports in use\n"); else fprintf(stderr, "rcmd: socket: %s\n", strerror(errno)); freeaddrinfo(res); _sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask, NULL); return (-1); } _fcntl(s, F_SETOWN, pid); if (_connect(s, ai->ai_addr, ai->ai_addrlen) >= 0) break; _close(s); if (errno == EADDRINUSE) { lport--; continue; } if (errno == ECONNREFUSED) refused = 1; if (ai->ai_next == NULL && (!refused || timo > 16)) { fprintf(stderr, "%s: %s\n", *ahost, strerror(errno)); freeaddrinfo(res); _sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask, NULL); return (-1); } if (nres > 1) { int oerrno = errno; getnameinfo(ai->ai_addr, ai->ai_addrlen, paddr, sizeof(paddr), NULL, 0, NI_NUMERICHOST); fprintf(stderr, "connect to address %s: ", paddr); errno = oerrno; perror(0); } if ((ai = ai->ai_next) == NULL) { /* refused && timo <= 16 */ struct timespec time_to_sleep, time_remaining; time_to_sleep.tv_sec = timo; time_to_sleep.tv_nsec = 0; _nanosleep(&time_to_sleep, &time_remaining); timo *= 2; ai = res; refused = 0; } if (nres > 1) { getnameinfo(ai->ai_addr, ai->ai_addrlen, paddr, sizeof(paddr), NULL, 0, NI_NUMERICHOST); fprintf(stderr, "Trying %s...\n", paddr); } } lport--; if (fd2p == 0) { _write(s, "", 1); lport = 0; } else { int s2 = rresvport_af(&lport, ai->ai_family), s3; socklen_t len = ai->ai_addrlen; int nfds; if (s2 < 0) goto bad; _listen(s2, 1); snprintf(num, sizeof(num), "%d", lport); if (_write(s, num, strlen(num)+1) != strlen(num)+1) { fprintf(stderr, "rcmd: write (setting up stderr): %s\n", strerror(errno)); _close(s2); goto bad; } nfds = max(s, s2)+1; if(nfds > FD_SETSIZE) { fprintf(stderr, "rcmd: too many files\n"); _close(s2); goto bad; } again: FD_ZERO(&reads); FD_SET(s, &reads); FD_SET(s2, &reads); errno = 0; if (_select(nfds, &reads, 0, 0, 0) < 1 || !FD_ISSET(s2, &reads)){ if (errno != 0) fprintf(stderr, "rcmd: select (setting up stderr): %s\n", strerror(errno)); else fprintf(stderr, "select: protocol failure in circuit setup\n"); _close(s2); goto bad; } s3 = _accept(s2, (struct sockaddr *)&from, &len); switch (from.ss_family) { case AF_INET: aport = ntohs(((struct sockaddr_in *)&from)->sin_port); break; #ifdef INET6 case AF_INET6: aport = ntohs(((struct sockaddr_in6 *)&from)->sin6_port); break; #endif default: aport = 0; /* error */ break; } /* * XXX careful for ftp bounce attacks. If discovered, shut them * down and check for the real auxiliary channel to connect. */ if (aport == 20) { _close(s3); goto again; } _close(s2); if (s3 < 0) { fprintf(stderr, "rcmd: accept: %s\n", strerror(errno)); lport = 0; goto bad; } *fd2p = s3; if (aport >= IPPORT_RESERVED || aport < IPPORT_RESERVED / 2) { fprintf(stderr, "socket: protocol failure in circuit setup.\n"); goto bad2; } } _write(s, locuser, strlen(locuser)+1); _write(s, remuser, strlen(remuser)+1); _write(s, cmd, strlen(cmd)+1); if (_read(s, &c, 1) != 1) { fprintf(stderr, "rcmd: %s: %s\n", *ahost, strerror(errno)); goto bad2; } if (c != 0) { while (_read(s, &c, 1) == 1) { _write(STDERR_FILENO, &c, 1); if (c == '\n') break; } goto bad2; } _sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask, NULL); freeaddrinfo(res); return (s); bad2: if (lport) _close(*fd2p); bad: _close(s); _sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask, NULL); freeaddrinfo(res); return (-1); }
/* * Function: socket_connection * * Purpose: Opens the network connection with the mail host, without * doing any sort of I/O with it or anything. * * Arguments: * host The host to which to connect. * flags Option flags. * * Return value: A file descriptor indicating the connection, or -1 * indicating failure, in which case an error has been copied * into pop_error. */ static int socket_connection (char *host, int flags) { #ifdef HAVE_GETADDRINFO struct addrinfo *res, *it; struct addrinfo hints; int ret; #else /* !HAVE_GETADDRINFO */ struct hostent *hostent; #endif struct servent *servent; struct sockaddr_in addr; char found_port = 0; const char *service; int sock; char *realhost; #ifdef KERBEROS #ifdef KERBEROS5 krb5_error_code rem; krb5_context kcontext = 0; krb5_auth_context auth_context = 0; krb5_ccache ccdef; krb5_principal client, server; krb5_error *err_ret; register char *cp; #else KTEXT ticket; MSG_DAT msg_data; CREDENTIALS cred; Key_schedule schedule; int rem; #endif /* KERBEROS5 */ #endif /* KERBEROS */ int try_count = 0; int connect_ok; #ifdef WINDOWSNT { WSADATA winsockData; if (WSAStartup (0x101, &winsockData) == 0) have_winsock = 1; } #endif memset (&addr, 0, sizeof (addr)); addr.sin_family = AF_INET; /** "kpop" service is never used: look for 20060515 to see why **/ #ifdef KERBEROS service = (flags & POP_NO_KERBEROS) ? POP_SERVICE : KPOP_SERVICE; #else service = POP_SERVICE; #endif #ifdef HESIOD if (! (flags & POP_NO_HESIOD)) { servent = hes_getservbyname (service, "tcp"); if (servent) { addr.sin_port = servent->s_port; found_port = 1; } } #endif if (! found_port) { servent = getservbyname (service, "tcp"); if (servent) { addr.sin_port = servent->s_port; } else { /** "kpop" service is never used: look for 20060515 to see why **/ #ifdef KERBEROS addr.sin_port = htons ((flags & POP_NO_KERBEROS) ? POP_PORT : KPOP_PORT); #else addr.sin_port = htons (POP_PORT); #endif } } #define POP_SOCKET_ERROR "Could not create socket for POP connection: " sock = socket (PF_INET, SOCK_STREAM, 0); if (sock < 0) { snprintf (pop_error, ERROR_MAX, "%s%s", POP_SOCKET_ERROR, strerror (errno)); return (-1); } #ifdef HAVE_GETADDRINFO memset (&hints, 0, sizeof (hints)); hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_CANONNAME; hints.ai_family = AF_INET; do { ret = getaddrinfo (host, service, &hints, &res); try_count++; if (ret != 0 && (ret != EAI_AGAIN || try_count == 5)) { strcpy (pop_error, "Could not determine POP server's address"); return (-1); } } while (ret != 0); if (ret == 0) { it = res; while (it) { if (it->ai_addrlen == sizeof (addr)) { struct sockaddr_in *in_a = (struct sockaddr_in *) it->ai_addr; memcpy (&addr.sin_addr, &in_a->sin_addr, sizeof (addr.sin_addr)); if (! connect (sock, (struct sockaddr *) &addr, sizeof (addr))) break; } it = it->ai_next; } connect_ok = it != NULL; if (connect_ok) { realhost = alloca (strlen (it->ai_canonname) + 1); strcpy (realhost, it->ai_canonname); } freeaddrinfo (res); } #else /* !HAVE_GETADDRINFO */ do { hostent = gethostbyname (host); try_count++; if ((! hostent) && ((h_errno != TRY_AGAIN) || (try_count == 5))) { strcpy (pop_error, "Could not determine POP server's address"); return (-1); } } while (! hostent); while (*hostent->h_addr_list) { memcpy (&addr.sin_addr, *hostent->h_addr_list, hostent->h_length); if (! connect (sock, (struct sockaddr *) &addr, sizeof (addr))) break; hostent->h_addr_list++; } connect_ok = *hostent->h_addr_list != NULL; if (! connect_ok) { realhost = alloca (strlen (hostent->h_name) + 1); strcpy (realhost, hostent->h_name); } #endif /* !HAVE_GETADDRINFO */ #define CONNECT_ERROR "Could not connect to POP server: " if (! connect_ok) { CLOSESOCKET (sock); snprintf (pop_error, ERROR_MAX, "%s%s", CONNECT_ERROR, strerror (errno)); return (-1); } #ifdef KERBEROS #define KRB_ERROR "Kerberos error connecting to POP server: " if (! (flags & POP_NO_KERBEROS)) { #ifdef KERBEROS5 if ((rem = krb5_init_context (&kcontext))) { krb5error: if (auth_context) krb5_auth_con_free (kcontext, auth_context); if (kcontext) krb5_free_context (kcontext); snprintf (pop_error, ERROR_MAX, "%s%s", KRB_ERROR, error_message (rem)); CLOSESOCKET (sock); return (-1); } if ((rem = krb5_auth_con_init (kcontext, &auth_context))) goto krb5error; if (rem = krb5_cc_default (kcontext, &ccdef)) goto krb5error; if (rem = krb5_cc_get_principal (kcontext, ccdef, &client)) goto krb5error; for (cp = realhost; *cp; cp++) { if (isupper (*cp)) { *cp = tolower (*cp); } } if (rem = krb5_sname_to_principal (kcontext, realhost, POP_SERVICE, FALSE, &server)) goto krb5error; rem = krb5_sendauth (kcontext, &auth_context, (krb5_pointer) &sock, "KPOPV1.0", client, server, AP_OPTS_MUTUAL_REQUIRED, 0, /* no checksum */ 0, /* no creds, use ccache instead */ ccdef, &err_ret, 0, /* don't need subsession key */ 0); /* don't need reply */ krb5_free_principal (kcontext, server); if (rem) { int pop_error_len = snprintf (pop_error, ERROR_MAX, "%s%s", KRB_ERROR, error_message (rem)); #if defined HAVE_KRB5_ERROR_TEXT if (err_ret && err_ret->text.length) { int errlen = err_ret->text.length; snprintf (pop_error + pop_error_len, ERROR_MAX - pop_error_len, " [server says '.*%s']", errlen, err_ret->text.data); } #elif defined HAVE_KRB5_ERROR_E_TEXT if (err_ret && err_ret->e_text && **err_ret->e_text) snprintf (pop_error + pop_error_len, ERRMAX - pop_error_len, " [server says '%s']", *err_ret->e_text); #endif if (err_ret) krb5_free_error (kcontext, err_ret); krb5_auth_con_free (kcontext, auth_context); krb5_free_context (kcontext); CLOSESOCKET (sock); return (-1); } #else /* ! KERBEROS5 */ ticket = (KTEXT) malloc (sizeof (KTEXT_ST)); rem = krb_sendauth (0L, sock, ticket, "pop", realhost, (char *) krb_realmofhost (realhost), (unsigned long) 0, &msg_data, &cred, schedule, (struct sockaddr_in *) 0, (struct sockaddr_in *) 0, "KPOPV0.1"); free ((char *) ticket); if (rem != KSUCCESS) { snprintf (pop_error, ERROR_MAX, "%s%s", KRB_ERROR, krb_err_txt[rem]); CLOSESOCKET (sock); return (-1); } #endif /* KERBEROS5 */ } #endif /* KERBEROS */ return (sock); } /* socket_connection */
int main(int argc, char *argv[]) { size_t blc, bls, black, white; char *db_array[2], *buf, *name; struct blacklist *blists; struct servent *ent; int daemonize = 0, ch; while ((ch = getopt(argc, argv, "bdDn")) != -1) { switch (ch) { case 'n': dryrun = 1; break; case 'd': debug = 1; break; case 'b': greyonly = 0; break; case 'D': daemonize = 1; break; default: usage(); break; } } argc -= optind; argv += optind; if (argc != 0) usage(); if (daemonize) daemon(0, 0); if ((ent = getservbyname("spamd-cfg", "tcp")) == NULL) errx(1, "cannot find service \"spamd-cfg\" in /etc/services"); ent->s_port = ntohs(ent->s_port); db_array[0] = PATH_SPAMD_CONF; db_array[1] = NULL; if (cgetent(&buf, db_array, "all") != 0) err(1, "Can't find \"all\" in spamd config"); name = strsep(&buf, ": \t"); /* skip "all" at start */ blists = NULL; blc = bls = 0; while ((name = strsep(&buf, ": \t")) != NULL) { if (*name) { /* extract config in order specified in "all" tag */ if (blc == bls) { struct blacklist *tmp; bls += 32; tmp = realloc(blists, bls * sizeof(struct blacklist)); if (tmp == NULL) errx(1, "malloc failed"); blists = tmp; } if (blc == 0) black = white = 0; else { white = blc - 1; black = blc; } memset(&blists[black], 0, sizeof(struct blacklist)); black = getlist(db_array, name, &blists[white], &blists[black]); if (black && blc > 0) { /* collapse and free previous blacklist */ send_blacklist(&blists[blc - 1], ent->s_port); } blc += black; } } /* collapse and free last blacklist */ if (blc > 0) send_blacklist(&blists[blc - 1], ent->s_port); return (0); }
int server_mode (const char *pidfile, struct sockaddr_in *phis_addr) { int ctl_sock, fd; struct servent *sv; int port; static struct sockaddr_in server_addr; /* Our address. */ /* Become a daemon. */ #ifdef HAVE_DAEMON if (daemon(1,1) < 0) #endif { syslog (LOG_ERR, "failed to become a daemon"); return -1; } (void) signal (SIGCHLD, reapchild); /* Get port for ftp/tcp. */ sv = getservbyname ("ftp", "tcp"); port = (sv == NULL) ? DEFPORT : sv->s_port; /* Open socket, bind and start listen. */ ctl_sock = socket (AF_INET, SOCK_STREAM, 0); if (ctl_sock < 0) { syslog (LOG_ERR, "control socket: %m"); return -1; } /* Enable local address reuse. */ { int on = 1; if (setsockopt (ctl_sock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) syslog (LOG_ERR, "control setsockopt: %m"); } memset (&server_addr, 0, sizeof server_addr); server_addr.sin_family = AF_INET; server_addr.sin_port = htons (port); if (bind (ctl_sock, (struct sockaddr *)&server_addr, sizeof server_addr)) { syslog (LOG_ERR, "control bind: %m"); return -1; } if (listen (ctl_sock, 32) < 0) { syslog (LOG_ERR, "control listen: %m"); return -1; } /* Stash pid in pidfile. */ { FILE *pid_fp = fopen (pidfile, "w"); if (pid_fp == NULL) syslog (LOG_ERR, "can't open %s: %m", PATH_FTPDPID); else { fprintf (pid_fp, "%d\n", getpid()); fchmod (fileno(pid_fp), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); fclose (pid_fp); } } /* Loop forever accepting connection requests and forking off children to handle them. */ while (1) { int addrlen = sizeof (*phis_addr); fd = accept (ctl_sock, (struct sockaddr *)phis_addr, &addrlen); #ifdef HAVE_WORKING_FORK if (fork () == 0) /* child */ #else if (vfork () == 0) /* child */ #endif { (void) dup2 (fd, 0); (void) dup2 (fd, 1); close (ctl_sock); break; } close (fd); } #ifdef WITH_WRAP /* In the child. */ if (!check_host ((struct sockaddr *)phis_addr)) return -1; #endif return fd; }
int main(int argc, const char *argv[]) { struct sockaddr_in si; socklen_t socklen; struct servent *s; int sockfd, i; signal(SIGCHLD, SIG_IGN); printf("ftps v1.0\n"); printf("2015.03.29\n"); printf("author niulibing\n"); if((fp=fopen("/etc/ftp.conf", "r")) == NULL) { perror("fopen"); exit(1); } fgets(data, sizeof(data), fp); data[strlen(data)-1] = '\0'; chdir(data); if((sockfd=socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } if((s=getservbyname("ftp", "tcp")) == NULL) { printf("getservbyname fail\n"); exit(1); } si.sin_family = AF_INET; si.sin_port = s->s_port; si.sin_addr.s_addr = INADDR_ANY; if(bind(sockfd, (const struct sockaddr *)&si, sizeof(si)) == -1) { perror("bind"); exit(1); } if(listen(sockfd, 5) == -1) { perror("listen"); exit(1); } while(1) { socklen = sizeof(si); if((acceptfd=accept(sockfd, (struct sockaddr *)&si, &socklen)) == -1) { perror("accept"); exit(1); } if(fork() == 0) { close(sockfd); while(recv(acceptfd, data, sizeof(data), 0) > 0) { arg[0] = strtok(data, " "); for(i=1; arg[i-1]!=NULL; i++) { arg[i] = strtok(NULL, " "); } if(strcmp(arg[0], "list") == 0) { list(); break; } if(strcmp(arg[0], "get") == 0) { get(); break; } if(strcmp(arg[0], "put") == 0) { put(); break; } } close(acceptfd); exit(0); } close(acceptfd); } }
/* * FtpConnect - connect to remote server * * return 1 if connected, 0 if not */ GLOBALDEF int FtpConnect(const char *host, netbuf **nControl) { int sControl; struct sockaddr_in sin; struct hostent *phe; struct servent *pse; int on=1; netbuf *ctrl; char *lhost; char *pnum; memset(&sin,0,sizeof(sin)); sin.sin_family = AF_INET; lhost = _strdup(host); pnum = strchr(lhost,':'); if (pnum == NULL) { #if defined(VMS) sin.sin_port = htons(21); #else if ((pse = getservbyname("ftp","tcp")) == NULL) { perror("getservbyname"); return 0; } sin.sin_port = pse->s_port; #endif } else { *pnum++ = '\0'; if (isdigit(*pnum)) sin.sin_port = htons((short)atoi(pnum)); else { pse = getservbyname(pnum,"tcp"); sin.sin_port = pse->s_port; } } if ((sin.sin_addr.s_addr = inet_addr(lhost)) == -1) { if ((phe = gethostbyname(lhost)) == NULL) { perror("gethostbyname"); return 0; } memcpy((char *)&sin.sin_addr, phe->h_addr, phe->h_length); } free(lhost); sControl = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if (sControl == -1) { perror("socket"); return 0; } if (setsockopt(sControl,SOL_SOCKET,SO_REUSEADDR, SETSOCKOPT_OPTVAL_TYPE &on, sizeof(on)) == -1) { perror("setsockopt"); net_close(sControl); return 0; } if (connect(sControl, (struct sockaddr *)&sin, sizeof(sin)) == -1) { perror("connect"); net_close(sControl); return 0; } ctrl = calloc(1,sizeof(netbuf)); if (ctrl == NULL) { perror("calloc"); net_close(sControl); return 0; } ctrl->buf = malloc(FTPLIB_BUFSIZ); if (ctrl->buf == NULL) { perror("calloc"); net_close(sControl); free(ctrl); return 0; } ctrl->handle = sControl; ctrl->dir = FTPLIB_CONTROL; ctrl->ctrl = NULL; ctrl->cmode = FTPLIB_DEFMODE; ctrl->idlecb = NULL; ctrl->idletime.tv_sec = ctrl->idletime.tv_usec = 0; ctrl->idlearg = NULL; ctrl->xfered = 0; ctrl->xfered1 = 0; ctrl->cbbytes = 0; if (readresp('2', ctrl) == 0) { net_close(sControl); free(ctrl->buf); free(ctrl); return 0; } *nControl = ctrl; return 1; }
int clip_TCPCONNECT(ClipMachine *mp) { C_FILE *cf = NULL; struct sockaddr_in sin; long port = 0, timeout = 60000; /* maybe we should add _set_ for default timeout */ int arg = 0, sock = -1, ret = -1, i; int *err = _clip_fetch_item(mp, HASH_ferror); struct timeval tv; char *addr = _clip_parc(mp,1), *sport; *err=0; if (_clip_parinfo(mp,0) < 2 || _clip_parinfo(mp,1) != CHARACTER_t) { *err = EINVAL; goto err; } if (_clip_parinfo(mp,2) == NUMERIC_t) port = htons(_clip_parnl(mp,2)); else if ((sport = _clip_parc(mp,2)) != NULL) { struct servent *sp; if ((sp = getservbyname( (const char *) sport, "tcp")) != NULL) port = sp->s_port; else { for (i = 0; sport[i] >= '0' && sport[i] <= '9'; i++); if (sport[i] == '\0') port = htons(atol(sport)); } } if (port == 0) { *err = EINVAL; goto err; } if (_clip_parinfo(mp,3) == NUMERIC_t) timeout = _clip_parnl(mp,3); tv.tv_sec = timeout / 1000; tv.tv_usec = (timeout % 1000) * 1000; if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) goto err; /* #if !defined(linux) && !defined(SOLARIS_26_X86) setsockopt( sock, SOL_SOCKET, SO_SNDTIMEO, (void *)&tv, sizeof(tv) ); setsockopt( sock, SOL_SOCKET, SO_RCVTIMEO, (void *)&tv, sizeof(tv) ); #endif */ if ((arg = fcntl(sock, F_GETFL, 0)) == -1) goto err; fcntl(sock, F_SETFL, arg | O_NONBLOCK); sin.sin_family = AF_INET; sin.sin_port = port; tcp_host_addr(addr, &sin.sin_addr); if (sin.sin_addr.s_addr == INADDR_NONE) { *err = EFAULT; goto err; } if (connect( sock, (struct sockaddr *) &sin, sizeof(sin)) == -1 ) { fd_set set; #ifndef OS_MINGW if (errno != EINPROGRESS) goto err; #endif FD_ZERO(&set); FD_SET(sock, &set); do i = _clip_select( sock+1, NULL, &set, NULL, &tv ); while (i == -1 && errno == EINTR); if (i == -1) goto err; else if (i == 0) { #ifdef OS_MINGW *err = EAGAIN; #else *err = ETIMEDOUT; #endif } arg = 0; i = sizeof(arg); if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void *) &arg, (socklen_t *)(&i)) == -1) goto err; if (arg != 0) { *err = arg; goto err; } } #ifndef OS_MINGW if ((arg = fcntl(sock, F_GETFL, 0)) == -1) goto err; fcntl(sock, F_SETFL, arg | O_NONBLOCK); #endif cf = calloc(1, sizeof(C_FILE)); cf->fileno = sock; cf->f = NULL; cf->type = FT_SOCKET; cf->pid = -1; cf->timeout = timeout; cf->stat = 0; /* see FS_* flags */ ret = _clip_store_c_item(mp, cf, _C_ITEM_TYPE_FILE, destroy_c_file); err: if (ret == -1) { if (*err !=0 ) *err = errno; if (sock != -1) close(sock); } _clip_retni(mp, ret); return 0; }
static int rdate(const char *hostname, time_t *retval) { struct servent *sent; struct sockaddr_in saddr; int fd; unsigned char time_buf[4]; int nr, n_toread; assert(hostname); assert(retval); saddr.sin_family = AF_INET; if(!inet_aton(hostname, &saddr.sin_addr)) { struct hostent *hent; hent = gethostbyname(hostname); if(!hent) { fprintf(stderr, "%s: Unknown host %s: %s\n", program_invocation_short_name, hostname, hstrerror(h_errno)); return -1; } assert(hent->h_addrtype == AF_INET); memcpy(&saddr.sin_addr, hent->h_addr_list[0], hent->h_length); } if((sent = getservbyname("time", "tcp"))) saddr.sin_port = sent->s_port; else saddr.sin_port = htons(DEFAULT_PORT); fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(fd < 0) { fprintf(stderr, "%s: couldn't create socket: %s\n", program_invocation_short_name, strerror(errno)); return -1; } if(connect(fd, (struct sockaddr *)&saddr, sizeof(saddr))) { fprintf(stderr, "%s: couldn't connect to host %s: %s\n", program_invocation_short_name, hostname, strerror(errno)); close(fd); return -1; } for(n_toread = sizeof(time_buf), nr = 1; nr > 0 && n_toread > 0; n_toread -= nr) nr = read(fd, time_buf + sizeof(time_buf) - n_toread, n_toread); if(n_toread) { if(nr) fprintf(stderr, "%s: error in read: %s\n", program_invocation_short_name, strerror(errno)); else fprintf(stderr, "%s: got EOF from time server\n", program_invocation_short_name); close(fd); return -1; } /* See inetd's builtins.c for an explanation */ *retval = (time_t)(ntohl(*(uint32_t *)time_buf) - 2208988800UL); return 0; }
int mcpOpen(char *name) { char host[MAXHOSTNAMELEN], service[MAXHOSTNAMELEN]; char buf[1024]; char *cptr; int count, status; int sock_fd; struct hostent *hp; struct servent *sp; struct in_addr tmpaddr; int optval; struct sockaddr_in inet_a; // inet_addr is a function name #ifndef _WIN32 char path[MAXPATHLEN]; struct sockaddr_un unix_addr; size_t unix_addr_len; #endif //WIN32 #ifdef _WIN32 // make sure we are initialized extern struct { int initialized; } initializer; if (initializer.initialized == 0) return -1; #endif //WIN32 /* * Parse the name string. * * A. If there is a ':' then it is an internet socket connection. * 1. Parse the name into <host>:<service> format. * a. If host is empty, use "localhost". * b. Lookup service with getservbyname(). If found, use * that port value. If not found, attempt to convert * it to an integer and use that port value. * 2. Connect to <host>:<port>. If the connection fails, * attempt to connect to <host>:tcpmux then request <service> * from tcpmux. * B. Else the name is a unix domain socket name. * 1. If the first character is not '/', prepend '/tmp/' to the * name string. * 2. Connect to the socket name. */ cptr = strchr(name, ':'); if (cptr) { /* Copy the host name */ if (cptr == name) { strcpy(host, "localhost"); } else { strncpy(host, name, (cptr - name)); host[cptr-name] = '\0'; } /* Copy the service name */ strcpy(service, cptr + 1); /* Initialize the inet_a struct */ bzero((char *) &inet_a, sizeof(inet_a)); inet_a.sin_family = AF_INET; /* Attempt to convert the host address as a dotted decimal number */ #ifdef _WIN32 tmpaddr.s_addr = inet_addr(host); status = (tmpaddr.s_addr != INADDR_NONE) ? 1 : 0; #else status = inet_aton(host, &tmpaddr); #endif //WIN32 if (status == 1) { bcopy((char *) &tmpaddr, (char *) &inet_a.sin_addr, sizeof(tmpaddr)); } else { /* Now find the host */ hp = gethostbyname(host); if (!hp) { /* We could not find the host */ errno = ENOENT; return -1; } bcopy(hp->h_addr, (char *) &inet_a.sin_addr, hp->h_length); } /* Attempt to decode the service parameter */ sp = getservbyname(service, "tcp"); if (sp) { inet_a.sin_port = sp->s_port; } else { /* Attempt to convert the service name as an integer */ inet_a.sin_port = htons((unsigned short)atoi(service)); } /* Create the socket */ sock_fd = socket(AF_INET, SOCK_STREAM, 0); if (sock_fd < 0) { return -1; } status = connect(sock_fd, (struct sockaddr *) &inet_a, sizeof(inet_a)); if (status < 0) { int status2; /* * The connection failed, try connecting to the tcpmux service. * tcpmux is at the well known port 1 so I just hardcoded it. */ inet_a.sin_port = htons(1); status = errno; status2 = connect(sock_fd, (struct sockaddr *) &inet_a, sizeof(inet_a)); if (status2 < 0) { closefd(sock_fd); errno = status; return -1; } /* * We connected to tcpmux, now send the service name and see if * tcpmux can give it to us. The tcpmux protocol works as follows: * * 1 Connect to the tcpmux port * 2 write the name of the service that you want followed by <CRLF>. * 3 read back the response terminated by <CRLF> * a If the first character is a '+' then we are connected. * b if the first character is a '-' then we are not connected. */ sprintf(buf, "%s\r\n", service); status = mcpWrite(sock_fd, buf, (unsigned int) strlen(buf)); if (status != (int)strlen(buf)) { status = errno; closefd(sock_fd); errno = status; return -1; } /* Read up through the <CRLF> pair */ /* There will be at least 3 characters coming back */ cptr = buf; count = 3; while (1) { status = mcpRead(sock_fd, cptr, count); if (status <= 0) { status = errno; closefd(sock_fd); errno = status; return -1; } cptr += status; if (cptr[-1] == '\n') { break; } else if (cptr[-1] == '\r') { count = 1; } else { count = 2; } } if (buf[0] != '+') { closefd(sock_fd); #ifdef _WIN32 errno = WSAECONNREFUSED; WSASetLastError (WSAECONNREFUSED); #else errno = ECONNREFUSED; #endif //WIN32 return -1; } } /* * We did it! We actually succeeded in connecting to the name * via internet sockets. Now make sure that we can send small * packets without delay. */ optval = 1; status = setsockopt(sock_fd, IPPROTO_TCP, TCP_NODELAY, (void *)&optval, sizeof(optval)); } else /* This must be a unix domain socket name */ { #ifndef _WIN32 // { /* Initialize the unix_addr struct */ bzero((char *) &unix_addr, sizeof(unix_addr)); unix_addr.sun_family = AF_UNIX; /* * If there is a leading '/' in the name name, it is an * absolute path name, otherwise, it is relative to /tmp. */ if (name[0] == '/') { strcpy(path, name); } else { sprintf(path, "/tmp/%s", name); } strcpy(unix_addr.sun_path, path); unix_addr_len = /*sizeof(unix_addr.sun_len) + */ sizeof(unix_addr.sun_family) + strlen(path); /* Create the socket */ sock_fd = socket(AF_UNIX, SOCK_STREAM, 0); if (sock_fd < 0) { return -1; } /* Connect to the name */ status = connect(sock_fd, (struct sockaddr *) &unix_addr, unix_addr_len); if (status < 0) { closefd(sock_fd); return -1; } /* * We did it! We actually succeeded in connecting to the name * via unix sockets. */ #else // } { HANDLE h; void* pmem; DWORD *mask, bit; struct sockmap* map; int i; h = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, MAYA_UNIX_SOCKET_SHARE_SIZE, MAYA_UNIX_SOCKET_SHARE_NAME); if (!h) return -1; if (GetLastError() != ERROR_ALREADY_EXISTS) { /* no "unix" handles exist */ CloseHandle(h); return -1; } pmem = MapViewOfFile(h, FILE_MAP_WRITE, 0, 0, 0); if (!pmem) { CloseHandle(h); return -1; } mask = (DWORD*)pmem; map = (struct sockmap*)((char*)pmem+sizeof(DWORD)); /* check if name is already here */ sock_fd = -1; for (bit = 1, i = 0; i < 32; ++i) { if (*mask & bit) { if (strcmp(map[i].unix_path, name) == 0) break; /* found */ } bit = bit << 1; } /* found */ if (i < 32) { /* Initialize the inet_a struct */ bzero((char *) &inet_a, sizeof(inet_a)); inet_a.sin_family = AF_INET; /* Now find the host */ hp = gethostbyname("localhost"); if (!hp) errno = ENOENT; else { bcopy(hp->h_addr, (char *) &inet_a.sin_addr, hp->h_length); inet_a.sin_port = map[i].port; /* Create the socket */ sock_fd = socket(AF_INET, SOCK_STREAM, 0); if (sock_fd >= 0) { status = connect(sock_fd, (struct sockaddr*)&inet_a, sizeof(inet_a)); if (status < 0) { closefd(sock_fd); sock_fd = -1; errno = status; } else { optval = 1; status = setsockopt(sock_fd, IPPROTO_TCP, TCP_NODELAY, (char*)&optval, sizeof(optval)); } } } } UnmapViewOfFile(pmem); CloseHandle(h); #endif //WIN32 } } /* Ok, we are connected. Return the socket descriptor */ return sock_fd; }
/*- * BIO_lookup - look up the node and service you want to connect to. * @node: the node you want to connect to. * @service: the service you want to connect to. * @lookup_type: declare intent with the result, client or server. * @family: the address family you want to use. Use AF_UNSPEC for any, or * AF_INET, AF_INET6 or AF_UNIX. * @socktype: The socket type you want to use. Can be SOCK_STREAM, SOCK_DGRAM * or 0 for all. * @res: Storage place for the resulting list of returned addresses * * This will do a lookup of the node and service that you want to connect to. * It returns a linked list of different addresses you can try to connect to. * * When no longer needed you should call BIO_ADDRINFO_free() to free the result. * * The return value is 1 on success or 0 in case of error. */ int BIO_lookup(const char *host, const char *service, enum BIO_lookup_type lookup_type, int family, int socktype, BIO_ADDRINFO **res) { int ret = 0; /* Assume failure */ switch(family) { case AF_INET: #ifdef AF_INET6 case AF_INET6: #endif #ifdef AF_UNIX case AF_UNIX: #endif #ifdef AF_UNSPEC case AF_UNSPEC: #endif break; default: BIOerr(BIO_F_BIO_LOOKUP, BIO_R_UNSUPPORTED_PROTOCOL_FAMILY); return 0; } #ifdef AF_UNIX if (family == AF_UNIX) { if (addrinfo_wrap(family, socktype, host, strlen(host), 0, res)) return 1; else BIOerr(BIO_F_BIO_LOOKUP, ERR_R_MALLOC_FAILURE); return 0; } #endif if (BIO_sock_init() != 1) return 0; if (1) { #ifdef AI_PASSIVE int gai_ret = 0; struct addrinfo hints; memset(&hints, 0, sizeof hints); hints.ai_family = family; hints.ai_socktype = socktype; if (lookup_type == BIO_LOOKUP_SERVER) hints.ai_flags |= AI_PASSIVE; /* Note that |res| SHOULD be a 'struct addrinfo **' thanks to * macro magic in bio_lcl.h */ switch ((gai_ret = getaddrinfo(host, service, &hints, res))) { # ifdef EAI_SYSTEM case EAI_SYSTEM: SYSerr(SYS_F_GETADDRINFO, get_last_socket_error()); BIOerr(BIO_F_BIO_LOOKUP, ERR_R_SYS_LIB); break; # endif case 0: ret = 1; /* Success */ break; default: BIOerr(BIO_F_BIO_LOOKUP, ERR_R_SYS_LIB); ERR_add_error_data(1, gai_strerror(gai_ret)); break; } } else { #endif const struct hostent *he; /* * Because struct hostent is defined for 32-bit pointers only with * VMS C, we need to make sure that '&he_fallback_address' and * '&he_fallback_addresses' are 32-bit pointers */ #if defined(OPENSSL_SYS_VMS) && defined(__DECC) # pragma pointer_size save # pragma pointer_size 32 #endif /* Windows doesn't seem to have in_addr_t */ #ifdef OPENSSL_SYS_WINDOWS static uint32_t he_fallback_address; static const char *he_fallback_addresses[] = { (char *)&he_fallback_address, NULL }; #else static in_addr_t he_fallback_address; static const char *he_fallback_addresses[] = { (char *)&he_fallback_address, NULL }; #endif static const struct hostent he_fallback = { NULL, NULL, AF_INET, sizeof(he_fallback_address), (char **)&he_fallback_addresses }; #if defined(OPENSSL_SYS_VMS) && defined(__DECC) # pragma pointer_size restore #endif struct servent *se; /* Apparently, on WIN64, s_proto and s_port have traded places... */ #ifdef _WIN64 struct servent se_fallback = { NULL, NULL, NULL, 0 }; #else struct servent se_fallback = { NULL, NULL, 0, NULL }; #endif if (!RUN_ONCE(&bio_lookup_init, do_bio_lookup_init)) { BIOerr(BIO_F_BIO_LOOKUP, ERR_R_MALLOC_FAILURE); ret = 0; goto err; } CRYPTO_THREAD_write_lock(bio_lookup_lock); he_fallback_address = INADDR_ANY; if (host == NULL) { he = &he_fallback; switch(lookup_type) { case BIO_LOOKUP_CLIENT: he_fallback_address = INADDR_LOOPBACK; break; case BIO_LOOKUP_SERVER: he_fallback_address = INADDR_ANY; break; default: OPENSSL_assert(("We forgot to handle a lookup type!" == 0)); break; } } else { he = gethostbyname(host); if (he == NULL) { #ifndef OPENSSL_SYS_WINDOWS /* * This might be misleading, because h_errno is used as if * it was errno. To minimize mixup add 1000. Underlying * reason for this is that hstrerror is declared obsolete, * not to mention that a) h_errno is not always guaranteed * to be meaningless; b) hstrerror can reside in yet another * library, linking for sake of hstrerror is an overkill; * c) this path is not executed on contemporary systems * anyway [above getaddrinfo/gai_strerror is]. We just let * system administrator figure this out... */ SYSerr(SYS_F_GETHOSTBYNAME, 1000 + h_errno); #else SYSerr(SYS_F_GETHOSTBYNAME, WSAGetLastError()); #endif ret = 0; goto err; } } if (service == NULL) { se_fallback.s_port = 0; se_fallback.s_proto = NULL; se = &se_fallback; } else { char *endp = NULL; long portnum = strtol(service, &endp, 10); /* * Because struct servent is defined for 32-bit pointers only with * VMS C, we need to make sure that 'proto' is a 32-bit pointer. */ #if defined(OPENSSL_SYS_VMS) && defined(__DECC) # pragma pointer_size save # pragma pointer_size 32 #endif char *proto = NULL; #if defined(OPENSSL_SYS_VMS) && defined(__DECC) # pragma pointer_size restore #endif switch (socktype) { case SOCK_STREAM: proto = "tcp"; break; case SOCK_DGRAM: proto = "udp"; break; } if (endp != service && *endp == '\0' && portnum > 0 && portnum < 65536) { se_fallback.s_port = htons(portnum); se_fallback.s_proto = proto; se = &se_fallback; } else if (endp == service) { se = getservbyname(service, proto); if (se == NULL) { #ifndef OPENSSL_SYS_WINDOWS SYSerr(SYS_F_GETSERVBYNAME, errno); #else SYSerr(SYS_F_GETSERVBYNAME, WSAGetLastError()); #endif goto err; } } else { BIOerr(BIO_F_BIO_LOOKUP, BIO_R_MALFORMED_HOST_OR_SERVICE); goto err; } } *res = NULL; { /* * Because hostent::h_addr_list is an array of 32-bit pointers with VMS C, * we must make sure our iterator designates the same element type, hence * the pointer size dance. */ #if defined(OPENSSL_SYS_VMS) && defined(__DECC) # pragma pointer_size save # pragma pointer_size 32 #endif char **addrlistp; #if defined(OPENSSL_SYS_VMS) && defined(__DECC) # pragma pointer_size restore #endif size_t addresses; BIO_ADDRINFO *tmp_bai = NULL; /* The easiest way to create a linked list from an array is to start from the back */ for(addrlistp = he->h_addr_list; *addrlistp != NULL; addrlistp++) ; for(addresses = addrlistp - he->h_addr_list; addrlistp--, addresses-- > 0; ) { if (!addrinfo_wrap(he->h_addrtype, socktype, *addrlistp, he->h_length, se->s_port, &tmp_bai)) goto addrinfo_malloc_err; tmp_bai->bai_next = *res; *res = tmp_bai; continue; addrinfo_malloc_err: BIO_ADDRINFO_free(*res); *res = NULL; BIOerr(BIO_F_BIO_LOOKUP, ERR_R_MALLOC_FAILURE); ret = 0; goto err; } ret = 1; } err: CRYPTO_THREAD_unlock(bio_lookup_lock); } return ret; }
/* * The timedaemons synchronize the clocks of hosts in a local area network. * One daemon runs as master, all the others as slaves. The master * performs the task of computing clock differences and sends correction * values to the slaves. * Slaves start an election to choose a new master when the latter disappears * because of a machine crash, network partition, or when killed. * A resolution protocol is used to kill all but one of the masters * that happen to exist in segments of a partitioned network when the * network partition is fixed. * * Authors: Riccardo Gusella & Stefano Zatti * * overhauled at Silicon Graphics */ int main(int argc, char *argv[]) { int on; int ret; int nflag, iflag; struct timeval ntime; struct servent *srvp; char buf[BUFSIZ], *cp, *cplim; struct ifconf ifc; struct ifreq ifreq, ifreqf, *ifr; register struct netinfo *ntp; struct netinfo *ntip; struct netinfo *savefromnet; struct netent *nentp; struct nets *nt; struct sockaddr_in server; u_short port; int c; #ifdef lint ntip = NULL; #endif on = 1; nflag = OFF; iflag = OFF; opterr = 0; while ((c = getopt(argc, argv, "Mtdn:i:F:G:P:")) != -1) { switch (c) { case 'M': Mflag = 1; break; case 't': trace = 1; break; case 'n': if (iflag) { errx(1, "-i and -n make no sense together"); } else { nflag = ON; addnetname(optarg); } break; case 'i': if (nflag) { errx(1, "-i and -n make no sense together"); } else { iflag = ON; addnetname(optarg); } break; case 'F': add_good_host(optarg,1); while (optind < argc && argv[optind][0] != '-') add_good_host(argv[optind++], 1); break; case 'd': debug = 1; break; case 'G': if (goodgroup != NULL) errx(1, "only one net group"); goodgroup = optarg; break; default: usage(); break; } } if (optind < argc) usage(); /* If we care about which machine is the master, then we must * be willing to be a master */ if (goodgroup != NULL || goodhosts != NULL) Mflag = 1; if (gethostname(hostname, sizeof(hostname) - 1) < 0) err(1, "gethostname"); self.l_bak = &self; self.l_fwd = &self; self.h_bak = &self; self.h_fwd = &self; self.head = 1; self.good = 1; if (goodhosts != NULL) /* trust ourself */ add_good_host(hostname,1); srvp = getservbyname("timed", "udp"); if (srvp == NULL) errx(1, "timed/udp: unknown service"); port = srvp->s_port; bzero(&server, sizeof(struct sockaddr_in)); server.sin_port = srvp->s_port; server.sin_family = AF_INET; sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) err(1, "socket"); if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&on, sizeof(on)) < 0) err(1, "setsockopt"); if (bind(sock, (struct sockaddr*)&server, sizeof(server))) { if (errno == EADDRINUSE) warnx("time daemon already running"); else warn("bind"); exit(1); } sequence = arc4random(); /* initial seq number */ (void)gettimeofday(&ntime, NULL); /* rounds kernel variable time to multiple of 5 ms. */ ntime.tv_sec = 0; ntime.tv_usec = -((ntime.tv_usec/1000) % 5) * 1000; (void)adjtime(&ntime, (struct timeval *)0); for (nt = nets; nt; nt = nt->next) { nentp = getnetbyname(nt->name); if (nentp == NULL) { nt->net = inet_network(nt->name); if (nt->net != INADDR_NONE) nentp = getnetbyaddr(nt->net, AF_INET); } if (nentp != NULL) { nt->net = nentp->n_net; } else if (nt->net == INADDR_NONE) { errx(1, "unknown net %s", nt->name); } else if (nt->net == INADDR_ANY) { errx(1, "bad net %s", nt->name); } else { warnx("warning: %s unknown in /etc/networks", nt->name); } if (0 == (nt->net & 0xff000000)) nt->net <<= 8; if (0 == (nt->net & 0xff000000)) nt->net <<= 8; if (0 == (nt->net & 0xff000000)) nt->net <<= 8; } ifc.ifc_len = sizeof(buf); ifc.ifc_buf = buf; if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) err(1, "get interface configuration"); ntp = NULL; #define size(p) max((p).sa_len, sizeof(p)) cplim = buf + ifc.ifc_len; /*skip over if's with big ifr_addr's */ for (cp = buf; cp < cplim; cp += sizeof (ifr->ifr_name) + size(ifr->ifr_addr)) { ifr = (struct ifreq *)cp; if (ifr->ifr_addr.sa_family != AF_INET) continue; if (!ntp) ntp = (struct netinfo*)malloc(sizeof(struct netinfo)); bzero(ntp,sizeof(*ntp)); ntp->my_addr=((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr; ntp->status = NOMASTER; ifreq = *ifr; ifreqf = *ifr; if (ioctl(sock, SIOCGIFFLAGS, (char *)&ifreqf) < 0) { warn("get interface flags"); continue; } if ((ifreqf.ifr_flags & IFF_UP) == 0) continue; if ((ifreqf.ifr_flags & IFF_BROADCAST) == 0 && (ifreqf.ifr_flags & IFF_POINTOPOINT) == 0) { continue; } if (ioctl(sock, SIOCGIFNETMASK, (char *)&ifreq) < 0) { warn("get netmask"); continue; } ntp->mask = ((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr.s_addr; if (ifreqf.ifr_flags & IFF_BROADCAST) { if (ioctl(sock, SIOCGIFBRDADDR, (char *)&ifreq) < 0) { warn("get broadaddr"); continue; } ntp->dest_addr = *(struct sockaddr_in *)&ifreq.ifr_broadaddr; /* What if the broadcast address is all ones? * So we cannot just mask ntp->dest_addr. */ ntp->net = ntp->my_addr; ntp->net.s_addr &= ntp->mask; } else { if (ioctl(sock, SIOCGIFDSTADDR, (char *)&ifreq) < 0) { warn("get destaddr"); continue; } ntp->dest_addr = *(struct sockaddr_in *)&ifreq.ifr_dstaddr; ntp->net = ntp->dest_addr.sin_addr; } ntp->dest_addr.sin_port = port; for (nt = nets; nt; nt = nt->next) { if (ntp->net.s_addr == htonl(nt->net)) break; } if ((nflag && !nt) || (iflag && nt)) continue; ntp->next = NULL; if (nettab == NULL) { nettab = ntp; } else { ntip->next = ntp; } ntip = ntp; ntp = NULL; } if (ntp) (void) free((char *)ntp); if (nettab == NULL) errx(1, "no network usable"); /* microseconds to delay before responding to a broadcast */ delay1 = casual(1, 100*1000); /* election timer delay in secs. */ delay2 = casual(MINTOUT, MAXTOUT); if (!debug) daemon(debug, 0); if (trace) traceon(); openlog("timed", LOG_CONS|LOG_PID, LOG_DAEMON); /* * keep returning here */ ret = setjmp(jmpenv); savefromnet = fromnet; setstatus(); if (Mflag) { switch (ret) { case 0: checkignorednets(); pickslavenet(0); break; case 1: /* Just lost our master */ if (slavenet != NULL) slavenet->status = election(slavenet); if (!slavenet || slavenet->status == MASTER) { checkignorednets(); pickslavenet(0); } else { makeslave(slavenet); /* prune extras */ } break; case 2: /* Just been told to quit */ justquit = 1; pickslavenet(savefromnet); break; } setstatus(); if (!(status & MASTER) && sock_raw != -1) { /* sock_raw is not being used now */ (void)close(sock_raw); sock_raw = -1; } if (status == MASTER) master(); else slave(); } else { if (sock_raw != -1) { (void)close(sock_raw); sock_raw = -1; } if (ret) { /* we just lost our master or were told to quit */ justquit = 1; } for (ntp = nettab; ntp != NULL; ntp = ntp->next) { if (ntp->status == MASTER) { rmnetmachs(ntp); ntp->status = NOMASTER; } } checkignorednets(); pickslavenet(0); setstatus(); slave(); } /* NOTREACHED */ return(0); }
int krb4int_send_to_kdc_addr( KTEXT pkt, KTEXT rpkt, char *realm, struct sockaddr *addr, socklen_t *addrlen) { struct addrlist al = ADDRLIST_INIT; char lrealm[REALM_SZ]; krb5int_access internals; krb5_error_code retval; struct servent *sp; int krb_udp_port = 0; int krbsec_udp_port = 0; char krbhst[MAXHOSTNAMELEN]; char *scol; int i; int err; krb5_data message, reply; /* * If "realm" is non-null, use that, otherwise get the * local realm. */ if (realm) strncpy(lrealm, realm, sizeof(lrealm) - 1); else { if (krb_get_lrealm(lrealm, 1)) { DEB (("%s: can't get local realm\n", prog)); return SKDC_CANT; } } lrealm[sizeof(lrealm) - 1] = '\0'; DEB (("lrealm is %s\n", lrealm)); retval = krb5int_accessor(&internals, KRB5INT_ACCESS_VERSION); if (retval) return KFAILURE; /* The first time, decide what port to use for the KDC. */ if (cached_krb_udp_port == 0) { sp = getservbyname("kerberos","udp"); if (sp) cached_krb_udp_port = sp->s_port; else cached_krb_udp_port = htons(KERBEROS_PORT); /* kerberos/udp */ DEB (("cached_krb_udp_port is %d\n", cached_krb_udp_port)); } /* If kerberos/udp isn't 750, try using kerberos-sec/udp (or 750) as a fallback. */ if (cached_krbsec_udp_port == 0 && cached_krb_udp_port != htons(KERBEROS_PORT)) { sp = getservbyname("kerberos-sec","udp"); if (sp) cached_krbsec_udp_port = sp->s_port; else cached_krbsec_udp_port = htons(KERBEROS_PORT); /* kerberos/udp */ DEB (("cached_krbsec_udp_port is %d\n", cached_krbsec_udp_port)); } for (i = 1; krb_get_krbhst(krbhst, lrealm, i) == KSUCCESS; ++i) { #ifdef DEBUG if (krb_debug) { DEB (("Getting host entry for %s...",krbhst)); (void) fflush(stdout); } #endif if (0 != (scol = strchr(krbhst,':'))) { krb_udp_port = htons(atoi(scol+1)); *scol = 0; if (krb_udp_port == 0) { #ifdef DEBUG if (krb_debug) { DEB (("bad port number %s\n",scol+1)); (void) fflush(stdout); } #endif continue; } krbsec_udp_port = 0; } else { krb_udp_port = cached_krb_udp_port; krbsec_udp_port = cached_krbsec_udp_port; } err = internals.add_host_to_list(&al, krbhst, krb_udp_port, krbsec_udp_port, SOCK_DGRAM, PF_INET); if (err) { retval = SKDC_CANT; goto free_al; } } if (al.naddrs == 0) { DEB (("%s: can't find any Kerberos host.\n", prog)); retval = SKDC_CANT; } message.length = pkt->length; message.data = (char *)pkt->dat; /* XXX yuck */ retval = internals.sendto_udp(NULL, &message, &al, NULL, &reply, addr, addrlen, NULL, 0, NULL); DEB(("sendto_udp returns %d\n", retval)); free_al: internals.free_addrlist(&al); if (retval) return SKDC_CANT; DEB(("reply.length=%d\n", reply.length)); if (reply.length > sizeof(rpkt->dat)) retval = SKDC_CANT; rpkt->length = 0; if (!retval) { memcpy(rpkt->dat, reply.data, reply.length); rpkt->length = reply.length; } krb5_free_data_contents(NULL, &reply); return retval; }
/* * FtpConnect - connect to remote server * * return 1 if connected, 0 if not */ GLOBALDEF int FtpConnect(const char *host, netbuf **nControl) { int sControl, stat, flags, oldflags; struct sockaddr_in sin; struct hostent *phe; struct servent *pse; int on=1; netbuf *ctrl; char *lhost; char *pnum; struct timeval tv; fd_set wr; memset(&sin,0,sizeof(sin)); sin.sin_family = AF_INET; lhost = strdup(host); pnum = strchr(lhost,':'); if (pnum == NULL) { #if defined(VMS) || defined(ANDROID) sin.sin_port = htons(21); #else if ((pse = getservbyname("ftp","tcp")) == NULL) { perror("getservbyname"); return 0; } sin.sin_port = pse->s_port; #endif } else { *pnum++ = '\0'; if (isdigit(*pnum)) sin.sin_port = htons(atoi(pnum)); else { pse = getservbyname(pnum,"tcp"); sin.sin_port = pse->s_port; } } if ((sin.sin_addr.s_addr = inet_addr(lhost)) == -1) { if ((phe = gethostbyname(lhost)) == NULL) { perror("gethostbyname"); return 0; } memcpy((char *)&sin.sin_addr, phe->h_addr, phe->h_length); } free(lhost); sControl = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if (sControl == -1) { perror("socket"); return 0; } if ( setsockopt(sControl,SOL_SOCKET,SO_REUSEADDR, SETSOCKOPT_OPTVAL_TYPE &on, sizeof(on)) == -1) { perror("setsockopt"); net_close(sControl); return 0; } #if defined(_WIN32) if (connect(sControl, (struct sockaddr *)&sin, sizeof(sin)) == -1) { perror("connect"); net_close(sControl); return 0; } #else //set nonblocking for connection timeout flags = fcntl( sControl, F_GETFL,0); oldflags=flags; fcntl( sControl, F_SETFL, O_NONBLOCK|flags); stat=connect( sControl, (struct sockaddr *)&sin, sizeof(sin)); if (stat < 0) { if (errno != EWOULDBLOCK && errno != EINPROGRESS) { perror("connect"); net_close(sControl); return 0; } } FD_ZERO(&wr); FD_SET( sControl, &wr); tv.tv_sec = ACCEPT_TIMEOUT; tv.tv_usec = 0; stat = select(sControl+1, 0, &wr, 0, &tv); if (stat < 1) { // time out has expired, // or an error has ocurred perror("timeout"); net_close(sControl); return 0; } if (ftplib_debug > 1) printf("connected\n"); //set original flags fcntl( sControl, F_SETFL, oldflags); #endif ctrl = calloc(1,sizeof(netbuf)); if (ctrl == NULL) { perror("calloc"); net_close(sControl); return 0; } ctrl->buf = malloc(FTPLIB_BUFSIZ); if (ctrl->buf == NULL) { perror("calloc"); net_close(sControl); free(ctrl); return 0; } ctrl->handle = sControl; ctrl->dir = FTPLIB_CONTROL; ctrl->ctrl = NULL; ctrl->cmode = FTPLIB_DEFMODE; ctrl->idlecb = NULL; ctrl->writercb = NULL; ctrl->idletime.tv_sec = ctrl->idletime.tv_usec = 0; ctrl->idlearg = NULL; ctrl->writerarg = NULL; ctrl->xfered = 0; ctrl->xfered1 = 0; ctrl->cbbytes = 0; if (readresp('2', ctrl) == 0) { net_close(sControl); free(ctrl->buf); free(ctrl); return 0; } *nControl = ctrl; return 1; }
int main(int argc, char **argv) { int sockfd = 0; int n = 0; char recvline[MAXLINE + 1]; struct sockaddr_in servaddr; struct in_addr **pptr = NULL; // struct in_addr *inetaddrp[2]; // struct in_addr inetaddr; // struct hostent *hp = NULL; struct servent *sp = NULL; if ( argc != 3 ) { err_quit("usage: daytimetcpcli <hostname> <service>"); } if ( (hp = gethostbyname(argv[1])) == NULL ) { if (inet_aton(argv[1], &inetaddr) == 0) { err_quit("hostname error for %s: %s\n", argv[1], hstrerror(h_errno)); } else { inetaddrp[0] = &inetaddr; inetaddrp[1] = NULL; pptr = inetaddrp; //注意是有p的. } } else { pptr = (struct in_addr **) hp->h_addr_list; } //获得了相应服务的端口号什么的 if ( (sp = getservbyname(argv[2], "tcp")) == NULL ) { err_quit("getservbyname error for %s\n", argv[2]); } for ( ; *pptr != NULL; pptr++ ) { sockfd = my_socket(AF_INET, SOCK_STREAM, 0); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = sp->s_port; //帅 memcpy(&servaddr.sin_addr, *pptr, sizeof(struct in_addr)); printf("trying %s\n", my_sock_ntop((SA *) &servaddr, sizeof(servaddr))); if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) == 0) { break; //success } err_ret("connect error"); close(sockfd); } if (*pptr == NULL) //这里不是很懂 { err_quit("unable to connect"); } while ((n= my_read(sockfd, recvline, MAXLINE)) > 0) { recvline[n] = 0; my_fputs(recvline, stdout); } exit (0); }
TCPSTREAM *tcp_open (char *host,char *service,unsigned long port) { TCPSTREAM *stream = NIL; int i; int sock = -1; int ctr = 0; int silent = (port & NET_SILENT) ? T : NIL; int *ctrp = (port & NET_NOOPENTIMEOUT) ? NIL : &ctr; char *s; struct sockaddr_in sin; struct hostent *he; char hostname[MAILTMPLEN]; char tmp[MAILTMPLEN]; struct servent *sv = NIL; blocknotify_t bn = (blocknotify_t) mail_parameters (NIL,GET_BLOCKNOTIFY,NIL); void *data; port &= 0xffff; /* erase flags */ /* lookup service */ if (service && (sv = getservbyname (service,"tcp"))) port = ntohs (sin.sin_port = sv->s_port); /* copy port number in network format */ else sin.sin_port = htons (port); /* The domain literal form is used (rather than simply the dotted decimal as with other Amiga programs) because it has to be a valid "host name" in mailsystem terminology. */ /* look like domain literal? */ if (host[0] == '[' && host[(strlen (host))-1] == ']') { strcpy (hostname,host+1); /* yes, copy number part */ hostname[(strlen (hostname))-1] = '\0'; if ((sin.sin_addr.s_addr = inet_addr (hostname)) == -1) sprintf (tmp,"Bad format domain-literal: %.80s",host); else { sin.sin_family = AF_INET; /* family is always Internet */ strcpy (hostname,host); /* hostname is user's argument */ (*bn) (BLOCK_TCPOPEN,NIL); /* get an open socket for this system */ sock = tcp_socket_open (&sin,tmp,ctrp,hostname,port); (*bn) (BLOCK_NONE,NIL); } } else { /* lookup host name */ if (tcpdebug) { sprintf (tmp,"DNS resolution %.80s",host); mm_log (tmp,TCPDEBUG); } (*bn) (BLOCK_DNSLOOKUP,NIL);/* quell alarms */ data = (*bn) (BLOCK_SENSITIVE,NIL); if (!(he = gethostbyname (lcase (strcpy (hostname,host))))) sprintf (tmp,"No such host as %.80s",host); (*bn) (BLOCK_NONSENSITIVE,data); (*bn) (BLOCK_NONE,NIL); if (he) { /* DNS resolution won? */ if (tcpdebug) mm_log ("DNS resolution done",TCPDEBUG); /* copy address type */ sin.sin_family = he->h_addrtype; /* copy host name */ strcpy (hostname,he->h_name); #ifdef HOST_NOT_FOUND /* muliple addresses only on DNS systems */ for (sock = -1,i = 0; (sock < 0) && (s = he->h_addr_list[i]); i++) { if (i && !silent) mm_log (tmp,WARN); memcpy (&sin.sin_addr,s,he->h_length); (*bn) (BLOCK_TCPOPEN,NIL); sock = tcp_socket_open (&sin,tmp,ctrp,hostname,port); (*bn) (BLOCK_NONE,NIL); } #else /* the one true address then */ memcpy (&sin.sin_addr,he->h_addr,he->h_length); (*bn) (BLOCK_TCPOPEN,NIL); sock = tcp_socket_open (&sin,tmp,ctrp,hostname,port); (*bn) (BLOCK_NONE,NIL); #endif } } if (sock >= 0) { /* won */ stream = (TCPSTREAM *) memset (fs_get (sizeof (TCPSTREAM)),0, sizeof (TCPSTREAM)); stream->port = port; /* port number */ /* init sockets */ stream->tcpsi = stream->tcpso = sock; /* stash in the snuck-in byte */ if (stream->ictr = ctr) *(stream->iptr = stream->ibuf) = tmp[0]; /* copy official host name */ stream->host = cpystr (hostname); if (tcpdebug) mm_log ("Stream open and ready for read",TCPDEBUG); } else if (!silent) mm_log (tmp,ERROR); return stream; /* return success */ }
static void printer_host_callback(void *arg, int status, int timeouts, struct hostent *host) { struct printer_poll_args *pargs = (struct printer_poll_args *) arg; struct printer *printer = pargs->printer; int s = -1, lport = IPPORT_RESERVED - 1, flags; unsigned short port; struct servent *servent; struct sockaddr_in sin; if (status == ARES_EDESTRUCTION) { syslog(LOG_DEBUG, "printer_host_callback: printer %s hostname query " "halted for channel destruction", printer->name); free(pargs); return; } if (status != ARES_SUCCESS) { syslog(LOG_ERR, "printer_host_callback: printer %s can't resolve print " "server name: %s", printer->name, ares_strerror(status)); goto failure; } s = rresvport(&lport); if (s < 0) { syslog(LOG_ERR, "printer_host_callback: printer %s can't get reserved " "port", printer->name); goto failure; } /* Set s non-blocking so we can do a non-blocking connect. */ flags = fcntl(s, F_GETFL); fcntl(s, F_SETFL, flags | O_NONBLOCK); servent = getservbyname("printer", "tcp"); port = (servent) ? servent->s_port : htons(PRINTER_FALLBACK_PORT); memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; memcpy(&sin.sin_addr, host->h_addr, sizeof(sin.sin_addr)); sin.sin_port = port; if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) == -1 && errno != EINPROGRESS) { syslog(LOG_ERR, "printer_host_callback: printer %s can't connect to " "print server %s: %m", printer->name, host->h_name); goto failure; } /* Set up the request we want to send; the main loop will call * printer_handle_output() when the socket selects true for * writing. */ printer->s = s; printer->to_send = 1; sprintf(printer->buf, "\3%.*s\n", (int)(sizeof(printer->buf) - 3), printer->name); printer->buflen = strlen(printer->buf); printer->jobs_counted = 0; printer->up_so_far = 1; syslog(LOG_DEBUG, "printer_host_callback: printer %s queued %d-byte query", printer->name, printer->buflen); free(pargs); return; failure: if (s >= 0) close(s); printer->timer = timer_set_rel(60, printer_poll, pargs); return; }
TCPSTREAM *tcp_open (char *host,char *service,unsigned long port) { TCPSTREAM *stream = NIL; int i,family; SOCKET sock = INVALID_SOCKET; int silent = (port & NET_SILENT) ? T : NIL; char *s,*hostname,tmp[MAILTMPLEN]; void *adr,*next; size_t adrlen; struct servent *sv = NIL; blocknotify_t bn = (blocknotify_t) mail_parameters (NIL,GET_BLOCKNOTIFY,NIL); if (!wsa_initted++) { /* init Windows Sockets */ WSADATA wsock; if (i = (int) WSAStartup (WINSOCK_VERSION,&wsock)) { wsa_initted = 0; /* in case we try again */ sprintf (tmp,"Unable to start Windows Sockets (%d)",i); mm_log (tmp,ERROR); return NIL; } } port &= 0xffff; /* erase flags */ /* lookup service */ if (service && (sv = getservbyname (service,"tcp"))) port = ntohs (sv->s_port); /* The domain literal form is used (rather than simply the dotted decimal as with other Windows programs) because it has to be a valid "host name" in mailsystem terminology. */ /* look like domain literal? */ if (host[0] == '[' && host[(strlen (host))-1] == ']') { strcpy (tmp,host+1); /* yes, copy number part */ tmp[strlen (tmp)-1] = '\0'; if (adr = ip_stringtoaddr (tmp,&adrlen,&family)) { (*bn) (BLOCK_TCPOPEN,NIL); sock = tcp_socket_open (family,adr,adrlen,(unsigned short) port,tmp, hostname = host); (*bn) (BLOCK_NONE,NIL); fs_give ((void **) &adr); } else sprintf (tmp,"Bad format domain-literal: %.80s",host); } else { /* lookup host name */ if (tcpdebug) { sprintf (tmp,"DNS resolution %.80s",host); mm_log (tmp,TCPDEBUG); } (*bn) (BLOCK_DNSLOOKUP,NIL);/* look up name */ if (!(s = ip_nametoaddr (host,&adrlen,&family,&hostname,&next))) sprintf (tmp,"Host not found (#%d): %s",WSAGetLastError (),host); (*bn) (BLOCK_NONE,NIL); if (s) { /* DNS resolution won? */ if (tcpdebug) mm_log ("DNS resolution done",TCPDEBUG); wsa_sock_open++; /* prevent tcp_abort() from freeing in loop */ do { (*bn) (BLOCK_TCPOPEN,NIL); if (((sock = tcp_socket_open (family,s,adrlen,(unsigned short) port, tmp,hostname)) == INVALID_SOCKET) && (s = ip_nametoaddr (NIL,&adrlen,&family,&hostname,&next)) && !silent) mm_log (tmp,WARN); (*bn) (BLOCK_NONE,NIL); } while ((sock == INVALID_SOCKET) && s); wsa_sock_open--; /* undo protection */ } } if (sock == INVALID_SOCKET) { /* do possible cleanup action */ if (!silent) mm_log (tmp,ERROR); tcp_abort (&sock); } else { /* got a socket, create TCP/IP stream */ stream = (TCPSTREAM *) memset (fs_get (sizeof (TCPSTREAM)),0, sizeof (TCPSTREAM)); stream->port = port; /* port number */ /* init socket */ stream->tcpsi = stream->tcpso = sock; stream->ictr = 0; /* init input counter */ /* copy official host name */ stream->host = cpystr (hostname); if (tcpdebug) mm_log ("Stream open and ready for read",TCPDEBUG); } return stream; /* return success */ }
int getaddrinfo(char const *hostname, char const *servname, struct addrinfo const *hints, struct addrinfo **res) { struct addrinfo *cur, *prev = NULL; struct hostent *hp; struct hostent result; struct in_addr in; int i, socktype, proto; uint16_t port = 0; int error; char buffer[2048]; if (hints && hints->ai_family != PF_INET && hints->ai_family != PF_UNSPEC) return EAI_FAMILY; socktype = (hints && hints->ai_socktype) ? hints->ai_socktype : SOCK_STREAM; if (hints && hints->ai_protocol) proto = hints->ai_protocol; else { switch (socktype) { case SOCK_DGRAM: proto = IPPROTO_UDP; break; case SOCK_STREAM: proto = IPPROTO_TCP; break; default: proto = 0; break; } } if (servname) { if (isdigit((int)*servname)) port = htons(atoi(servname)); else { struct servent *se; char const *pe_proto; switch (socktype) { case SOCK_DGRAM: pe_proto = "udp"; break; case SOCK_STREAM: pe_proto = "tcp"; break; default: pe_proto = NULL; break; } if ((se = getservbyname(servname, pe_proto)) == NULL) return EAI_SERVICE; port = se->s_port; } } if (!hostname) { if (hints && hints->ai_flags & AI_PASSIVE) *res = malloc_ai(port, htonl(0x00000000), socktype, proto); else *res = malloc_ai(port, htonl(0x7f000001), socktype, proto); if (*res) return 0; else return EAI_MEMORY; } /* Numeric IP Address */ if (inet_aton(hostname, &in)) { *res = malloc_ai(port, in.s_addr, socktype, proto); if (*res) return 0; else return EAI_MEMORY; } if (hints && hints->ai_flags & AI_NUMERICHOST) return EAI_NONAME; /* DNS Lookup */ #ifdef GETHOSTBYNAMERSTYLE #if GETHOSTBYNAMERSTYLE == SYSVSTYLE hp = gethostbyname_r(hostname, &result, buffer, sizeof(buffer), &error); #elif GETHOSTBYNAMERSTYLE == GNUSTYLE if (gethostbyname_r(hostname, &result, buffer, sizeof(buffer), &hp, &error) != 0) { hp = NULL; } #else hp = gethostbyname_r(hostname, &result, buffer, sizeof(buffer), &error); #endif #else hp = gethostbyname_r(hostname, &result, buffer, sizeof(buffer), &error); #endif if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) { for (i = 0; hp->h_addr_list[i]; i++) { if ((cur = malloc_ai(port, ((struct in_addr *)hp->h_addr_list[i])->s_addr, socktype, proto)) == NULL) { if (*res) freeaddrinfo(*res); return EAI_MEMORY; } if (prev) prev->ai_next = cur; else *res = cur; prev = cur; } if (hints && hints->ai_flags & AI_CANONNAME && *res) { if (((*res)->ai_canonname = strdup(hp->h_name)) == NULL) { freeaddrinfo(*res); return EAI_MEMORY; } } return 0; } return EAI_NONAME; }
R_API int r_socket_port_by_name(const char *name) { struct servent *p = getservbyname (name, "tcp"); if (p && p->s_port) return ntohs (p->s_port); return r_num_get (NULL, name); }
int tcpopen(char *host,char *server) { int i,mflg=0; int s; struct sockaddr_in sa; struct hostent *hp=NULL; struct servent *sp; char addr[41],*cp; if((hp=gethostbyname(host))==NULL){ if(isdigit(*host)){ cp=host; i=0; while(cp&&*cp&&i<4){ addr[i]=strtol(cp,&cp,10); if(*cp=='.')cp++; i++; } if((hp=gethostbyaddr(addr,4,AF_INET))==NULL){ hp=(struct hostent *)malloc(sizeof(struct hostent)); if(!hp) { return MEMERR; } hp->h_name=strdup(host); hp->h_aliases=0; hp->h_addrtype=AF_INET; hp->h_length=4; hp->h_addr_list=(char **)malloc(sizeof(char *)*2); hp->h_addr_list[0]=(char *)malloc(sizeof(char *)*8); hp->h_addr_list[1]=0; memcpy(hp->h_addr,addr,4); mflg=1; } } else { ShowLog(1,"gethostbyname %s error",host); return(-2); } } if(!hp->h_addr) { if(mflg) {free(hp->h_name); free(hp->h_addr_list[0]); free(hp->h_addr_list); free(hp); } return FORMATERR; } bcopy((char *)hp->h_addr,(char *)&sa.sin_addr,hp->h_length); sa.sin_family=hp->h_addrtype; if(isdigit(server[0])){ sa.sin_port=htons((u_short)atol(server)); } else { if((sp=getservbyname(server,"tcp"))==NULL){ if(mflg) {free(hp->h_name); free(hp->h_addr_list[0]); free(hp->h_addr_list); free(hp); } ShowLog(1,"getsrvbyname %s error",server); return(-3); } sa.sin_port=(u_short)sp->s_port; } if((s=socket(hp->h_addrtype,SOCK_STREAM,0))<=0){ i=errno; if(mflg) {free(hp->h_name); free(hp->h_addr_list[0]); free(hp->h_addr_list); free(hp); } ShowLog(1,"tcpopen socket error %d,%s",errno,strerror(errno)); return -4; } if(mflg) {free(hp->h_name); free(hp->h_addr_list[0]); free(hp->h_addr_list); free(hp); } /* 如果要已经处于连接状态的soket在调用closesocket后强制关闭,不经历TIME_WAIT的过程: BOOL bDontLinger = FALSE; setsockopt(s,SOL_SOCKET,SO_DONTLINGER,(const char*)&bDontLinger,sizeof(BOOL)); for WINDOWS */ #ifdef LINUX i=1; setsockopt(s,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(i)); #endif if((int)connect(s,(struct sockaddr *)&sa,sizeof(sa))< 0){ ShowLog(1,"connect %s/%s error %d",host,server,errno); i=errno; close(s); s=-1; errno=i; } return(s); }
/* * A. Shawn Bandy * CECS 472 * Assignment 4 * 09/11/2012 */ #include <sys/types.h> /* u_long */ #include <netdb.h> /* getXbyY */ #include <netinet/in.h> /*htons*/ #include <stdio.h> /*printf*/ #include <string.h> /*memcpy*/ #include <arpa/inet.h> /*inet_ntoa*/ int main(int argc, char *argv[]) { struct hostent *hp; struct servent *sp, *sp2; struct in_addr addr; printf("--Info--\n"); if(argc == 5) { //ARGUMENT 1 hp = gethostbyname(argv[1]); if(hp) { memcpy(&addr, hp->h_addr, hp->h_length); printf("Hostname from %s: %s\n",argv[1],inet_ntoa(addr)); } else { printf("ERROR: gethostbyname failed on %s\n",argv[1]); } //ARGUMENT 2 sp = getservbyname(argv[2],"tcp"); if(sp) { printf("Port number from service name %s: %i\n",argv[2],ntohs(sp->s_port)); } else { printf("ERROR: getservicebyname failed on %s\n",argv[2]); } //ARGUMENT 3 sp2 = getservbyport(htons(atoi(argv[3])),"tcp"); if(sp2) { printf("Service name from port %s: %s\n",argv[3],sp2->s_name); } else { printf("ERROR: getservbyport failed on %s\n",argv[3]); } //ARGUMENT 4 if(inet_addr(argv[4]) != INADDR_NONE) { printf("Internet address of %s: %i\n",argv[4],inet_addr(argv[4])); } else { printf("ERROR: inet_addr failed on %s\n",argv[4]); } } else { printf("ERROR: Wrong number of arguments."); } printf("--/Info--\n"); /* struct hostent *hp, *hp2; struct in_addr addr; hp = gethostbyname("cheetah.cecs.csulb.edu"); printf("%s\n",hp->h_name); printf("%d\n",hp->h_length); memcpy(&addr, hp->h_addr, hp->h_length); printf("%x\n",ntohl(addr.s_addr)); printf("%s\n",inet_ntoa(addr)); hp2 = gethostbyaddr(&addr, 4, AF_INET); { struct servent *sp, *sp2; sp = getservbyname("telnet", "tcp"); printf("%s\n",sp->s_name); // telnet printf("%d\n",ntohs(sp->s_port)); // 23 printf("%s\n",sp->s_proto); // tcp sp2 = getservbyport(htons(23), "tcp"); */ return 0; };
int main(int argc, char **argv) { #ifdef __FreeBSD__ FILE *fpid = NULL; #endif int ch; struct passwd *pw; pcap_handler phandler = logpkt_handler; int syncfd = 0; struct servent *ent; char *sync_iface = NULL; char *sync_baddr = NULL; if ((ent = getservbyname("spamd-sync", "udp")) == NULL) errx(1, "Can't find service \"spamd-sync\" in /etc/services"); sync_port = ntohs(ent->s_port); #ifndef __FreeBSD__ while ((ch = getopt(argc, argv, "DIi:l:Y:")) != -1) { #else while ((ch = getopt(argc, argv, "DIi:l:Y:m:")) != -1) { #endif switch (ch) { case 'D': flag_debug = 1; break; case 'I': flag_inbound = 1; break; case 'i': networkif = optarg; break; case 'l': pflogif = optarg; break; case 'Y': if (sync_addhost(optarg, sync_port) != 0) sync_iface = optarg; syncsend++; break; #ifdef __FreeBSD__ case 'm': if (strcmp(optarg, "ipfw") == 0) use_pf=0; break; #endif default: usage(); /* NOTREACHED */ } } signal(SIGINT , sighandler_close); signal(SIGQUIT, sighandler_close); signal(SIGTERM, sighandler_close); logmsg(LOG_DEBUG, "Listening on %s for %s %s", pflogif, (networkif == NULL) ? "all interfaces." : networkif, (flag_inbound) ? "Inbound direction only." : ""); if (init_pcap() == -1) err(1, "couldn't initialize pcap"); if (syncsend) { syncfd = sync_init(sync_iface, sync_baddr, sync_port); if (syncfd == -1) err(1, "sync init"); } #ifdef __FreeBSD__ /* open the pid file just before switch the user */ fpid = fopen(pid_file, "w"); if (fpid == NULL) { syslog(LOG_ERR, "exiting (couldn't create pid file %s)", pid_file); err(1, "couldn't create pid file \"%s\"", pid_file); } #endif /* privdrop */ pw = getpwnam("_spamd"); if (pw == NULL) errx(1, "User '_spamd' not found! "); 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)) err(1, "failed to drop privs"); if (!flag_debug) { if (daemon(0, 0) == -1) err(1, "daemon"); tzset(); openlog_r("spamlogd", LOG_PID | LOG_NDELAY, LOG_DAEMON, &sdata); } #ifdef __FreeBSD__ /* after switch user and daemon write and close the pid file */ if (fpid) { fprintf(fpid, "%ld\n", (long) getpid()); if (fclose(fpid) == EOF) { syslog(LOG_ERR, "exiting (couldn't close pid file %s)", pid_file); exit (1); } } #endif pcap_loop(hpcap, -1, phandler, NULL); logmsg(LOG_NOTICE, "exiting"); if (!flag_debug) closelog_r(&sdata); exit(0); }
static void MailResult(const ExecConfig *config, const char *file) { #if defined __linux__ || defined __NetBSD__ || defined __FreeBSD__ || defined __OpenBSD__ time_t now = time(NULL); #endif Log(LOG_LEVEL_VERBOSE, "Mail result..."); { struct stat statbuf; if (stat(file, &statbuf) == -1) { return; } if (statbuf.st_size == 0) { unlink(file); Log(LOG_LEVEL_DEBUG, "Nothing to report in file '%s'", file); return; } } { char prev_file[CF_BUFSIZE]; snprintf(prev_file, CF_BUFSIZE - 1, "%s/outputs/previous", CFWORKDIR); MapName(prev_file); if (CompareResult(file, prev_file) == 0) { Log(LOG_LEVEL_VERBOSE, "Previous output is the same as current so do not mail it"); return; } } if ((strlen(config->mail_server) == 0) || (strlen(config->mail_to_address) == 0)) { /* Syslog should have done this */ Log(LOG_LEVEL_VERBOSE, "Empty mail server or address - skipping"); return; } if (config->mail_max_lines == 0) { Log(LOG_LEVEL_DEBUG, "Not mailing: EmailMaxLines was zero"); return; } Log(LOG_LEVEL_DEBUG, "Mailing results of '%s' to '%s'", file, config->mail_to_address); /* Check first for anomalies - for subject header */ FILE *fp = fopen(file, "r"); if (!fp) { Log(LOG_LEVEL_INFO, "Couldn't open file '%s'. (fopen: %s)", file, GetErrorStr()); return; } bool anomaly = false; char vbuff[CF_BUFSIZE]; while (!feof(fp)) { vbuff[0] = '\0'; if (fgets(vbuff, sizeof(vbuff), fp) == NULL) { break; } if (strstr(vbuff, "entropy")) { anomaly = true; break; } } fclose(fp); if ((fp = fopen(file, "r")) == NULL) { Log(LOG_LEVEL_INFO, "Couldn't open file '%s'. (fopen: %s)", file, GetErrorStr()); return; } struct hostent *hp = gethostbyname(config->mail_server); if (!hp) { Log(LOG_LEVEL_ERR, "While mailing agent output, unknown host '%s'. Make sure that fully qualified names can be looked up at your site.", config->mail_server); fclose(fp); return; } struct servent *server = getservbyname("smtp", "tcp"); if (!server) { Log(LOG_LEVEL_INFO, "Unable to lookup smtp service. (getservbyname: %s)", GetErrorStr()); fclose(fp); return; } struct sockaddr_in raddr; memset(&raddr, 0, sizeof(raddr)); raddr.sin_port = (unsigned int) server->s_port; raddr.sin_addr.s_addr = ((struct in_addr *) (hp->h_addr))->s_addr; raddr.sin_family = AF_INET; Log(LOG_LEVEL_DEBUG, "Connecting..."); int sd = socket(AF_INET, SOCK_STREAM, 0); if (sd == -1) { Log(LOG_LEVEL_INFO, "Couldn't open a socket. (socket: %s)", GetErrorStr()); fclose(fp); return; } if (connect(sd, (void *) &raddr, sizeof(raddr)) == -1) { Log(LOG_LEVEL_INFO, "Couldn't connect to host '%s'. (connect: %s)", config->mail_server, GetErrorStr()); fclose(fp); cf_closesocket(sd); return; } /* read greeting */ if (!Dialogue(sd, NULL)) { goto mail_err; } sprintf(vbuff, "HELO %s\r\n", config->fq_name); Log(LOG_LEVEL_DEBUG, "%s", vbuff); if (!Dialogue(sd, vbuff)) { goto mail_err; } if (strlen(config->mail_from_address) == 0) { sprintf(vbuff, "MAIL FROM: <cfengine@%s>\r\n", config->fq_name); Log(LOG_LEVEL_DEBUG, "%s", vbuff); } else { sprintf(vbuff, "MAIL FROM: <%s>\r\n", config->mail_from_address); Log(LOG_LEVEL_DEBUG, "%s", vbuff); } if (!Dialogue(sd, vbuff)) { goto mail_err; } sprintf(vbuff, "RCPT TO: <%s>\r\n", config->mail_to_address); Log(LOG_LEVEL_DEBUG, "%s", vbuff); if (!Dialogue(sd, vbuff)) { goto mail_err; } if (!Dialogue(sd, "DATA\r\n")) { goto mail_err; } char mailsubject_anomaly_prefix[8]; if (anomaly) { strcpy(mailsubject_anomaly_prefix, "**!! "); } else { mailsubject_anomaly_prefix[0] = '\0'; } if (SafeStringLength(config->mail_subject) == 0) { snprintf(vbuff, sizeof(vbuff), "Subject: %s[%s/%s]\r\n", mailsubject_anomaly_prefix, config->fq_name, config->ip_address); Log(LOG_LEVEL_DEBUG, "%s", vbuff); } else { snprintf(vbuff, sizeof(vbuff), "Subject: %s%s\r\n", mailsubject_anomaly_prefix, config->mail_subject); Log(LOG_LEVEL_DEBUG, "%s", vbuff); } send(sd, vbuff, strlen(vbuff), 0); /* send X-CFEngine SMTP header if mailsubject set */ if (SafeStringLength(config->mail_subject) > 0) { unsigned char digest[EVP_MAX_MD_SIZE + 1]; char buffer[EVP_MAX_MD_SIZE * 4]; char *existing_policy_server = ReadPolicyServerFile(GetWorkDir()); HashPubKey(PUBKEY, digest, CF_DEFAULT_DIGEST); snprintf(vbuff, sizeof(vbuff), "X-CFEngine: vfqhost=\"%s\";ip-addresses=\"%s\";policyhub=\"%s\";pkhash=\"%s\"\r\n", VFQNAME, config->ip_addresses, existing_policy_server, HashPrintSafe(CF_DEFAULT_DIGEST, true, digest, buffer)); send(sd, vbuff, strlen(vbuff), 0); free(existing_policy_server); } #if defined __linux__ || defined __NetBSD__ || defined __FreeBSD__ || defined __OpenBSD__ strftime(vbuff, CF_BUFSIZE, "Date: %a, %d %b %Y %H:%M:%S %z\r\n", localtime(&now)); send(sd, vbuff, strlen(vbuff), 0); #endif if (strlen(config->mail_from_address) == 0) { sprintf(vbuff, "From: cfengine@%s\r\n", config->fq_name); Log(LOG_LEVEL_DEBUG, "%s", vbuff); } else { sprintf(vbuff, "From: %s\r\n", config->mail_from_address); Log(LOG_LEVEL_DEBUG, "%s", vbuff); } send(sd, vbuff, strlen(vbuff), 0); sprintf(vbuff, "To: %s\r\n\r\n", config->mail_to_address); Log(LOG_LEVEL_DEBUG, "%s", vbuff); send(sd, vbuff, strlen(vbuff), 0); int count = 0; while (!feof(fp)) { vbuff[0] = '\0'; if (fgets(vbuff, sizeof(vbuff), fp) == NULL) { break; } Log(LOG_LEVEL_DEBUG, "%s", vbuff); if (strlen(vbuff) > 0) { vbuff[strlen(vbuff) - 1] = '\r'; strcat(vbuff, "\n"); count++; send(sd, vbuff, strlen(vbuff), 0); } if ((config->mail_max_lines != INF_LINES) && (count > config->mail_max_lines)) { sprintf(vbuff, "\r\n[Mail truncated by cfengine. File is at %s on %s]\r\n", file, config->fq_name); send(sd, vbuff, strlen(vbuff), 0); break; } } if (!Dialogue(sd, ".\r\n")) { Log(LOG_LEVEL_DEBUG, "mail_err\n"); goto mail_err; } Dialogue(sd, "QUIT\r\n"); Log(LOG_LEVEL_DEBUG, "Done sending mail"); fclose(fp); cf_closesocket(sd); return; mail_err: fclose(fp); cf_closesocket(sd); Log(LOG_LEVEL_INFO, "Cannot mail to %s.", config->mail_to_address); }
int main(int argc, char *argv[]) { struct sockaddr_in from; struct stat st; char path[64]; int on = 1; char *cp; struct sockaddr_in soin; uid_t unpriv_uid; gid_t unpriv_gid; if (getuid()) errx(1, "not super user"); run_as(&unpriv_uid, &unpriv_gid); argv++; argc--; while (argc > 0 && *argv[0] == '-') { if (strcmp(*argv, "-m") == 0) { if (argc > 1 && isdigit(*(argv + 1)[0])) { argv++, argc--; multicast_mode = SCOPED_MULTICAST; multicast_scope = atoi(*argv); if (multicast_scope > MAX_MULTICAST_SCOPE) errx(1, "ttl must not exceed %u", MAX_MULTICAST_SCOPE); } else multicast_mode = PER_INTERFACE_MULTICAST; } else if (strcmp(*argv, "-i") == 0) insecure_mode = 1; else if (strcmp(*argv, "-l") == 0) quiet_mode = 1; else if (strcmp(*argv, "-p") == 0) iff_flag = 0; else usage(); argv++, argc--; } if (argc > 0) usage(); #ifndef DEBUG daemon(1, 0); #endif (void) signal(SIGHUP, getboottime); openlog("rwhod", LOG_PID, LOG_DAEMON); sp = getservbyname("who", "udp"); if (sp == NULL) { syslog(LOG_ERR, "who/udp: unknown service"); exit(1); } if (chdir(_PATH_RWHODIR) < 0) { syslog(LOG_ERR, "%s: %m", _PATH_RWHODIR); exit(1); } /* * Establish host name as returned by system. */ if (gethostname(myname, sizeof(myname) - 1) < 0) { syslog(LOG_ERR, "gethostname: %m"); exit(1); } if ((cp = index(myname, '.')) != NULL) *cp = '\0'; strncpy(mywd.wd_hostname, myname, sizeof(mywd.wd_hostname) - 1); mywd.wd_hostname[sizeof(mywd.wd_hostname) - 1] = '\0'; #ifdef __APPLE__ utmpf = open(_PATH_UTMPX, O_RDONLY|O_CREAT, 0644); #else utmpf = open(_PATH_UTMP, O_RDONLY|O_CREAT, 0644); #endif if (utmpf < 0) { #ifdef __APPLE__ syslog(LOG_ERR, "%s: %m", _PATH_UTMPX); #else syslog(LOG_ERR, "%s: %m", _PATH_UTMP); #endif exit(1); } getboottime(0); if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { syslog(LOG_ERR, "socket: %m"); exit(1); } if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0) { syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m"); exit(1); } memset(&soin, 0, sizeof(soin)); soin.sin_len = sizeof(soin); soin.sin_family = AF_INET; soin.sin_port = sp->s_port; if (bind(s, (struct sockaddr *)&soin, sizeof(soin)) < 0) { syslog(LOG_ERR, "bind: %m"); exit(1); } setgid(unpriv_gid); setgroups(1, &unpriv_gid); /* XXX BOGUS groups[0] = egid */ setuid(unpriv_uid); if (!configure(s)) exit(1); if (!quiet_mode) { signal(SIGALRM, onalrm); onalrm(0); } for (;;) { struct whod wd; socklen_t len = sizeof(from); int cc, whod; time_t t; cc = recvfrom(s, (char *)&wd, sizeof(struct whod), 0, (struct sockaddr *)&from, &len); if (cc <= 0) { if (cc < 0 && errno != EINTR) syslog(LOG_WARNING, "recv: %m"); continue; } if (from.sin_port != sp->s_port && !insecure_mode) { syslog(LOG_WARNING, "%d: bad source port from %s", ntohs(from.sin_port), inet_ntoa(from.sin_addr)); continue; } if (cc < WHDRSIZE) { syslog(LOG_WARNING, "short packet from %s", inet_ntoa(from.sin_addr)); continue; } if (wd.wd_vers != WHODVERSION) continue; if (wd.wd_type != WHODTYPE_STATUS) continue; if (!verify(wd.wd_hostname, sizeof wd.wd_hostname)) { syslog(LOG_WARNING, "malformed host name from %s", inet_ntoa(from.sin_addr)); continue; } (void) snprintf(path, sizeof path, "whod.%s", wd.wd_hostname); /* * Rather than truncating and growing the file each time, * use ftruncate if size is less than previous size. */ whod = open(path, O_WRONLY | O_CREAT, 0644); if (whod < 0) { syslog(LOG_WARNING, "%s: %m", path); continue; } #if ENDIAN != BIG_ENDIAN { int i, n = (cc - WHDRSIZE)/sizeof(struct whoent); struct whoent *we; /* undo header byte swapping before writing to file */ wd.wd_sendtime = ntohl(wd.wd_sendtime); for (i = 0; i < 3; i++) wd.wd_loadav[i] = ntohl(wd.wd_loadav[i]); wd.wd_boottime = ntohl(wd.wd_boottime); we = wd.wd_we; for (i = 0; i < n; i++) { we->we_idle = ntohl(we->we_idle); we->we_utmp.out_time = ntohl(we->we_utmp.out_time); we++; } } #endif (void) time(&t); wd.wd_recvtime = _time_to_int(t); (void) write(whod, (char *)&wd, cc); if (fstat(whod, &st) < 0 || st.st_size > cc) ftruncate(whod, cc); (void) close(whod); } }
int NetInit() { int s; struct servent *servent; char *udp_device; char *tcp_device; nwio_udpopt_t udpopt; nwio_tcpconf_t tcpconf; if((udp_device = getenv("UDP_DEVICE")) == (char *)NULL) udp_device = UDP_DEVICE; if((udp_ctl = open(udp_device, O_RDWR)) < 0) { fprintf(stderr, "talk: Could not open %s: %s\n", udp_device, strerror(errno)); return(-1); } if((servent = getservbyname("ntalk", "udp")) == (struct servent *)NULL) { fprintf(stderr, "talk: Could not find ntalk udp service\n"); close(udp_ctl); return(-1); } ntalk_port = (udpport_t)servent->s_port; udpopt.nwuo_flags = NWUO_NOFLAGS; udpopt.nwuo_flags |= NWUO_COPY | NWUO_LP_SEL | NWUO_EN_LOC; udpopt.nwuo_flags |= NWUO_DI_BROAD | NWUO_RP_SET | NWUO_RA_SET; udpopt.nwuo_flags |= NWUO_RWDATONLY | NWUO_DI_IPOPT; udpopt.nwuo_remaddr = raddr; udpopt.nwuo_remport = ntalk_port; s = ioctl(udp_ctl, NWIOSUDPOPT, &udpopt); if(s < 0) { perror("talk: ioctl NWIOSUDPOPT"); close(udp_ctl); return(-1); } s = ioctl(udp_ctl, NWIOGUDPOPT, &udpopt); if(s < 0) { perror("talk: ioctl NWIOGUDPOPT"); close(udp_ctl); return(-1); } laddr = udpopt.nwuo_locaddr; ctlport = udpopt.nwuo_locport; if((tcp_device = getenv("TCP_DEVICE")) == (char *)NULL) tcp_device = TCP_DEVICE; if((tcp_fd = open(tcp_device, O_RDWR)) < 0) { fprintf(stderr, "talk: Could not open %s: %s\n", tcp_device, strerror(errno)); close(udp_ctl); return(-1); } tcpconf.nwtc_flags = NWTC_NOFLAGS; tcpconf.nwtc_flags |= NWTC_LP_SEL | NWTC_SET_RA | NWTC_UNSET_RP; tcpconf.nwtc_remaddr = raddr; s = ioctl(tcp_fd, NWIOSTCPCONF, &tcpconf); if(s < 0) { perror("talk: ioctl NWIOSTCPCONF"); close(udp_ctl); close(tcp_fd); return(-1); } s = ioctl(tcp_fd, NWIOGTCPCONF, &tcpconf); if(s < 0) { perror("talk: ioctl NWIOGTCPCONF"); close(udp_ctl); close(tcp_fd); return(-1); } dataport = tcpconf.nwtc_locport; return(0); }
static int smux_socket (void) { int ret; #ifdef HAVE_IPV6 struct addrinfo hints, *res0, *res; int gai; #else struct sockaddr_in serv; struct servent *sp; #endif int sock = 0; #ifdef HAVE_IPV6 memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; gai = getaddrinfo(NULL, "smux", &hints, &res0); if (gai == EAI_SERVICE) { char servbuf[NI_MAXSERV]; sprintf(servbuf,"%d",SMUX_PORT_DEFAULT); servbuf[sizeof (servbuf) - 1] = '\0'; gai = getaddrinfo(NULL, servbuf, &hints, &res0); } if (gai) { zlog_warn("Cannot locate loopback service smux"); return -1; } for(res=res0; res; res=res->ai_next) { if (res->ai_family != AF_INET #ifdef HAVE_IPV6 && res->ai_family != AF_INET6 #endif /* HAVE_IPV6 */ ) continue; sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (sock < 0) continue; sockopt_reuseaddr (sock); sockopt_reuseport (sock); ret = connect (sock, res->ai_addr, res->ai_addrlen); if (ret < 0) { close(sock); sock = -1; continue; } break; } freeaddrinfo(res0); if (sock < 0 && debug_smux) zlog_warn ("Can't connect to SNMP agent with SMUX"); #else sock = socket (AF_INET, SOCK_STREAM, 0); if (sock < 0) { zlog_warn ("Can't make socket for SNMP"); return -1; } memset (&serv, 0, sizeof (struct sockaddr_in)); serv.sin_family = AF_INET; #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN serv.sin_len = sizeof (struct sockaddr_in); #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ sp = getservbyname ("smux", "tcp"); if (sp != NULL) serv.sin_port = sp->s_port; else serv.sin_port = htons (SMUX_PORT_DEFAULT); serv.sin_addr.s_addr = htonl (INADDR_LOOPBACK); sockopt_reuseaddr (sock); sockopt_reuseport (sock); ret = connect (sock, (struct sockaddr *) &serv, sizeof (struct sockaddr_in)); if (ret < 0) { close (sock); smux_sock = -1; if (debug_smux) zlog_warn ("Can't connect to SNMP agent with SMUX"); return -1; } #endif return sock; }
/* * init: * Initialize the global parameters. */ static void init(void) { int i; struct sockaddr_in test_port; int true = 1; socklen_t len; struct sockaddr_in addr; struct sigaction sact; struct servent *se; (void) setsid(); if (setpgid(getpid(), getpid()) == -1) err(1, "setpgid"); sact.sa_flags = SA_RESTART; sigemptyset(&sact.sa_mask); /* Ignore HUP, QUIT and PIPE: */ sact.sa_handler = SIG_IGN; if (sigaction(SIGHUP, &sact, NULL) == -1) err(1, "sigaction SIGHUP"); if (sigaction(SIGQUIT, &sact, NULL) == -1) err(1, "sigaction SIGQUIT"); if (sigaction(SIGPIPE, &sact, NULL) == -1) err(1, "sigaction SIGPIPE"); /* Clean up gracefully on INT and TERM: */ sact.sa_handler = cleanup; if (sigaction(SIGINT, &sact, NULL) == -1) err(1, "sigaction SIGINT"); if (sigaction(SIGTERM, &sact, NULL) == -1) err(1, "sigaction SIGTERM"); /* Handle INFO: */ sact.sa_handler = siginfo; if (sigaction(SIGINFO, &sact, NULL) == -1) err(1, "sigaction SIGINFO"); if (chdir("/") == -1) warn("chdir"); (void) umask(0777); /* Initialize statistics socket: */ addr.sin_family = AF_INET; addr.sin_addr.s_addr = Server_addr; addr.sin_port = 0; Status = socket(AF_INET, SOCK_STREAM, 0); if (bind(Status, (struct sockaddr *) &addr, sizeof addr) < 0) { logit(LOG_ERR, "bind"); cleanup(1); } if (listen(Status, 5) == -1) { logit(LOG_ERR, "listen"); cleanup(1); } len = sizeof (struct sockaddr_in); if (getsockname(Status, (struct sockaddr *) &addr, &len) < 0) { logit(LOG_ERR, "getsockname"); cleanup(1); } stat_port = ntohs(addr.sin_port); /* Initialize main socket: */ addr.sin_family = AF_INET; addr.sin_addr.s_addr = Server_addr; addr.sin_port = 0; Socket = socket(AF_INET, SOCK_STREAM, 0); if (bind(Socket, (struct sockaddr *) &addr, sizeof addr) < 0) { logit(LOG_ERR, "bind"); cleanup(1); } if (listen(Socket, 5) == -1) { logit(LOG_ERR, "listen"); cleanup(1); } len = sizeof (struct sockaddr_in); if (getsockname(Socket, (struct sockaddr *) &addr, &len) < 0) { logit(LOG_ERR, "getsockname"); cleanup(1); } sock_port = ntohs(addr.sin_port); /* Initialize minimal select mask */ FD_ZERO(&Fds_mask); FD_SET(Socket, &Fds_mask); FD_SET(Status, &Fds_mask); Num_fds = ((Socket > Status) ? Socket : Status) + 1; /* Find the port that huntd should run on */ if (Server_port == 0) { se = getservbyname("hunt", "udp"); if (se != NULL) Server_port = ntohs(se->s_port); else Server_port = HUNT_PORT; } /* Check if stdin is a socket: */ len = sizeof (struct sockaddr_in); if (getsockname(STDIN_FILENO, (struct sockaddr *) &test_port, &len) >= 0 && test_port.sin_family == AF_INET) { /* We are probably running from inetd: don't log to stderr */ Server_socket = STDIN_FILENO; conf_logerr = 0; if (test_port.sin_port != htons((u_short) Server_port)) { /* Private game */ should_announce = FALSE; Server_port = ntohs(test_port.sin_port); } } else { /* We need to listen on a socket: */ test_port = addr; test_port.sin_port = htons((u_short) Server_port); Server_socket = socket(AF_INET, SOCK_DGRAM, 0); /* Permit multiple huntd's on the same port. */ if (setsockopt(Server_socket, SOL_SOCKET, SO_REUSEPORT, &true, sizeof true) < 0) logit(LOG_ERR, "setsockopt SO_REUSEADDR"); if (bind(Server_socket, (struct sockaddr *) &test_port, sizeof test_port) < 0) { logit(LOG_ERR, "bind port %d", Server_port); cleanup(1); } /* Datagram sockets do not need a listen() call. */ } /* We'll handle the broadcast listener in the main loop: */ FD_SET(Server_socket, &Fds_mask); if (Server_socket + 1 > Num_fds) Num_fds = Server_socket + 1; /* Initialise the random seed: */ srandomdev(); /* Dig the maze: */ makemaze(); /* Create some boots, if needed: */ makeboots(); /* Construct a table of what objects a player can see over: */ for (i = 0; i < NASCII; i++) See_over[i] = TRUE; See_over[DOOR] = FALSE; See_over[WALL1] = FALSE; See_over[WALL2] = FALSE; See_over[WALL3] = FALSE; See_over[WALL4] = FALSE; See_over[WALL5] = FALSE; logx(LOG_INFO, "game started"); }
int main(int argc, char **argv) { int i; struct servent *service; udpport_t route_port; nwio_udpopt_t udpopt; nwio_ipopt_t ipopt; asynchio_t asyn; time_t timeout; struct timeval tv; struct sigaction sa; char *offset_arg, *offset_end; long arg; udp_device= ip_device= nil; offset_arg= nil; for (i = 1; i < argc && argv[i][0] == '-'; i++) { char *p= argv[i] + 1; if (p[0] == '-' && p[1] == 0) { i++; break; } while (*p != 0) { switch (*p++) { case 'U': if (udp_device != nil) usage(); if (*p == 0) { if (++i == argc) usage(); p= argv[i]; } udp_device= p; p= ""; break; case 'I': if (ip_device != nil) usage(); if (*p == 0) { if (++i == argc) usage(); p= argv[i]; } ip_device= p; p= ""; break; case 'o': if (offset_arg != nil) usage(); if (*p == 0) { if (++i == argc) usage(); p= argv[i]; } offset_arg= p; p= ""; break; case 'b': bcast= 1; break; case 's': /*obsolete*/ break; case 'd': debug= 1; break; default: usage(); } } } if (i != argc) usage(); /* Debug level signals. */ sa.sa_handler= sig_handler; sigemptyset(&sa.sa_mask); sa.sa_flags= 0; sigaction(SIGUSR1, &sa, nil); sigaction(SIGUSR2, &sa, nil); if (udp_device == nil && (udp_device= getenv("UDP_DEVICE")) == nil) udp_device= UDP_DEVICE; if (ip_device == nil && (ip_device= getenv("IP_DEVICE")) == nil) ip_device= IP_DEVICE; if (offset_arg == nil) { priority_offset= PRIO_OFF_DEF; } else { arg= strtol(offset_arg, &offset_end, 0); if (*offset_end != 0 || (priority_offset= arg) != arg) usage(); } if ((service= getservbyname("route", "udp")) == nil) { fprintf(stderr, "irdpd: unable to look up the port number for the 'route' service\n"); exit(1); } route_port= (udpport_t) service->s_port; if ((rip_fd= open(udp_device, O_RDWR)) < 0) fatal(udp_device); udpopt.nwuo_flags= NWUO_COPY | NWUO_LP_SET | NWUO_DI_LOC | NWUO_EN_BROAD | NWUO_RP_SET | NWUO_RA_ANY | NWUO_RWDATALL | NWUO_DI_IPOPT; udpopt.nwuo_locport= route_port; udpopt.nwuo_remport= route_port; if (ioctl(rip_fd, NWIOSUDPOPT, &udpopt) < 0) fatal("setting UDP options failed"); if ((irdp_fd= open(ip_device, O_RDWR)) < 0) fatal(ip_device); ipopt.nwio_flags= NWIO_COPY | NWIO_EN_LOC | NWIO_EN_BROAD | NWIO_REMANY | NWIO_PROTOSPEC | NWIO_HDR_O_SPEC | NWIO_RWDATALL; ipopt.nwio_tos= 0; ipopt.nwio_ttl= 1; ipopt.nwio_df= 0; ipopt.nwio_hdropt.iho_opt_siz= 0; ipopt.nwio_rem= htonl(0xFFFFFFFFL); ipopt.nwio_proto= IPPROTO_ICMP; if (ioctl(irdp_fd, NWIOSIPOPT, &ipopt) < 0) fatal("can't configure ICMP channel"); asyn_init(&asyn); while (1) { ssize_t r; if (do_rip) { /* Try a RIP read. */ r= asyn_read(&asyn, rip_fd, rip_buf, sizeof(rip_buf)); if (r < 0) { if (errno == EIO) fatal(udp_device); if (errno != EINPROGRESS) report(udp_device); } else { now= time(nil); rip_incoming(r); } } if (do_rdisc) { /* Try an IRDP read. */ r= asyn_read(&asyn, irdp_fd, irdp_buf, sizeof(irdp_buf)); if (r < 0) { if (errno == EIO) fatal(ip_device); if (errno != EINPROGRESS) report(ip_device); } else { now= time(nil); irdp_incoming(r); } } fflush(stdout); /* Compute the next wakeup call. */ timeout= next_sol < next_advert ? next_sol : next_advert; /* Wait for a RIP or IRDP packet or a timeout. */ tv.tv_sec= timeout; tv.tv_usec= 0; if (asyn_wait(&asyn, 0, timeout == NEVER ? nil : &tv) < 0) { /* Timeout? */ if (errno != EINTR && errno != EAGAIN) fatal("asyn_wait()"); now= time(nil); time_functions(); } } }
static int setup_listener(char *name, char *port, char *interface, int queue, int ttl, int tos, int reuse, int keepalive) { int fd; struct sockaddr_in addr; int addrlen; int prt; struct hostent *hst; struct servent *srv; addr.sin_family = AF_INET; if (port == NULL) { fatal_failure(LINET_USAGE, 0, "require a port to bind (-p port)"); } prt = atoi(port); if (prt == 0) { srv = getservbyname(port, LINET_TCP); if (srv == NULL) { fatal_failure(LINET_USAGE, 0, "could not convert %s to a nonzero number", port); } addr.sin_port = srv->s_port; } else { addr.sin_port = htons(prt); } if (interface) { if (inet_aton(interface, &(addr.sin_addr)) == 0) { hst = gethostbyname(interface); if (hst == NULL) { fatal_failure(LINET_USAGE, 0, "could not convert %s to an address", interface); } if (hst->h_addrtype != AF_INET) { fatal_failure(LINET_USAGE, 0, "%s does not resolve to an ip4 address", interface); } addr.sin_addr = *(struct in_addr *) hst->h_addr; } } else { addr.sin_addr.s_addr = htonl(INADDR_ANY); } fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (fd < 0) { fatal_failure(LINET_SYSTEM, errno, "could not create an internet socket"); } if(reuse){ setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&reuse, sizeof(int)); } if(keepalive){ setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepalive, sizeof(int)); } addrlen = sizeof(addr); if (bind(fd, (struct sockaddr *) &addr, addrlen) == (-1)) { fatal_failure(LINET_SYSTEM, errno, "could not bind an internet socket"); } if (listen(fd, queue) == (-1)) { fatal_failure(LINET_SYSTEM, errno, "could not listen on socket"); } if(ttl) { if (setsockopt(fd, SOL_IP, IP_TTL, (void *)&ttl, sizeof(int))) { fatal_failure(LINET_SYSTEM, errno, "could not set time to live to %d hops", ttl); } } if(tos) { if (setsockopt(fd, SOL_IP, IP_TOS, (void *)&tos, sizeof(int))) { fatal_failure(LINET_SYSTEM, errno, "could not set type of service to 0x%02x", tos); } } return fd; }
TCPSTREAM *tcp_open (char *host,char *service,unsigned long port) { TCPSTREAM *stream = NIL; int sock; char *s; struct sockaddr_in sin; struct hostent *host_name; char hostname[MAILTMPLEN]; char tmp[MAILTMPLEN]; struct protoent *pt = getprotobyname ("tcp"); struct servent *sv = NIL; port &= 0xffff; /* erase flags */ if (service) { /* service specified? */ if (*service == '*') { /* yes, special alt driver kludge? */ sv = getservbyname (service + 1,"tcp"); } else sv = getservbyname (service,"tcp"); } /* user service name port */ if (sv) port = ntohs (sin.sin_port = sv->s_port); /* copy port number in network format */ else sin.sin_port = htons (port); /* The domain literal form is used (rather than simply the dotted decimal as with other Unix programs) because it has to be a valid "host name" in mailsystem terminology. */ /* look like domain literal? */ if (host[0] == '[' && host[(strlen (host))-1] == ']') { strcpy (hostname,host+1); /* yes, copy number part */ hostname[(strlen (hostname))-1] = '\0'; if ((sin.sin_addr.s_addr = inet_addr (hostname)) != -1) { sin.sin_family = AF_INET; /* family is always Internet */ strcpy (hostname,host); /* hostname is user's argument */ } else { sprintf (tmp,"Bad format domain-literal: %.80s",host); mm_log (tmp,ERROR); return NIL; } } else { /* lookup host name, note that brain-dead Unix requires lowercase! */ strcpy (hostname,host); /* in case host is in write-protected memory */ if ((host_name = gethostbyname (lcase (hostname)))) { /* copy address type */ sin.sin_family = host_name->h_addrtype; /* copy host name */ strcpy (hostname,host_name->h_name); /* copy host addresses */ memcpy (&sin.sin_addr,host_name->h_addr,host_name->h_length); } else { sprintf (tmp,"No such host as %.80s",host); mm_log (tmp,ERROR); return NIL; } } /* get a TCP stream */ if ((sock = socket (sin.sin_family,SOCK_STREAM,pt ? pt->p_proto : 0)) < 0) { sprintf (tmp,"Unable to create TCP socket: %s",strerror (errno)); mm_log (tmp,ERROR); return NIL; } #if 0 /* Maybe this test is necessary. It depends upon how VMS implements * fd_set. UNIX-style fd_set needs it; Windows-style does not. */ else if (sock >= FD_SETSIZE) {/* unselectable sockets are useless */ sprintf (tmp,"Unable to create selectable TCP socket (%d >= %d)", sock,FD_SETSIZE); close (sock); return NIL; } #endif /* open connection */ if (connect (sock,(struct sockaddr *)&sin,sizeof (sin)) < 0) { sprintf (tmp,"Can't connect to %.80s,%d: %s",hostname,port, strerror (errno)); mm_log (tmp,ERROR); return NIL; } /* create TCP/IP stream */ stream = (TCPSTREAM *) fs_get (sizeof (TCPSTREAM)); /* copy official host name */ stream->host = cpystr (hostname); /* get local name */ gethostname (tmp,MAILTMPLEN-1); stream->localhost = cpystr ((host_name = gethostbyname (tmp)) ? host_name->h_name : tmp); /* init sockets */ stream->port = port; /* port number */ stream->tcpsi = stream->tcpso = sock; stream->ictr = 0; /* init input counter */ return stream; /* return success */ }