summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@cvs.openbsd.org>2004-03-31 23:17:09 +0000
committerDamien Miller <djm@cvs.openbsd.org>2004-03-31 23:17:09 +0000
commit64472d0fa5178650c9cad135bb6ef3cd1113fd03 (patch)
tree689ab2bfb6aff1cf419ed8b6b66b348795baa5db
parent1305943f96274a71a5ef7c08441861e071414ce1 (diff)
support IPv6 connections in "openssl s_client", adding -4 and -6 options to
force protocol; ok itojun@
-rw-r--r--lib/libssl/src/apps/s_apps.h4
-rw-r--r--lib/libssl/src/apps/s_client.c16
-rw-r--r--lib/libssl/src/apps/s_socket.c121
3 files changed, 45 insertions, 96 deletions
diff --git a/lib/libssl/src/apps/s_apps.h b/lib/libssl/src/apps/s_apps.h
index 66b6edd442b..48e7dbaddce 100644
--- a/lib/libssl/src/apps/s_apps.h
+++ b/lib/libssl/src/apps/s_apps.h
@@ -154,10 +154,10 @@ int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx);
#ifdef HEADER_SSL_H
int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file);
#endif
-int init_client(int *sock, char *server, int port);
+int init_client(int *sock, char *server, char *port, int af);
int should_retry(int i);
int extract_port(char *str, short *port_ptr);
-int extract_host_port(char *str,char **host_ptr,unsigned char *ip,short *p);
+int extract_host_port(char *str,char **host_ptr,unsigned char *ip,char **p);
long MS_CALLBACK bio_dump_cb(BIO *bio, int cmd, const char *argp,
int argi, long argl, long ret);
diff --git a/lib/libssl/src/apps/s_client.c b/lib/libssl/src/apps/s_client.c
index 1128735d49e..ae7c9f9ede7 100644
--- a/lib/libssl/src/apps/s_client.c
+++ b/lib/libssl/src/apps/s_client.c
@@ -109,6 +109,8 @@
*
*/
+#include <sys/types.h>
+#include <netinet/in.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
@@ -183,6 +185,8 @@ static void sc_usage(void)
{
BIO_printf(bio_err,"usage: s_client args\n");
BIO_printf(bio_err,"\n");
+ BIO_printf(bio_err," -4 - Force IPv4\n");
+ BIO_printf(bio_err," -6 - Force IPv6\n");
BIO_printf(bio_err," -host host - use -connect instead\n");
BIO_printf(bio_err," -port port - use -connect instead\n");
BIO_printf(bio_err," -connect host:port - who to connect to (default is %s:%s)\n",SSL_HOST_NAME,PORT_STR);
@@ -232,12 +236,12 @@ int MAIN(int argc, char **argv)
int off=0;
SSL *con=NULL,*con2=NULL;
X509_STORE *store = NULL;
- int s,k,width,state=0;
+ int s,k,width,state=0, af=AF_UNSPEC;
char *cbuf=NULL,*sbuf=NULL,*mbuf=NULL;
int cbuf_len,cbuf_off;
int sbuf_len,sbuf_off;
fd_set readfds,writefds;
- short port=PORT;
+ char *port=PORT_STR;
int full_log=1;
char *host=SSL_HOST_NAME;
char *cert_file=NULL,*key_file=NULL;
@@ -308,8 +312,8 @@ int MAIN(int argc, char **argv)
else if (strcmp(*argv,"-port") == 0)
{
if (--argc < 1) goto bad;
- port=atoi(*(++argv));
- if (port == 0) goto bad;
+ port= *(++argv);
+ if (port == NULL || *port == '\0') goto bad;
}
else if (strcmp(*argv,"-connect") == 0)
{
@@ -429,6 +433,8 @@ int MAIN(int argc, char **argv)
if (--argc < 1) goto bad;
inrand= *(++argv);
}
+ else if (strcmp(*argv,"-4") == 0) { af = AF_INET;}
+ else if (strcmp(*argv,"-6") == 0) { af = AF_INET6;}
else
{
BIO_printf(bio_err,"unknown option %s\n",*argv);
@@ -524,7 +530,7 @@ bad:
re_start:
- if (init_client(&s,host,port) == 0)
+ if (init_client(&s,host,port,af) == 0)
{
BIO_printf(bio_err,"connect:errno=%d\n",get_last_socket_error());
SHUTDOWN(s);
diff --git a/lib/libssl/src/apps/s_socket.c b/lib/libssl/src/apps/s_socket.c
index 02c3f640cf7..3b36d2dff80 100644
--- a/lib/libssl/src/apps/s_socket.c
+++ b/lib/libssl/src/apps/s_socket.c
@@ -86,11 +86,9 @@ static struct hostent *GetHostByName(char *name);
static void ssl_sock_cleanup(void);
#endif
static int ssl_sock_init(void);
-static int init_client_ip(int *sock,unsigned char ip[4], int port);
static int init_server(int *sock, int port);
static int init_server_long(int *sock, int port,char *ip);
static int do_accept(int acc_sock, int *sock, char **host);
-static int host_ip(char *str, unsigned char ip[4]);
#ifdef OPENSSL_SYS_WIN16
#define SOCKET_PROTOCOL 0 /* more microsoft stupidity */
@@ -185,50 +183,41 @@ static int ssl_sock_init(void)
return(1);
}
-int init_client(int *sock, char *host, int port)
+int init_client(int *sock, char *host, char *port, int af)
{
- unsigned char ip[4];
- short p=0;
+ struct addrinfo hints, *ai_top, *ai;
+ int i, s;
- if (!host_ip(host,&(ip[0])))
+ memset(&hints, '\0', sizeof(hints));
+ hints.ai_family = af;
+ hints.ai_socktype = SOCK_STREAM;
+
+ if ((i = getaddrinfo(host, port, &hints, &ai_top)) != 0 ||
+ ai_top == NULL || ai_top->ai_addr == NULL)
{
- return(0);
+ BIO_printf(bio_err,"getaddrinfo: %s\n", gai_strerror(i));
+ return (0);
}
- if (p != 0) port=p;
- return(init_client_ip(sock,ip,port));
- }
-
-static int init_client_ip(int *sock, unsigned char ip[4], int port)
- {
- unsigned long addr;
- struct sockaddr_in them;
- int s,i;
-
- if (!ssl_sock_init()) return(0);
-
- memset((char *)&them,0,sizeof(them));
- them.sin_family=AF_INET;
- them.sin_port=htons((unsigned short)port);
- addr=(unsigned long)
- ((unsigned long)ip[0]<<24L)|
- ((unsigned long)ip[1]<<16L)|
- ((unsigned long)ip[2]<< 8L)|
- ((unsigned long)ip[3]);
- them.sin_addr.s_addr=htonl(addr);
-
- s=socket(AF_INET,SOCK_STREAM,SOCKET_PROTOCOL);
- if (s == INVALID_SOCKET) { perror("socket"); return(0); }
+ for (ai = ai_top; ai != NULL; ai = ai->ai_next)
+ {
+ s=socket(ai->ai_addr->sa_family, SOCK_STREAM, SOCKET_PROTOCOL);
+ if (s == INVALID_SOCKET) { continue; }
#ifndef OPENSSL_SYS_MPE
- i=0;
- i=setsockopt(s,SOL_SOCKET,SO_KEEPALIVE,(char *)&i,sizeof(i));
- if (i < 0) { perror("keepalive"); return(0); }
+ i=0;
+ i=setsockopt(s,SOL_SOCKET,SO_KEEPALIVE,(char *)&i,sizeof(i));
+ if (i == -1) { close(s); continue; }
#endif
+ if ((i = connect(s, ai->ai_addr, ai->ai_addr->sa_len)) == 0)
+ { *sock=s; freeaddrinfo(ai_top); return (1);}
- if (connect(s,(struct sockaddr *)&them,sizeof(them)) == -1)
- { close(s); perror("connect"); return(0); }
- *sock=s;
- return(1);
+ close(s);
+ }
+
+ perror("connect");
+ close(s);
+ freeaddrinfo(ai_top);
+ return(0);
}
int do_server(int port, int *ret, int (*cb)(), char *context)
@@ -410,12 +399,13 @@ end:
}
int extract_host_port(char *str, char **host_ptr, unsigned char *ip,
- short *port_ptr)
+ char **port_ptr)
{
char *h,*p;
h=str;
- p=strchr(str,':');
+ p=strrchr(str,'/'); /* IPv6 host/port */
+ if (p == NULL) { p=strrchr(str,':'); }
if (p == NULL)
{
BIO_printf(bio_err,"no port defined\n");
@@ -423,58 +413,11 @@ int extract_host_port(char *str, char **host_ptr, unsigned char *ip,
}
*(p++)='\0';
- if ((ip != NULL) && !host_ip(str,ip))
- goto err;
if (host_ptr != NULL) *host_ptr=h;
- if (!extract_port(p,port_ptr))
- goto err;
- return(1);
-err:
- return(0);
- }
+ if (port_ptr != NULL && p != NULL && *p != '\0')
+ *port_ptr = p;
-static int host_ip(char *str, unsigned char ip[4])
- {
- unsigned int in[4];
- int i;
-
- if (sscanf(str,"%u.%u.%u.%u",&(in[0]),&(in[1]),&(in[2]),&(in[3])) == 4)
- {
- for (i=0; i<4; i++)
- if (in[i] > 255)
- {
- BIO_printf(bio_err,"invalid IP address\n");
- goto err;
- }
- ip[0]=in[0];
- ip[1]=in[1];
- ip[2]=in[2];
- ip[3]=in[3];
- }
- else
- { /* do a gethostbyname */
- struct hostent *he;
-
- if (!ssl_sock_init()) return(0);
-
- he=GetHostByName(str);
- if (he == NULL)
- {
- BIO_printf(bio_err,"gethostbyname failure\n");
- goto err;
- }
- /* cast to short because of win16 winsock definition */
- if ((short)he->h_addrtype != AF_INET)
- {
- BIO_printf(bio_err,"gethostbyname addr is not AF_INET\n");
- return(0);
- }
- ip[0]=he->h_addr_list[0][0];
- ip[1]=he->h_addr_list[0][1];
- ip[2]=he->h_addr_list[0][2];
- ip[3]=he->h_addr_list[0][3];
- }
return(1);
err:
return(0);