diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/dktools/dk4sock06.c |
Initial commit
Diffstat (limited to 'support/dktools/dk4sock06.c')
-rw-r--r-- | support/dktools/dk4sock06.c | 629 |
1 files changed, 629 insertions, 0 deletions
diff --git a/support/dktools/dk4sock06.c b/support/dktools/dk4sock06.c new file mode 100644 index 0000000000..81f617a0ee --- /dev/null +++ b/support/dktools/dk4sock06.c @@ -0,0 +1,629 @@ +/* + WARNING: This file was generated by dkct. + Changes you make here will be lost if dkct is run again! + You should modify the original source and run dkct on it. + Original source: dk4sock06.ctr +*/ + +/* +Copyright (C) 2015-2017, Dirk Krause + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above opyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. +* Neither the name of the author nor the names of contributors may be used + to endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``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 COPYRIGHT OWNER OR CONTRIBUTORS 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. +*/ + +/** @file dk4sock06.c The dk4sock06 module. +*/ + + +#line 10 "dk4sock06.ctr" + +#include "dk4sock.h" +#include "dk4maaul.h" +#include "dk4maaus.h" + + + + + +#line 18 "dk4sock06.ctr" + + + +#if !DK4_HAVE_INET_PTON + +/** Character classes. +*/ +enum { + /** Any character not rom the types below. + */ + INPUT_ANY = 0 , + + /** Digit. + */ + INPUT_DIGIT , + + /** Separator (dot for IPv4, colon for IPv6). + */ + INPUT_SEP , + + /** End of input reached. + */ + INPUT_END +}; + +/** States while reading IPv4. +*/ +enum { + /** Nothing processed yet. + */ + S4_INIT = 0 , + + /** Previous character was a separator. + */ + S4_SEP , + + /** Previous character was digit. + */ + S4_DIG , + + /** Successfully finished IP address retrieval. + */ + S4_FINISHED , + + /** Error found in previous input. + */ + S4_ERROR +}; + +static +int +dk4socket_classify_input_char( + char c, + int ipv6, + unsigned short *valptr +) +{ + int back = INPUT_ANY; + switch (c) { + case ':' : { + if (0 != ipv6) { back = INPUT_SEP; } + } break; + case '.' : { + if (0 == ipv6) { back = INPUT_SEP; } + } break; + case '0': { back = INPUT_DIGIT; *valptr = 0; } break; + case '1': { back = INPUT_DIGIT; *valptr = 1; } break; + case '2': { back = INPUT_DIGIT; *valptr = 2; } break; + case '3': { back = INPUT_DIGIT; *valptr = 3; } break; + case '4': { back = INPUT_DIGIT; *valptr = 4; } break; + case '5': { back = INPUT_DIGIT; *valptr = 5; } break; + case '6': { back = INPUT_DIGIT; *valptr = 6; } break; + case '7': { back = INPUT_DIGIT; *valptr = 7; } break; + case '8': { back = INPUT_DIGIT; *valptr = 8; } break; + case '9': { back = INPUT_DIGIT; *valptr = 9; } break; + case 'a': { + if (0 != ipv6) { back = INPUT_DIGIT; *valptr = 10; } + } break; + case 'A': { + if (0 != ipv6) { back = INPUT_DIGIT; *valptr = 10; } + } break; + case 'b': { + if (0 != ipv6) { back = INPUT_DIGIT; *valptr = 11; } + } break; + case 'B': { + if (0 != ipv6) { back = INPUT_DIGIT; *valptr = 11; } + } break; + case 'c': { + if (0 != ipv6) { back = INPUT_DIGIT; *valptr = 12; } + } break; + case 'C': { + if (0 != ipv6) { back = INPUT_DIGIT; *valptr = 12; } + } break; + case 'd': { + if (0 != ipv6) { back = INPUT_DIGIT; *valptr = 13; } + } break; + case 'D': { + if (0 != ipv6) { back = INPUT_DIGIT; *valptr = 13; } + } break; + case 'e': { + if (0 != ipv6) { back = INPUT_DIGIT; *valptr = 14; } + } break; + case 'E': { + if (0 != ipv6) { back = INPUT_DIGIT; *valptr = 14; } + } break; + case 'f': { + if (0 != ipv6) { back = INPUT_DIGIT; *valptr = 15; } + } break; + case 'F': { + if (0 != ipv6) { back = INPUT_DIGIT; *valptr = 15; } + } break; + } + return back; +} + +#if DK4_HAVE_STRUCT_SOCKADDR_IN6 + + +/** States while reading IPv4. +*/ +enum { + /** Nothing processed yet. + */ + S6_INIT = 0 , + + /** Previous character was a separator. + */ + S6_SEP , + + /** Previous two characters were separators. + */ + S6_DSEP , + + /** Previous character was digit. + */ + S6_DIG , + + /** Successfully finished IP address retrieval. + */ + S6_FINISHED , + + /** Error found in previous input. + */ + S6_ERROR +}; + +static +int +dk4socket_my_ip6_pton( + void *pAddr, + size_t szAddr, + const char *src, + dk4_er_t *erp +) +{ + dk4_er_t er; + unsigned short left[8]; /* Values for left side */ + unsigned short right[8]; /* Values for right side */ + struct in6_addr *inp6 = NULL; /* Result */ + int isright = 0; /* Flag: Already on right side */ + int hl = 0; /* Number of values on left side */ + int hr = 0; /* Number of values on right side */ + int icl = 0; /* Input character class */ + int cc = 1; /* Flag: Can continue */ + int st = S6_INIT; /* Current state */ + int back = DK4_SOCKET_RESULT_FAILED; + int i = 0; /* Index to fill address */ + unsigned short curval = 0; /* Value collected so far */ + unsigned short us = 0; /* Current character value */ + + do { + if ('\0' == *src) { + icl = INPUT_END; + } else { + icl = dk4socket_classify_input_char(*src, 1, &us); + } + switch (st) { + case S6_INIT : { + switch (icl) { + case INPUT_DIGIT : { + curval = us; + st = S6_DIG; + } break; + case INPUT_SEP : { + st = S6_SEP; + } break; + default : { + st = S6_ERROR; + cc = -1; + } break; + } + } break; + case S6_SEP : { + switch (icl) { + case INPUT_DIGIT : { + curval = us; + st = S6_DIG; + } break; + case INPUT_SEP : { + st = S6_DSEP; + if (0 == isright) { + isright = 1; + } else { + st = S6_ERROR; + cc = -1; + } + } break; + default : { + st = S6_ERROR; + cc = -1; + } break; + } + } break; + case S6_DSEP : { + switch (icl) { + case INPUT_DIGIT : { + curval = us; + st = S6_DIG; + } break; + case INPUT_END : { + st = S6_FINISHED; + } break; + default : { + st = S6_ERROR; + cc = -1; + } break; + } + } break; + case S6_DIG : { + switch (icl) { + case INPUT_DIGIT : { + dk4error_init(&er); + curval = dk4ma_ushort_add( + dk4ma_ushort_mul(curval, 16UL, &er), + us, &er + ); + if (DK4_E_NONE != er.ec) { + st = S6_ERROR; + cc = -1; + } + } break; + case INPUT_SEP : { + if (0 != isright) { + if (8 > hr) { + right[hr++] = curval; + st = S6_SEP; + } else { + st = S6_ERROR; + cc = -1; + } + } else { + if (8 > hl) { + left[hl++] = curval; + st = S6_SEP; + } else { + st = S6_ERROR; + cc = -1; + } + } + } break; + case INPUT_END : { + if (0 != isright) { + if (8 > hr) { + right[hr++] = curval; + st = S6_FINISHED; + cc = 0; + } else { + st = S6_ERROR; + cc = -1; + } + } else { + if (8 > hl) { + left[hl++] = curval; + st = S6_FINISHED; + cc = 0; + } else { + st = S6_ERROR; + cc = -1; + } + } + } break; + default : { + st = S6_ERROR; + cc = -1; + } break; + } + } break; + } + src++; + if ((1 == cc) && (INPUT_END == icl)) { cc = 0; } + } while (1 == cc); + if ((0 == cc) && (S6_FINISHED == st)) { + if (9 > (hl + hr)) { + inp6 = (struct in6_addr *)pAddr; + for (i = 0; i < 8; i++) { +#if DK4_ON_WINDOWS + inp6->u.Word[i] = dk4socket_htons(0); +#else + inp6->s6_addr16[i] = dk4socket_htons(0); +#endif + } + for (i = 0; i < hl; i++) { +#if DK4_ON_WINDOWS + inp6->u.Word[i] = dk4socket_htons(left[i]); +#else + inp6->s6_addr16[i] = dk4socket_htons(left[i]); +#endif + } + for (i = 0; i < hr; i++) { +#if DK4_ON_WINDOWS + inp6->u.Word[8 - hr + i ] = dk4socket_htons(right[i]); +#else + inp6->s6_addr16[8 - hr + i] = dk4socket_htons(right[i]); +#endif + } + back = DK4_SOCKET_RESULT_SUCCESS; + } else { + dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); + } + } else { + dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); + } + return back; +} + +#endif + +static +int +dk4socket_my_ip4_pton( + void *pAddr, + size_t szAddr, + const char *src, + dk4_er_t *erp +) +{ + dk4_er_t er; + struct in_addr *pin4; + unsigned long curval = 0UL; + unsigned long result = 0UL; + int back = DK4_SOCKET_RESULT_FAILED; + int cc = 1; + int icl = 0; + int st = S4_INIT; + int curnum = 0; + unsigned short us = 0; + + +#line 365 "dk4sock06.ctr" + do { + us = 0; + if ('\0' == *src) { + icl = INPUT_END; + } else { + icl = dk4socket_classify_input_char(*src, 0, &us); + } + switch (icl) { + case INPUT_DIGIT : { + switch (st) { + case S4_INIT: { + curval = (unsigned long)us; + st = S4_DIG; + } break; + case S4_SEP : { + curval = (unsigned long)us; + st = S4_DIG; + } break; + case S4_DIG : { + dk4error_init(&er); + curval = dk4ma_ulong_add( + dk4ma_ulong_mul(curval, 10UL, &er), + (unsigned long)us, + &er + ); + if (DK4_E_NONE != er.ec) { + st = S4_ERROR; + cc = -1; + } + } break; + } + } break; + case INPUT_SEP : { + switch (st) { + case S4_INIT: { + st = S4_ERROR; + cc = -1; + } break; + case S4_SEP : { + st = S4_ERROR; + cc = -1; + } break; + case S4_DIG : { + if (256UL > curval) { + switch (curnum++) { + case 0: { + result = ((curval << 24) & 0xFF000000UL); + st = S4_SEP; + curval = 0UL; + } break; + case 1: { + result |= ((curval << 16) & 0x00FF0000UL); + st = S4_SEP; + curval = 0UL; + } break; + case 2: { + result |= ((curval << 8) & 0x0000FF00UL); + st = S4_SEP; + curval = 0UL; + } break; + default: { + st = S4_ERROR; + cc = -1; + } break; + } + } else { + st = S4_ERROR; + cc = -1; + } + } break; + } + } break; + case INPUT_END : { + switch (st) { + case S4_INIT: { + st = S4_ERROR; + cc = -1; + } break; + case S4_SEP : { + st = S4_ERROR; + cc = -1; + } break; + case S4_DIG : { + st = S4_ERROR; + cc = -1; + if (3 == curnum) { + if (256UL > curval) { + result |= curval; + cc = 0; + st = S4_FINISHED; + } + } + } break; + } + } break; + default : { + st = S4_ERROR; + cc = -1; + } break; + } + src++; + } while(1 == cc); + if ((0 == cc) && (S4_FINISHED == st)) { + pin4 = (struct in_addr *)pAddr; + pin4->s_addr = dk4socket_htonl(result); + back = DK4_SOCKET_RESULT_FAILED; + + +#line 472 "dk4sock06.ctr" + } else { + dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); + + +#line 475 "dk4sock06.ctr" + } + + +#line 477 "dk4sock06.ctr" + return back; +} + +static +int +dk4socket_my_inet_pton( + void *pAddr, + size_t szAddr, + int afam, + const char *src, + dk4_er_t *erp +) +{ + int back = DK4_SOCKET_RESULT_FAILED; + +#if DK4_HAVE_STRUCT_SOCKADDR_IN6 + if (AF_INET6 == afam) { + back = dk4socket_my_ip6_pton(pAddr, szAddr, src, erp); + } else { +#endif + back = dk4socket_my_ip4_pton(pAddr, szAddr, src, erp); +#if DK4_HAVE_STRUCT_SOCKADDR_IN6 + } +#endif + return back; +} + +#endif + + +int +dk4socket_c8_inet_pton( + void *pAddr, + size_t szAddr, + int afam, + const char *src, + dk4_er_t *erp +) +{ +#if DK4_HAVE_INET_PTON + /* +++++ +inet_pton */ + int back = DK4_SOCKET_RESULT_FAILED; + int res; + if ((NULL != pAddr) && (0 < szAddr) && (NULL != src)) { + switch (afam) { + case AF_INET : { + if (sizeof(struct in_addr) == szAddr) { + back = DK4_SOCKET_RESULT_SUCCESS; + } + } break; +#if DK4_HAVE_STRUCT_SOCKADDR_IN6 + case AF_INET6 : { + if (sizeof(struct in6_addr) == szAddr) { + back = DK4_SOCKET_RESULT_SUCCESS; + } + } break; +#endif + } + if (DK4_SOCKET_RESULT_SUCCESS == back) { + back = DK4_SOCKET_RESULT_FAILED; + dk4socket_error_reset(); + res = inet_pton(afam, src, pAddr); + switch (res) { + case 0 : { + dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); + } break; + case -1 : { + dk4socket_error_report(erp, DK4_E_SOCKET_INET_PTON); + } break; + default : { + back = DK4_SOCKET_RESULT_SUCCESS; + } break; + } + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } + return back; + /* ----- +inet_pton */ +#else + /* +++++ -inet_pton */ + int back = DK4_SOCKET_RESULT_FAILED; + if ((NULL != pAddr) && (0 < szAddr) && (NULL != src)) { + switch (afam) { + case AF_INET : { + if (sizeof(struct in_addr) == szAddr) { + back = DK4_SOCKET_RESULT_SUCCESS; + } + } break; +#if DK4_HAVE_STRUCT_SOCKADDR_IN6 + case AF_INET6 : { + if (sizeof(struct in6_addr) == szAddr) { + back = DK4_SOCKET_RESULT_SUCCESS; + } + } break; +#endif + } + if (DK4_SOCKET_RESULT_SUCCESS == back) { + back = dk4socket_my_inet_pton(pAddr, szAddr, afam, src, erp); + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } + return back; + /* ----- -inet_pton */ +#endif +} + |