* Mnemonic: SIaddress
* Abstract: This routine will convert a sockaddr_in structure to a
* dotted decimal address, or visa versa.
-* If type == AC_TOADDR the src string may be:
+* If type == AC_TOADDR the src string may be:
* xxx.xxx.xxx.xxx.portnumber or host-name.portnumber
* xxx.xxx.xxx.xxx.service[.protocol] or hostname;service[;protocol]
* if protocol is not supplied then tcp is assumed.
* hostname may be something like godzilla.moviemania.com
* Parms: src - Pointer to source buffer
-* dest- Pointer to dest buffer pointer
-* type- Type of conversion AC_TODOT converts sockaddr to human readable. AC_TOADDR
+* dest- Pointer to dest buffer pointer
+* type- Type of conversion AC_TODOT converts sockaddr to human readable. AC_TOADDR
* converts character buffer to sockaddr.
* Returns: Nothing.
* Date: 19 January 1995
* Modified: 22 Mar 1995 - To add support for ipx addresses.
* 18 Oct 2020 - drop old port separator (;)
*
-* CAUTION: The netdb.h header file is a bit off when it sets up the
-* hostent structure. It claims that h_addr_list is a pointer
-* to character pointers, but it is really a pointer to a list
+* CAUTION: The netdb.h header file is a bit off when it sets up the
+* hostent structure. It claims that h_addr_list is a pointer
+* to character pointers, but it is really a pointer to a list
* of pointers to integers!!!
-*
+*
***************************************************************************
*/
-#include "sisetup.h" // get necessary defs and other stuff
+#include "sisetup.h" // get necessary defs and other stuff
#include <netdb.h>
#include <stdio.h>
#include <ctype.h>
-/*
+/*
target: buffer with address e.g. 192.168.0.1:4444 :4444 (listen) [::1]4444
- family: PF_INET[6] (let it be 0 to select based on addr in buffer
+ family: PF_INET[6] (let it be 0 to select based on addr in buffer
proto: IPPROTO_TCP IPPROTO_UDP
type: SOCK_STREAM SOCK_DGRAM
returns length of struct pointed to by rap (return addr blockpointer)
*/
extern int SIgenaddr( char *target, int proto, int family, int socktype, struct sockaddr **rap ) {
- struct addrinfo hint; // hints to give getaddrinfo
- struct addrinfo *list = NULL; // list of what comes back
- int ga_flags = 0; // flags to pass to getaddrinfo in hints
+ struct addrinfo hint; // hints to give getaddrinfo
+ struct addrinfo *list = NULL; // list of what comes back
+ int ga_flags = 0; // flags to pass to getaddrinfo in hints
int error = 0;
- int rlen = 0; // length of the addr that rap points to on return
- char *pstr; // port string
- char *dstr; // a copy of the users target that we can destroy
+ int rlen = 0; // length of the addr that rap points to on return
+ char *pstr; // port string
+ char *dstr; // a copy of the users target that we can destroy
char* fptr; // ptr we allocated and need to free (we may adjust dstr)
- fptr = dstr = strdup( (char *) target ); // copy so we can destroy it with strtok
- *rap = NULL; // ensure null incase something breaks
+ fptr = dstr = strdup( (char *) target ); // copy so we can destroy it with strtok
+ *rap = NULL; // ensure null incase something breaks
while( isspace( *dstr ) ) {
dstr++;
}
- if( *dstr == ':' ) { // user passed in :port -- so we assume this is for bind
+ if( *dstr == ':' ) { // user passed in :port -- so we assume this is for bind
pstr = dstr;
*(pstr++) = 0;
if( *dstr == '[' ) { // strip [ and ] from v6 and point pstring if port there
dstr++;
pstr = strchr( dstr, ']' );
- if( *pstr != ']' ) {
+ if( !pstr || *pstr != ']' ) {
+ free( fptr );
return -1;
}
}
memset( &hint, 0, sizeof( hint ) );
- hint.ai_family = family; // AF_INET AF_INET6... let this be 0 to select best based on addr
- hint.ai_socktype = socktype; // SOCK_DGRAM SOCK_STREAM
- hint.ai_protocol = proto; // IPPORTO_TCP IPPROTO_UDP
+ hint.ai_family = family; // AF_INET AF_INET6... let this be 0 to select best based on addr
+ hint.ai_socktype = socktype; // SOCK_DGRAM SOCK_STREAM
+ hint.ai_protocol = proto; // IPPROTO_TCP IPPROTO_UDP
hint.ai_flags = ga_flags;
- if( DEBUG )
- fprintf( stderr, "[DBUG] siaddress: calling getaddrinfo flags=%x proto=%d family=%d target=%s host=%s port=%s\n",
- ga_flags, proto, family, target, dstr, pstr );
+ if( DEBUG )
+ rmr_vlog( RMR_VL_DEBUG, "siaddress: calling getaddrinfo flags=%x sockty=%d proto=%d family=%d target=%s host=%s port=%s\n",
+ ga_flags, socktype, proto, family, target, dstr, pstr );
if( (error = getaddrinfo( dstr, pstr, &hint, &list )) ) {
- fprintf( stderr, "error from getaddrinfo: target=%s host=%s port=%s(port): error=(%d) %s\n", target, dstr, pstr, error, gai_strerror( error ) );
+ fprintf( stderr, "sigenaddr: error from getaddrinfo: target=%s host=%s port=%s(port): error=(%d) %s\n",
+ target, dstr, pstr, error, gai_strerror( error ) );
} else {
- *rap = (struct sockaddr *) malloc( list->ai_addrlen ); // alloc a buffer and give address to caller
+ *rap = (struct sockaddr *) malloc( list->ai_addrlen ); // alloc a buffer and give address to caller
memcpy( *rap, list->ai_addr, list->ai_addrlen );
rlen = list->ai_addrlen;
-
- freeaddrinfo( list ); // ditch system allocated memory
+
+ freeaddrinfo( list ); // ditch system allocated memory
}
- free( dstr );
+ free( fptr );
return rlen;
}
-/*
+/*
Given a source address convert from one form to another based on type constant.
Type const == AC_TODOT Convert source address structure to human readable string.
Type const == AC_TOADDR6 Convert source string (host:port or ipv6 address [n:n...:n]:port) to an address struct
Type const == AC_TOADDR Convert source string (host:port or ipv4 dotted decimal address) to an address struct
*/
extern int SIaddress( void *src, void **dest, int type ) {
- struct sockaddr_in *addr; // pointer to the address
- unsigned char *num; // pointer at the address number
- char wbuf[256]; // work buffer
- int i;
+ struct sockaddr_in *addr; // pointer to the address
+ struct sockaddr_in6 *addr6; // ip6 has a different layout
+ unsigned char *num; // pointer at the address number
+ uint8_t* byte; // pointer at the ipv6 address byte values
+ char wbuf[256]; // work buffer
+ int i;
int rlen = 0; // return len - len of address struct or string
+ if( src == NULL || dest == NULL ) {
+ return rlen;
+ }
+
switch( type ) {
case AC_TODOT: // convert from a struct to human readable "dotted decimal"
- addr = (struct sockaddr_in *) src;
- num = (char *) &addr->sin_addr.s_addr; // point at the long
+ addr = (struct sockaddr_in *) src;
if( addr->sin_family == AF_INET6 ) {
- sprintf( wbuf, "[%u:%u:%u:%u:%u:%u]:%d",
- *(num+0), *(num+1), *(num+2),
- *(num+3), *(num+4), *(num+5) ,
- (int) ntohs( addr->sin_port ) );
+ addr6 = (struct sockaddr_in6 *) src; // really an ip6 struct
+ byte = (uint8_t *) &addr6->sin6_addr;
+ snprintf( wbuf, sizeof( wbuf ), "[%u:%u:%u:%u:%u:%u]:%d",
+ *(byte+0), *(byte+1), *(byte+2),
+ *(byte+3), *(byte+4), *(byte+5) ,
+ (int) ntohs( addr6->sin6_port ) );
} else {
- sprintf( wbuf, "%u.%u.%u.%u;%d", *(num+0), *(num+1), *(num+2), *(num+3), (int) ntohs(addr->sin_port) );
+ num = (char *) &addr->sin_addr.s_addr; // point at the long
+ snprintf( wbuf, sizeof( wbuf ), "%u.%u.%u.%u:%d", *(num+0), *(num+1), *(num+2), *(num+3), (int) ntohs(addr->sin_port) );
}
*dest = (void *) strdup( wbuf );
rlen = strlen( *dest );
break;
- case AC_TOADDR6: // from hostname;port string to address for send etc
- return SIgenaddr( src, PF_INET6, IPPROTO_TCP, SOCK_STREAM, (struct sockaddr **) dest );
- break;
+ case AC_TOADDR6: // from hostname:port string to address for send etc
+ return SIgenaddr( src, IPPROTO_TCP, AF_INET6, SOCK_STREAM, (struct sockaddr **) dest );
- case AC_TOADDR: // from dotted decimal to address struct ip4
- return SIgenaddr( src, PF_INET, IPPROTO_TCP, SOCK_STREAM, (struct sockaddr **) dest );
- break;
+ case AC_TOADDR: // from dotted decimal to address struct ip4
+ return SIgenaddr( src, IPPROTO_TCP, AF_INET, SOCK_STREAM, (struct sockaddr **) dest );
}
return rlen;