[821] | 1 | /* vi: set sw=4 ts=4: */
|
---|
| 2 | /*
|
---|
| 3 | * Utility routines.
|
---|
| 4 | *
|
---|
| 5 | * Connect to host at port using address resolution from getaddrinfo
|
---|
| 6 | *
|
---|
| 7 | */
|
---|
| 8 |
|
---|
| 9 | #include <unistd.h>
|
---|
| 10 | #include <string.h>
|
---|
| 11 | #include <stdlib.h>
|
---|
| 12 | #include <sys/types.h>
|
---|
| 13 | #include <sys/socket.h>
|
---|
| 14 | #include <errno.h>
|
---|
| 15 | #include <netdb.h>
|
---|
| 16 | #include <sys/socket.h>
|
---|
| 17 | #include <netinet/in.h>
|
---|
| 18 | #include <arpa/inet.h>
|
---|
| 19 | #include "libbb.h"
|
---|
| 20 |
|
---|
| 21 | /* Return network byte ordered port number for a service.
|
---|
| 22 | * If "port" is a number use it as the port.
|
---|
| 23 | * If "port" is a name it is looked up in /etc/services, if it isnt found return
|
---|
| 24 | * default_port
|
---|
| 25 | */
|
---|
| 26 | unsigned short bb_lookup_port(const char *port, const char *protocol, unsigned short default_port)
|
---|
| 27 | {
|
---|
| 28 | unsigned short port_nr = htons(default_port);
|
---|
| 29 | if (port) {
|
---|
| 30 | char *endptr;
|
---|
| 31 | int old_errno;
|
---|
| 32 | long port_long;
|
---|
| 33 |
|
---|
| 34 | /* Since this is a lib function, we're not allowed to reset errno to 0.
|
---|
| 35 | * Doing so could break an app that is deferring checking of errno. */
|
---|
| 36 | old_errno = errno;
|
---|
| 37 | errno = 0;
|
---|
| 38 | port_long = strtol(port, &endptr, 10);
|
---|
| 39 | if (errno != 0 || *endptr!='\0' || endptr==port || port_long < 0 || port_long > 65535) {
|
---|
| 40 | struct servent *tserv = getservbyname(port, protocol);
|
---|
| 41 | if (tserv) {
|
---|
| 42 | port_nr = tserv->s_port;
|
---|
| 43 | }
|
---|
| 44 | } else {
|
---|
| 45 | port_nr = htons(port_long);
|
---|
| 46 | }
|
---|
| 47 | errno = old_errno;
|
---|
| 48 | }
|
---|
| 49 | return port_nr;
|
---|
| 50 | }
|
---|
| 51 |
|
---|
| 52 | void bb_lookup_host(struct sockaddr_in *s_in, const char *host)
|
---|
| 53 | {
|
---|
| 54 | struct hostent *he;
|
---|
| 55 |
|
---|
| 56 | memset(s_in, 0, sizeof(struct sockaddr_in));
|
---|
| 57 | s_in->sin_family = AF_INET;
|
---|
| 58 | he = xgethostbyname(host);
|
---|
| 59 | memcpy(&(s_in->sin_addr), he->h_addr_list[0], he->h_length);
|
---|
| 60 | }
|
---|
| 61 |
|
---|
| 62 | int xconnect(struct sockaddr_in *s_addr)
|
---|
| 63 | {
|
---|
| 64 | int s = bb_xsocket(AF_INET, SOCK_STREAM, 0);
|
---|
| 65 | if (connect(s, (struct sockaddr *)s_addr, sizeof(struct sockaddr_in)) < 0)
|
---|
| 66 | {
|
---|
| 67 | if (ENABLE_FEATURE_CLEAN_UP) close(s);
|
---|
| 68 | bb_perror_msg_and_die("Unable to connect to remote host (%s)",
|
---|
| 69 | inet_ntoa(s_addr->sin_addr));
|
---|
| 70 | }
|
---|
| 71 | return s;
|
---|
| 72 | }
|
---|