experimental socket address conversion function
This commit is contained in:
		@ -486,7 +486,7 @@ static int rtx_err_uchars (hawk_fmtout_t* fmtout, const hawk_uch_t* ptr, hawk_oo
 | 
				
			|||||||
	rtx->errmsg_len += len;
 | 
						rtx->errmsg_len += len;
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
	if (max <= 0) return 1;
 | 
						if (max <= 0) return 1;
 | 
				
			||||||
	hawk_conv_uchars_to_bchars_with_cmgr (ptr, &len, &rtx->_gem.errmsg[rtx->errmsg_len], &max, hawk_getcmgr(hawk));
 | 
						hawk_conv_uchars_to_bchars_with_cmgr (ptr, &len, &rtx->_gem.errmsg[rtx->errmsg_len], &max, hawk_rtx_getcmgr(rtx));
 | 
				
			||||||
	rtx->errmsg_len += max;
 | 
						rtx->errmsg_len += max;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	rtx->_gem.errmsg[rtx->errmsg_len] = '\0';
 | 
						rtx->_gem.errmsg[rtx->errmsg_len] = '\0';
 | 
				
			||||||
@ -572,3 +572,94 @@ void hawk_gem_seterrnum (hawk_gem_t* gem, const hawk_loc_t* errloc, hawk_errnum_
 | 
				
			|||||||
	gem->errmsg[0] = '\0';
 | 
						gem->errmsg[0] = '\0';
 | 
				
			||||||
	gem->errloc = (errloc? *errloc: _nullloc);
 | 
						gem->errloc = (errloc? *errloc: _nullloc);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int gem_err_bchars (hawk_fmtout_t* fmtout, const hawk_bch_t* ptr, hawk_oow_t len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						hawk_gem_t* gem = (hawk_gem_t*)fmtout->ctx;
 | 
				
			||||||
 | 
						hawk_oow_t max;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						max = HAWK_COUNTOF(gem->errmsg) - gem->errmsg_len - 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(HAWK_OOCH_IS_UCH)
 | 
				
			||||||
 | 
						if (max <= 0) return 1;
 | 
				
			||||||
 | 
						hawk_conv_bchars_to_uchars_with_cmgr (ptr, &len, &gem->errmsg[gem->errmsg_len], &max, gem->cmgr, 1);
 | 
				
			||||||
 | 
						gem->errmsg_len += max;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						if (len > max) len = max;
 | 
				
			||||||
 | 
						if (len <= 0) return 1;
 | 
				
			||||||
 | 
						HAWK_MEMCPY (&gem->errinf.msg[gem->errmsg_len], ptr, len * HAWK_SIZEOF(*ptr));
 | 
				
			||||||
 | 
						gem->errmsg_len += len;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gem->errmsg[gem->errmsg_len] = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 1; /* success */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int gem_err_uchars (hawk_fmtout_t* fmtout, const hawk_uch_t* ptr, hawk_oow_t len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						hawk_gem_t* gem = (hawk_gem_t*)fmtout->ctx;
 | 
				
			||||||
 | 
						hawk_oow_t max;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						max = HAWK_COUNTOF(gem->errmsg) - gem->errmsg_len - 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(HAWK_OOCH_IS_UCH)
 | 
				
			||||||
 | 
						if (len > max) len = max;
 | 
				
			||||||
 | 
						if (len <= 0) return 1;
 | 
				
			||||||
 | 
						HAWK_MEMCPY (&gem->errmsg[gem->errmsg_len], ptr, len * HAWK_SIZEOF(*ptr));
 | 
				
			||||||
 | 
						gem->errmsg_len += len;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						if (max <= 0) return 1;
 | 
				
			||||||
 | 
						hawk_conv_uchars_to_bchars_with_cmgr (ptr, &len, &gem->errmsg[gem->errmsg_len], &max, gem->cmgr);
 | 
				
			||||||
 | 
						gem->errmsg_len += max;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						gem->errmsg[gem->errmsg_len] = '\0';
 | 
				
			||||||
 | 
						return 1; /* success */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void hawk_gem_seterrbfmt (hawk_gem_t* gem, const hawk_loc_t* errloc, hawk_errnum_t errnum, const hawk_bch_t* errfmt, ...)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						va_list ap;
 | 
				
			||||||
 | 
						hawk_fmtout_t fo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*if (hawk->shuterr) return;*/
 | 
				
			||||||
 | 
						gem->errmsg_len = 0;
 | 
				
			||||||
 | 
						gem->errmsg[0] = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						HAWK_MEMSET (&fo, 0, HAWK_SIZEOF(fo));
 | 
				
			||||||
 | 
						fo.mmgr = hawk_gem_getmmgr(gem);
 | 
				
			||||||
 | 
						fo.putbchars = gem_err_bchars;
 | 
				
			||||||
 | 
						fo.putuchars = gem_err_uchars;
 | 
				
			||||||
 | 
						fo.ctx = gem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						va_start (ap, errfmt);
 | 
				
			||||||
 | 
						hawk_bfmt_outv (&fo, errfmt, ap);
 | 
				
			||||||
 | 
						va_end (ap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gem->errnum = errnum;
 | 
				
			||||||
 | 
						gem->errloc = (errloc? *errloc: _nullloc);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void hawk_gem_seterrufmt (hawk_gem_t* gem, const hawk_loc_t* errloc, hawk_errnum_t errnum, const hawk_uch_t* errfmt, ...)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						va_list ap;
 | 
				
			||||||
 | 
						hawk_fmtout_t fo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*if (hawk->shuterr) return;*/
 | 
				
			||||||
 | 
						gem->errmsg_len = 0;
 | 
				
			||||||
 | 
						gem->errmsg[0] = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						HAWK_MEMSET (&fo, 0, HAWK_SIZEOF(fo));
 | 
				
			||||||
 | 
						fo.mmgr = hawk_gem_getmmgr(gem);
 | 
				
			||||||
 | 
						fo.putbchars = gem_err_bchars;
 | 
				
			||||||
 | 
						fo.putuchars = gem_err_uchars;
 | 
				
			||||||
 | 
						fo.ctx = gem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						va_start (ap, errfmt);
 | 
				
			||||||
 | 
						hawk_ufmt_outv (&fo, errfmt, ap);
 | 
				
			||||||
 | 
						va_end (ap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gem->errnum = errnum;
 | 
				
			||||||
 | 
						gem->errloc =  (errloc? *errloc: _nullloc);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -927,13 +927,6 @@ struct hawk_loc_t
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
typedef struct hawk_loc_t hawk_loc_t;
 | 
					typedef struct hawk_loc_t hawk_loc_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef void (*hawk_assertfail_t) (
 | 
					 | 
				
			||||||
	hawk_gem_t*        gem,
 | 
					 | 
				
			||||||
	const hawk_bch_t*   expr,
 | 
					 | 
				
			||||||
	const hawk_bch_t*   file,
 | 
					 | 
				
			||||||
	hawk_oow_t          line
 | 
					 | 
				
			||||||
);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct hawk_gem_t
 | 
					struct hawk_gem_t
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	hawk_mmgr_t*  mmgr;
 | 
						hawk_mmgr_t*  mmgr;
 | 
				
			||||||
@ -941,9 +934,6 @@ struct hawk_gem_t
 | 
				
			|||||||
	hawk_errnum_t errnum;
 | 
						hawk_errnum_t errnum;
 | 
				
			||||||
	hawk_ooch_t   errmsg[HAWK_ERRMSG_CAPA];
 | 
						hawk_ooch_t   errmsg[HAWK_ERRMSG_CAPA];
 | 
				
			||||||
	hawk_loc_t    errloc;
 | 
						hawk_loc_t    errloc;
 | 
				
			||||||
#if defined(HAWK_BUILD_DEBUG)
 | 
					 | 
				
			||||||
	hawk_assertfail_t assertfail;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum hawk_log_mask_t
 | 
					enum hawk_log_mask_t
 | 
				
			||||||
 | 
				
			|||||||
@ -354,6 +354,33 @@ typedef int (*hawk_sort_comperx_t) (
 | 
				
			|||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* =========================================================================
 | 
				
			||||||
 | 
					 * SOCKET ADDRESS
 | 
				
			||||||
 | 
					 * ========================================================================= */
 | 
				
			||||||
 | 
					#define HAWK_SIZEOF_SKAD_T 1
 | 
				
			||||||
 | 
					#if (HAWK_SIZEOF_STRUCT_SOCKADDR_IN > HAWK_SIZEOF_SKAD_T)
 | 
				
			||||||
 | 
					#	undef HAWK_SIZEOF_SKAD_T
 | 
				
			||||||
 | 
					#	define HAWK_SIZEOF_SKAD_T HAWK_SIZEOF_STRUCT_SOCKADDR_IN
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#if (HAWK_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
 | 
				
			||||||
 | 
					#	undef HAWK_SIZEOF_SKAD_T
 | 
				
			||||||
 | 
					#	define HAWK_SIZEOF_SKAD_T HAWK_SIZEOF_STRUCT_SOCKADDR_IN6
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#if (HAWK_SIZEOF_STRUCT_SOCKADDR_LL > 0)
 | 
				
			||||||
 | 
					#	undef HAWK_SIZEOF_SKAD_T
 | 
				
			||||||
 | 
					#	define HAWK_SIZEOF_SKAD_T HAWK_SIZEOF_STRUCT_SOCKADDR_LL
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#if (HAWK_SIZEOF_STRUCT_SOCKADDR_UN > 0)
 | 
				
			||||||
 | 
					#	undef HAWK_SIZEOF_SKAD_T
 | 
				
			||||||
 | 
					#	define HAWK_SIZEOF_SKAD_T HAWK_SIZEOF_STRUCT_SOCKADDR_UN
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct hawk_skad_t
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						hawk_uint8_t data[HAWK_SIZEOF_SKAD_T];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					typedef struct hawk_skad_t hawk_skad_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(__cplusplus)
 | 
					#if defined(__cplusplus)
 | 
				
			||||||
extern "C" {
 | 
					extern "C" {
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@ -1542,6 +1569,16 @@ HAWK_EXPORT void hawk_sub_time (
 | 
				
			|||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* =========================================================================
 | 
				
			||||||
 | 
					 * SOCKET ADDRESS
 | 
				
			||||||
 | 
					 * ========================================================================= */
 | 
				
			||||||
 | 
					HAWK_EXPORT int hawk_oochars_to_skad (
 | 
				
			||||||
 | 
						hawk_t*            hawk,
 | 
				
			||||||
 | 
						const hawk_ooch_t* str,
 | 
				
			||||||
 | 
						hawk_oow_t         len,
 | 
				
			||||||
 | 
						hawk_skad_t*       skad
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* =========================================================================
 | 
					/* =========================================================================
 | 
				
			||||||
 * ASSERTION
 | 
					 * ASSERTION
 | 
				
			||||||
 * ========================================================================= */
 | 
					 * ========================================================================= */
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										442
									
								
								hawk/lib/utl-skad.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										442
									
								
								hawk/lib/utl-skad.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,442 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * $Id$
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					    Copyright (c) 2006-2019 Chung, Hyung-Hwan. All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Redistribution and use in source and binary forms, with or without
 | 
				
			||||||
 | 
					    modification, are permitted provided that the following conditions
 | 
				
			||||||
 | 
					    are met:
 | 
				
			||||||
 | 
					    1. Redistributions of source code must retain the above copyright
 | 
				
			||||||
 | 
					       notice, this list of conditions and the following disclaimer.
 | 
				
			||||||
 | 
					    2. Redistributions in binary form must reproduce the above copyright
 | 
				
			||||||
 | 
					       notice, this list of conditions and the following disclaimer in the
 | 
				
			||||||
 | 
					       documentation and/or other materials provided with the distribution.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
 | 
				
			||||||
 | 
					    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 | 
				
			||||||
 | 
					    OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 | 
				
			||||||
 | 
					    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
				
			||||||
 | 
					    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 | 
				
			||||||
 | 
					    NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
				
			||||||
 | 
					    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
				
			||||||
 | 
					    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
				
			||||||
 | 
					    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 | 
				
			||||||
 | 
					    THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <hawk-utl.h>
 | 
				
			||||||
 | 
					#include "hawk-prv.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					#include <sys/socket.h>
 | 
				
			||||||
 | 
					#if defined(HAVE_NETINET_IN_H)
 | 
				
			||||||
 | 
					#	include <netinet/in.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#if defined(HAVE_SYS_UN_H)
 | 
				
			||||||
 | 
					#	include <sys/un.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#if defined(HAVE_NETPACKET_PACKET_H)
 | 
				
			||||||
 | 
					#	include <netpacket/packet.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#if defined(HAVE_NET_IF_DL_H)
 | 
				
			||||||
 | 
					#	include <net/if_dl.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					union hawk_skad_alt_t
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct sockaddr    sa;
 | 
				
			||||||
 | 
					#if (HAWK_SIZEOF_STRUCT_SOCKADDR_IN > 0)
 | 
				
			||||||
 | 
						struct sockaddr_in in4;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#if (HAWK_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
 | 
				
			||||||
 | 
						struct sockaddr_in6 in6;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#if (HAWK_SIZEOF_STRUCT_SOCKADDR_LL > 0)
 | 
				
			||||||
 | 
						struct sockaddr_ll ll;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#if (HAWK_SIZEOF_STRUCT_SOCKADDR_UN > 0)
 | 
				
			||||||
 | 
						struct sockaddr_un un;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					typedef union hawk_skad_alt_t hawk_skad_alt_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int str_to_ipv4 (const hawk_ooch_t* str, hawk_oow_t len, struct in_addr* inaddr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const hawk_ooch_t* end;
 | 
				
			||||||
 | 
						int dots = 0, digits = 0;
 | 
				
			||||||
 | 
						hawk_uint32_t acc = 0, addr = 0;
 | 
				
			||||||
 | 
						hawk_ooch_t c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						end = str + len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						do
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (str >= end)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if (dots < 3 || digits == 0) return -1;
 | 
				
			||||||
 | 
								addr = (addr << 8) | acc;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							c = *str++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (c >= '0' && c <= '9') 
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if (digits > 0 && acc == 0) return -1;
 | 
				
			||||||
 | 
								acc = acc * 10 + (c - '0');
 | 
				
			||||||
 | 
								if (acc > 255) return -1;
 | 
				
			||||||
 | 
								digits++;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else if (c == '.') 
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if (dots >= 3 || digits == 0) return -1;
 | 
				
			||||||
 | 
								addr = (addr << 8) | acc;
 | 
				
			||||||
 | 
								dots++; acc = 0; digits = 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						while (1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						inaddr->s_addr = hawk_hton32(addr);
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if (HAWK_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
 | 
				
			||||||
 | 
					static int str_to_ipv6 (const hawk_ooch_t* src, hawk_oow_t len, struct in6_addr* inaddr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						hawk_uint8_t* tp, * endp, * colonp;
 | 
				
			||||||
 | 
						const hawk_ooch_t* curtok;
 | 
				
			||||||
 | 
						hawk_ooch_t ch;
 | 
				
			||||||
 | 
						int saw_xdigit;
 | 
				
			||||||
 | 
						unsigned int val;
 | 
				
			||||||
 | 
						const hawk_ooch_t* src_end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						src_end = src + len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						HAWK_MEMSET (inaddr, 0, HAWK_SIZEOF(*inaddr));
 | 
				
			||||||
 | 
						tp = &inaddr->s6_addr[0];
 | 
				
			||||||
 | 
						endp = &inaddr->s6_addr[HAWK_COUNTOF(inaddr->s6_addr)];
 | 
				
			||||||
 | 
						colonp = HAWK_NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Leading :: requires some special handling. */
 | 
				
			||||||
 | 
						if (src < src_end && *src == ':')
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							src++;
 | 
				
			||||||
 | 
							if (src >= src_end || *src != ':') return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						curtok = src;
 | 
				
			||||||
 | 
						saw_xdigit = 0;
 | 
				
			||||||
 | 
						val = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (src < src_end)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							int v1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ch = *src++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (ch >= '0' && ch <= '9')
 | 
				
			||||||
 | 
								v1 = ch - '0';
 | 
				
			||||||
 | 
							else if (ch >= 'A' && ch <= 'F')
 | 
				
			||||||
 | 
								v1 = ch - 'A' + 10;
 | 
				
			||||||
 | 
							else if (ch >= 'a' && ch <= 'f')
 | 
				
			||||||
 | 
								v1 = ch - 'a' + 10;
 | 
				
			||||||
 | 
							else v1 = -1;
 | 
				
			||||||
 | 
							if (v1 >= 0)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								val <<= 4;
 | 
				
			||||||
 | 
								val |= v1;
 | 
				
			||||||
 | 
								if (val > 0xffff) return -1;
 | 
				
			||||||
 | 
								saw_xdigit = 1;
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (ch == ':') 
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								curtok = src;
 | 
				
			||||||
 | 
								if (!saw_xdigit) 
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									if (colonp) return -1;
 | 
				
			||||||
 | 
									colonp = tp;
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else if (src >= src_end)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									/* a colon can't be the last character */
 | 
				
			||||||
 | 
									return -1;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								*tp++ = (hawk_uint8_t)(val >> 8) & 0xff;
 | 
				
			||||||
 | 
								*tp++ = (hawk_uint8_t)val & 0xff;
 | 
				
			||||||
 | 
								saw_xdigit = 0;
 | 
				
			||||||
 | 
								val = 0;
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (ch == '.' && ((tp + HAWK_SIZEOF(struct in_addr)) <= endp) &&
 | 
				
			||||||
 | 
							    str_to_ipv4(curtok, src_end - curtok, (struct in_addr*)tp) == 0) 
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								tp += HAWK_SIZEOF(struct in_addr*);
 | 
				
			||||||
 | 
								saw_xdigit = 0;
 | 
				
			||||||
 | 
								break; 
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (saw_xdigit) 
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (tp + HAWK_SIZEOF(hawk_uint16_t) > endp) return -1;
 | 
				
			||||||
 | 
							*tp++ = (hawk_uint8_t)(val >> 8) & 0xff;
 | 
				
			||||||
 | 
							*tp++ = (hawk_uint8_t)val & 0xff;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (colonp != HAWK_NULL) 
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
							 * Since some memmove()'s erroneously fail to handle
 | 
				
			||||||
 | 
							 * overlapping regions, we'll do the shift by hand.
 | 
				
			||||||
 | 
							 */
 | 
				
			||||||
 | 
							hawk_oow_t n = tp - colonp;
 | 
				
			||||||
 | 
							hawk_oow_t i;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
							for (i = 1; i <= n; i++) 
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								endp[-i] = colonp[n - i];
 | 
				
			||||||
 | 
								colonp[n - i] = 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							tp = endp;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (tp != endp) return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int hawk_oochars_to_skad (hawk_t* hawk, const hawk_ooch_t* str, hawk_oow_t len, hawk_skad_t* _skad)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						hawk_skad_alt_t* skad = (hawk_skad_alt_t*)_skad;
 | 
				
			||||||
 | 
						const hawk_ooch_t* p;
 | 
				
			||||||
 | 
						const hawk_ooch_t* end;
 | 
				
			||||||
 | 
						hawk_oocs_t tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p = str;
 | 
				
			||||||
 | 
						end = str + len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (p >= end) 
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							hawk_seterrbfmt (hawk, HAWK_EINVAL, "blank address");
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						HAWK_MEMSET (skad, 0, HAWK_SIZEOF(*skad));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(AF_UNIX)
 | 
				
			||||||
 | 
						if (*p == '/' && len >= 2)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
						#if defined(HAWK_OOCH_IS_BCH)
 | 
				
			||||||
 | 
							hawk_copy_bcstr (skad->un.sun_path, HAWK_COUNTOF(skad->un.sun_path), str);
 | 
				
			||||||
 | 
						#else
 | 
				
			||||||
 | 
							hawk_oow_t dstlen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							dstlen = HAWK_COUNTOF(skad->un.sun_path) - 1;
 | 
				
			||||||
 | 
							if (hawk_convutobchars(hawk, p, &len, skad->un.sun_path, &dstlen) <= -1) 
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								hawk_seterrbfmt (hawk, HAWK_EINVAL, "unable to convert encoding");
 | 
				
			||||||
 | 
								return -1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							skad->un.sun_path[dstlen] = '\0';
 | 
				
			||||||
 | 
						#endif
 | 
				
			||||||
 | 
							skad->un.sun_family = AF_UNIX;
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if (HAWK_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
 | 
				
			||||||
 | 
						if (*p == '[')
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							/* IPv6 address */
 | 
				
			||||||
 | 
							tmp.ptr = (hawk_ooch_t*)++p; /* skip [ and remember the position */
 | 
				
			||||||
 | 
							while (p < end && *p != '%' && *p != ']') p++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (p >= end) goto no_rbrack;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							tmp.len = p - tmp.ptr;
 | 
				
			||||||
 | 
							if (*p == '%')
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								/* handle scope id */
 | 
				
			||||||
 | 
								hawk_uint32_t x;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								p++; /* skip % */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (p >= end)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									/* premature end */
 | 
				
			||||||
 | 
									hawk_seterrbfmt (hawk, HAWK_EINVAL, "scope id blank");
 | 
				
			||||||
 | 
									return -1;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (*p >= '0' && *p <= '9') 
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									/* numeric scope id */
 | 
				
			||||||
 | 
									skad->in6.sin6_scope_id = 0;
 | 
				
			||||||
 | 
									do
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										x = skad->in6.sin6_scope_id * 10 + (*p - '0');
 | 
				
			||||||
 | 
										if (x < skad->in6.sin6_scope_id) 
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											hawk_seterrbfmt (hawk, HAWK_EINVAL, "scope id too large");
 | 
				
			||||||
 | 
											return -1; /* overflow */
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										skad->in6.sin6_scope_id = x;
 | 
				
			||||||
 | 
										p++;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									while (p < end && *p >= '0' && *p <= '9');
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
					#if 0
 | 
				
			||||||
 | 
					TODO:
 | 
				
			||||||
 | 
									/* interface name as a scope id? */
 | 
				
			||||||
 | 
									const hawk_ooch_t* stmp = p;
 | 
				
			||||||
 | 
									unsigned int index;
 | 
				
			||||||
 | 
									do p++; while (p < end && *p != ']');
 | 
				
			||||||
 | 
									if (hawk_nwifwcsntoindex(stmp, p - stmp, &index) <= -1) return -1;
 | 
				
			||||||
 | 
									tmpad.u.in6.scope = index;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (p >= end || *p != ']') goto no_rbrack;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							p++; /* skip ] */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (str_to_ipv6(tmp.ptr, tmp.len, &skad->in6.sin6_addr) <= -1) goto unrecog;
 | 
				
			||||||
 | 
							skad->in6.sin6_family = AF_INET6;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
							/* IPv4 address */
 | 
				
			||||||
 | 
							tmp.ptr = (hawk_ooch_t*)p;
 | 
				
			||||||
 | 
							while (p < end && *p != ':') p++;
 | 
				
			||||||
 | 
							tmp.len = p - tmp.ptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (str_to_ipv4(tmp.ptr, tmp.len, &skad->in4.sin_addr) <= -1)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
							#if (HAWK_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
 | 
				
			||||||
 | 
								/* check if it is an IPv6 address not enclosed in []. 
 | 
				
			||||||
 | 
								 * the port number can't be specified in this format. */
 | 
				
			||||||
 | 
								if (p >= end || *p != ':') 
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									/* without :, it can't be an ipv6 address */
 | 
				
			||||||
 | 
									goto unrecog;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								while (p < end && *p != '%') p++;
 | 
				
			||||||
 | 
								tmp.len = p - tmp.ptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (str_to_ipv6(tmp.ptr, tmp.len, &skad->in6.sin6_addr) <= -1) goto unrecog;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (p < end && *p == '%')
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									/* handle scope id */
 | 
				
			||||||
 | 
									hawk_uint32_t x;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									p++; /* skip % */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									if (p >= end)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										/* premature end */
 | 
				
			||||||
 | 
										hawk_seterrbfmt (hawk, HAWK_EINVAL, "scope id blank");
 | 
				
			||||||
 | 
										return -1;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									if (*p >= '0' && *p <= '9') 
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										/* numeric scope id */
 | 
				
			||||||
 | 
										skad->in6.sin6_scope_id = 0;
 | 
				
			||||||
 | 
										do
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											x = skad->in6.sin6_scope_id * 10 + (*p - '0');
 | 
				
			||||||
 | 
											if (x < skad->in6.sin6_scope_id) 
 | 
				
			||||||
 | 
											{
 | 
				
			||||||
 | 
												hawk_seterrbfmt (hawk, HAWK_EINVAL, "scope id too large");
 | 
				
			||||||
 | 
												return -1; /* overflow */
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
											skad->in6.sin6_scope_id = x;
 | 
				
			||||||
 | 
											p++;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										while (p < end && *p >= '0' && *p <= '9');
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									else
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
					#if 0
 | 
				
			||||||
 | 
					TODO
 | 
				
			||||||
 | 
										/* interface name as a scope id? */
 | 
				
			||||||
 | 
										const hawk_ooch_t* stmp = p;
 | 
				
			||||||
 | 
										unsigned int index;
 | 
				
			||||||
 | 
										do p++; while (p < end);
 | 
				
			||||||
 | 
										if (hawk_nwifwcsntoindex (stmp, p - stmp, &index) <= -1) return -1;
 | 
				
			||||||
 | 
										skad->in6.sin6_scope_id = index;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (p < end) goto unrecog; /* some gargage after the end? */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								skad->in6.sin6_family = AF_INET6;
 | 
				
			||||||
 | 
								return 0;
 | 
				
			||||||
 | 
							#else
 | 
				
			||||||
 | 
								goto unrecog;
 | 
				
			||||||
 | 
							#endif
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							skad->in4.sin_family = AF_INET;
 | 
				
			||||||
 | 
					#if (HAWK_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (p < end && *p == ':') 
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							/* port number */
 | 
				
			||||||
 | 
							hawk_uint32_t port = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							p++; /* skip : */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							tmp.ptr = (hawk_ooch_t*)p;
 | 
				
			||||||
 | 
							while (p < end && *p >= '0' && *p <= '9')
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								port = port * 10 + (*p - '0');
 | 
				
			||||||
 | 
								p++;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							tmp.len = p - tmp.ptr;
 | 
				
			||||||
 | 
							if (tmp.len <= 0 || tmp.len >= 6 || 
 | 
				
			||||||
 | 
							    port > HAWK_TYPE_MAX(hawk_uint16_t)) 
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								hawk_seterrbfmt (hawk, HAWK_EINVAL, "port number blank or too large");
 | 
				
			||||||
 | 
								return -1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#if (HAWK_SIZEOF_STRUCT_SOCKADDR_IN6 > 0)
 | 
				
			||||||
 | 
							if (skad->in4.sin_family == AF_INET)
 | 
				
			||||||
 | 
								skad->in4.sin_port = hawk_hton16(port);
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								skad->in6.sin6_port = hawk_hton16(port);
 | 
				
			||||||
 | 
						#else
 | 
				
			||||||
 | 
							skad->in4.sin_port = hawk_hton16(port);
 | 
				
			||||||
 | 
						#endif
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unrecog:
 | 
				
			||||||
 | 
						hawk_seterrbfmt (hawk, HAWK_EINVAL, "unrecognized address");
 | 
				
			||||||
 | 
						return -1;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					no_rbrack:
 | 
				
			||||||
 | 
						hawk_seterrbfmt (hawk, HAWK_EINVAL, "missing right bracket");
 | 
				
			||||||
 | 
						return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user