int udp_connect(char *addr, int port, struct sockaddr_in *serv) { struct sockaddr_in sv; int sock, optval = 1; if (serv == NULL) serv = &sv; if (!fill_sockaddr(serv, addr, port)) return -1; sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) { LOGL(0, "udp_connect failed: socket() %s", strerror(errno)); return -1; } if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0) { LOGL(0, "udp_bind: setsockopt(SO_REUSEADDR): %s", strerror(errno)); return -1; } if (connect(sock, (struct sockaddr *) serv, sizeof(*serv)) < 0) { LOGL(0, "udp_connect: failed: bind(): %s", strerror(errno)); return -1; } LOG("New UDP socket %d connected to %s:%d", sock, inet_ntoa(serv->sin_addr), ntohs(serv->sin_port)); return sock; }
int tcp_listen(char *addr, int port) { struct sockaddr_in serv; int sock, optval = 1; if (!fill_sockaddr(&serv, addr, port)) return -1; sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { LOGL(0, "tcp_listen failed: socket(): %s", strerror(errno)); return -1; } if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0) { LOGL(0, "tcp_listen failed: setsockopt(SO_REUSEADDR): %s", strerror(errno)); return -1; } if (bind(sock, (struct sockaddr *) &serv, sizeof(serv)) < 0) { LOGL(0, "tcp_listen: failed: bind() on address: %s, port %d : error %s", addr ? addr : "ANY", port, strerror(errno)); return -1; } if (listen(sock, 10) < 0) { LOGL(0, "tcp_listen: listen(): %s", strerror(errno)); return -1; } return sock; }
int udp_bind(char *addr, int port) { struct sockaddr_in serv; int sock, optval = 1; if (!fill_sockaddr(&serv, addr, port)) return -1; sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) { LOGL(0, "udp_bind failed: socket(): %s", strerror(errno)); return -1; } if (addr && atoi(addr) >= 239) { struct ip_mreq mreq; mreq.imr_multiaddr.s_addr = inet_addr(addr); mreq.imr_interface.s_addr = htonl(INADDR_ANY); LOG("setting multicast for %s", addr); if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) == -1) { LOGL(0, "membership error: %s", strerror(errno)); } } if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0) { LOGL(0, "udp_bind failed: setsockopt(SO_REUSEADDR): %s", strerror(errno)); return -1; } if (bind(sock, (struct sockaddr *) &serv, sizeof(serv)) < 0) { LOGL(0, "udp_bind: failed: bind() on host %s port %d: error %s", addr, port, strerror(errno)); return -1; } set_linux_socket_timeout(sock); LOGL(1, "New UDP socket %d bound to %s:%d", sock, inet_ntoa(serv.sin_addr), ntohs(serv.sin_port)); return sock; }
int parse_hostport(char *addr_str, struct sockaddr_in *addr, char **host_out) { char *host, *c, *dup; int port, err = -1; dup = strdup(addr_str); if (dup == NULL) { print_log("failed to allocate address buffer. len=%ld", strlen(addr_str)); goto exit; } c = dup; host = c; while (*c != ':' && *c != '\0') c++; if (*c == '\0') { print_log("bad address string %s", addr_str); goto exit; } *c++ = '\0'; errno = 0; port = strtol(c, NULL, 10); if (errno != 0) { ERRLOG(errno, "error while parsing port number (strtol). address=%s", addr_str); goto exit; } if (port <= 0 || port >= 64*1024) { print_log("bad port %d in address string %s", port, addr_str); goto exit; } memset(addr, 0, sizeof(*addr)); if (0 != fill_sockaddr(host, addr)) { print_log("cannot find the address for host %s", host); goto exit; } addr->sin_port = htons(port); err = 0; exit: if (err == 0 && host_out != NULL) *host_out = host; else if (dup) free(dup); return err; }
int udp_bind_connect(char *src, int sport, char *dest, int dport, struct sockaddr_in *serv) { int sock; sock = udp_bind(src, sport); if (sock < 0) return sock; fill_sockaddr(serv, dest, dport); if (connect(sock, (struct sockaddr *) serv, sizeof(*serv)) < 0) { LOGL(0, "udp_bind_connect: failed: bind(): %s", strerror(errno)); return -1; } LOG("New UDP socket %d connected to %s:%d", sock, inet_ntoa(serv->sin_addr), ntohs(serv->sin_port)); return sock; }
int tcp_connect(char *addr, int port, struct sockaddr_in *serv, int blocking) { struct sockaddr_in sv; int sock, optval = 1; if (serv == NULL) serv = &sv; if (!fill_sockaddr(serv, addr, port)) return -1; sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { LOGL(0, "tcp_connect failed: socket() %s", strerror(errno)); return -1; } if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0) { LOGL(0, "tcp_connect: setsockopt(SO_REUSEADDR): %s", strerror(errno)); close(sock); return -1; } set_linux_socket_timeout(sock); if (blocking) { int flags = fcntl(sock, F_GETFL, 0); fcntl(sock, F_SETFL, flags | O_NONBLOCK); } if (connect(sock, (struct sockaddr *) serv, sizeof(*serv)) < 0) { if (errno != EINPROGRESS) { LOGL(0, "tcp_connect: failed: connect to %s:%d failed: %s", addr, port, strerror(errno)); close(sock); return -1; } } LOG("New TCP socket %d connected to %s:%d", sock, addr, port); return sock; }
int sockaddr_from_proc_name(char *name, struct sockaddr_in *addr) { /* name always starts like host:port-... */ char *c = name, *colon = NULL, *dash = NULL; int port, err = -1; while (*c != '\0' && *c != ':') c++; if (*c == ':') { colon = c; while (*c != '\0' && *c != '-') c++; if (*c == '-') { dash = c; /* null terminate temporarily... */ *colon = '\0'; *dash = '\0'; c = colon+1; port = 0; while (*c != '\0') { if (*c >= '0' && *c <= '9') { port = port * 10 + (*c - '0'); } else { port = -1; break; } c++; } if (port > 0 && port < 64*1024 && 0 == fill_sockaddr(name, addr)) { addr->sin_port = htons(port); err = 0; } } } if (colon) *colon = ':'; if (dash) *dash = '-'; return err; }
char * getlocalip() { // if(localip[0]!=0)return localip; const char *dest = opts.disc_host, *h; int port = 1900; struct sockaddr_in serv; int sock = socket(AF_INET, SOCK_DGRAM, 0); //Socket could not be created if (sock < 0) { LOG("getlocalip: Cannot create socket: %s", strerror(errno)); return localip; } fill_sockaddr(&serv, (char *) dest, port); int err = connect(sock, (const struct sockaddr *) &serv, sizeof(serv)); if (err) { LOG("getlocalip: Error '%s'' during connect", strerror(errno)); memset(localip, 0, sizeof(localip)); } else { h = get_sock_shost(sock); if (h) strcpy(localip, h); } close(sock); return localip; }
int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) { struct hostent *host; struct servent *serv; int count, i; int port; char *name; size_t addrlen; char *addrs; struct addrinfo *addrinfos; host = gethostbyname(node); if (! host || (hints->ai_family != AF_UNSPEC && host->h_addrtype != hints->ai_family)) return -1; count = 1; #ifdef h_addr while (host->h_addr_list[count]) ++count; #endif /* h_addr */ serv = getservbyname(service, (hints->ai_socktype == SOCK_STREAM ? "tcp" : "udp")); port = serv ? serv->s_port : htons(atoi(service)); if (host->h_name) { size_t name_len = strlen(host->h_name); name = (char *) malloc(name_len + 1); memcpy(name, host->h_name, name_len + 1); } else { name = NULL; } #ifdef AF_INET6 if (host->h_addrtype == AF_INET6) fill_sockaddr6(host, port, count, addrlen, addrs); else #endif /* AF_INET6 */ fill_sockaddr(host, port, count, addrlen, addrs); addrinfos = (struct addrinfo *) malloc(sizeof(*addrinfos) * count); addrinfos[0].ai_flags = hints->ai_flags; addrinfos[0].ai_family = host->h_addrtype; addrinfos[0].ai_socktype = hints->ai_socktype; addrinfos[0].ai_protocol = hints->ai_protocol; addrinfos[0].ai_addrlen = addrlen; addrinfos[0].ai_addr = (struct sockaddr *) addrs; addrinfos[0].ai_canonname = name; for (i = 1; i < count; ++i) { addrinfos[i] = addrinfos[0]; addrinfos[i].ai_addr = (struct sockaddr *) (addrs + addrlen * i); addrinfos[i - 1].ai_next = &addrinfos[i]; } addrinfos[i - 1].ai_next = NULL; *res = addrinfos; return 0; }
int main(int argc,char **argv) { int i,srv_sock,j,retval,ptype; struct sockaddr_in srv_sa; int clientfds[MAX_CLIENTS]; char *clientsas[MAX_CLIENTS]; int client_cnt = 0; int block_size = 1024; int maxfd = 0; int c; char *srvhost = NULL; short srvport = DEF_SRV_PORT; int proto = DEF_PROTO; int debug = 0; char *buf = NULL; fd_set rfds; fd_set static_rfds; /* grab some quick args, hostname, port, tcp, udp... */ while ((c = getopt(argc,argv,"h:p:tudb:")) != -1) { switch(c) { case 'h': srvhost = optarg; break; case 'p': srvport = atoi(optarg); break; case 't': proto = SOCK_STREAM; break; case 'u': proto = SOCK_DGRAM; fatal("no udp support yet!"); break; case 'd': ++debug; break; case 'b': block_size = atoi(optarg); break; default: break; } } if ((buf = (char *)malloc(sizeof(char)*block_size)) == NULL) { efatal("no memory for data buf"); } if ((retval = fill_sockaddr(srvhost,srvport,&srv_sa)) != 0) { if (retval == -1) { fatal("bad port"); } else { efatal("host lookup failed"); } } /* startup server... */ if ((srv_sock = socket(AF_INET,proto,0)) == -1) { efatal("could not get socket"); } if (bind(srv_sock, (struct sockaddr *)&srv_sa, sizeof(struct sockaddr_in) ) < 0) { efatal("could not bind"); } if (proto == PROTO_TCP) { if (listen(srv_sock,8) < 0) { efatal("could not listen"); } } /* daemonize... */ if (!debug) { daemon(0,0); } for (i = 0; i < MAX_CLIENTS; ++i) { clientfds[i] = -1; clientsas[i] = (char *)malloc(MAX_NAME_LEN + 1); } FD_ZERO(&static_rfds); FD_SET(srv_sock,&static_rfds); maxfd = srv_sock; /* listen and read forever */ while (1) { /* reset fdsets */ memcpy(&rfds,&static_rfds,sizeof(static_rfds)); retval = select(maxfd+1,&rfds,NULL,NULL,NULL); if (retval > 0) { if (FD_ISSET(srv_sock,&rfds)) { struct sockaddr_in client_sin; socklen_t slen; int client_fd; slen = sizeof(client_sin); if ((client_fd = accept(srv_sock, (struct sockaddr *)&client_sin, &slen)) < 0) { warn("accept failed"); } else if (client_cnt >= MAX_CLIENTS) { warn("already at max clients"); } else { /* add new client... */ for (i = 0; i < MAX_CLIENTS; ++i) { if (clientfds[i] == -1) { break; } } clientfds[i] = client_fd; if (client_fd > maxfd) { maxfd = client_fd; } FD_SET(client_fd,&static_rfds); if (debug) { fprintf(stdout, "connect from %s:%d\n", inet_ntoa(client_sin.sin_addr), ntohs(client_sin.sin_port)); } char *addr = inet_ntoa(client_sin.sin_addr); int addrlen = strlen(addr); strncpy(clientsas[i], addr, (addrlen > MAX_NAME_LEN)?MAX_NAME_LEN:addrlen); /* null term if strncpy couldn't */ if (addrlen > MAX_NAME_LEN) { clientsas[i][MAX_NAME_LEN] = '\0'; } ++client_cnt; } } else { for (i = 0; i < MAX_CLIENTS; ++i) { if (clientfds[i] > -1) { if (FD_ISSET(clientfds[i],&rfds)) { /* read a block, or as much as possible */ retval = read(clientfds[i],buf,block_size); /* dead client, pretty much */ if (retval <= 0) { if (debug) { fprintf(stdout, "disconnect from %s\n", clientsas[i]); } close(clientfds[i]); FD_CLR(clientfds[i],&static_rfds); clientfds[i] = -1; --client_cnt; } else if (debug > 2 ) { fprintf(stdout, "DEBUG: read %d bytes from %s\n", retval, clientsas[i]); } } } } } } else if (retval < 0) { /* error... */ ewarn("error in select"); } } return -1; }