int ip_udp_open(int *sock, anysin_t *address) { *sock = ip_socket(address, IP_PROTOCOL_UDP); if (*sock < 0) goto wrong; if (!ip_nonblock(*sock)) debug_log(DEBUG_WARN, "ip_udp_open(): unable to set socket non-blocking (%s)\n", strerror(errno)); return 1; wrong: if (*sock >= 0) close(*sock); return 0; }
/* Create a socket and connect to host (name or number, ipv6 ok) at one of port-range. Arguments: type SOCK_DGRAM or SOCK_STREAM af AF_INET6 or AF_INET for the socket type address the remote address, in text form portlo,porthi the remote port range timeout a timeout connhost if not NULL, host_item filled in with connection details errstr pointer for allocated string on error Return: socket fd, or -1 on failure (having allocated an error string) */ int ip_connectedsocket(int type, const uschar * hostname, int portlo, int porthi, int timeout, host_item * connhost, uschar ** errstr) { int namelen, port; host_item shost; host_item *h; int af = 0, fd, fd4 = -1, fd6 = -1; shost.next = NULL; shost.address = NULL; shost.port = portlo; shost.mx = -1; namelen = Ustrlen(hostname); /* Anything enclosed in [] must be an IP address. */ if (hostname[0] == '[' && hostname[namelen - 1] == ']') { uschar * host = string_copy(hostname); host[namelen - 1] = 0; host++; if (string_is_ip_address(host, NULL) == 0) { *errstr = string_sprintf("malformed IP address \"%s\"", hostname); return -1; } shost.name = shost.address = host; } /* Otherwise check for an unadorned IP address */ else if (string_is_ip_address(hostname, NULL) != 0) shost.name = shost.address = string_copy(hostname); /* Otherwise lookup IP address(es) from the name */ else { shost.name = string_copy(hostname); if (host_find_byname(&shost, NULL, HOST_FIND_QUALIFY_SINGLE, NULL, FALSE) != HOST_FOUND) { *errstr = string_sprintf("no IP address found for host %s", shost.name); return -1; } } /* Try to connect to the server - test each IP till one works */ for (h = &shost; h != NULL; h = h->next) { fd = (Ustrchr(h->address, ':') != 0) ? (fd6 < 0) ? (fd6 = ip_socket(type, af = AF_INET6)) : fd6 : (fd4 < 0) ? (fd4 = ip_socket(type, af = AF_INET )) : fd4; if (fd < 0) { *errstr = string_sprintf("failed to create socket: %s", strerror(errno)); goto bad; } for(port = portlo; port <= porthi; port++) if (ip_connect(fd, af, h->address, port, timeout) == 0) { if (fd != fd6) close(fd6); if (fd != fd4) close(fd4); if (connhost) { h->port = port; *connhost = *h; connhost->next = NULL; } return fd; } } *errstr = string_sprintf("failed to connect to any address for %s: %s", hostname, strerror(errno)); bad: close(fd4); close(fd6); return -1; }
int main(int argc, char *argv[]) { char *file = NULL; char c; int daemon = 0; int rc = OK; if (getuid() != 0) { fprintf(stderr, "Run me as root please\n"); return 1; } while ((c = getopt(argc, argv, "c:dvh")) != EOF) { switch (c) { case 'c': file = strdup(optarg); if (file == NULL) { fprintf(stderr, "Failed to alloc memory\n"); exit(1); } break; case 'd': daemon++; break; case 'v': show_version(); exit(0); break; case 'h': usage(argv[0]); exit(0); break; default: usage(argv[0]); exit(1); } } init_filter(); set_conf_file(file); parse_conf(); rc = init_log(); if (rc != OK) { fprintf(stderr, "Failed to open log file \n"); return 1; } ip_socket_fd = ip_socket(); if (ip_socket_fd < 0) { fprintf(stderr, "Failed to create raw socket \n"); return 1; } rc = create_pipe(&ip_pipe_in_fd, &ip_pipe_out_fd); if (rc != OK) { fprintf(stderr, "Failed to create net pipe \n"); return 1; } rc = create_pipe(&cmd_pipe_in_fd, &cmd_pipe_out_fd); if (rc != OK) { fprintf(stderr, "Failed to create cmd pipe \n"); return 1; } log_msg(LOG_WARN, "Icmp Knock daemon %s started", version); /* Go daemon mode */ if (daemon) { switch (fork()) { case -1: fprintf(stderr, "fork(): call failed \n"); return 3; case 0: close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); if (setsid() == -1) { exit(1); } break; default : return 0; } } parent_pid = getpid(); child_pid = fork(); switch (child_pid) { case -1: fprintf(stderr, "fork(): call failed \n"); return 1; break; case 0: agent_main(); break; default : principal_main(); break; } return OK; }