changer/OS/uc/tcpip/Source/net_ascii.c
Dmitriy 5fe1e5d358 первый коммит
первый коммит
2021-02-08 21:10:39 +03:00

823 lines
38 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
*********************************************************************************************************
* uC/TCP-IP
* The Embedded TCP/IP Suite
*
* (c) Copyright 2003-2007; Micrium, Inc.; Weston, FL
*
* All rights reserved. Protected by international copyright laws.
*
* uC/TCP-IP is provided in source form for FREE evaluation, for educational
* use or peaceful research. If you plan on using uC/TCP-IP in a commercial
* product you need to contact Micrium to properly license its use in your
* product. We provide ALL the source code for your convenience and to help
* you experience uC/TCP-IP. The fact that the source code is provided does
* NOT mean that you can use it without paying a licensing fee.
*
* Knowledge of the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the Embedded community with the finest
* software available. Your honesty is greatly appreciated.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
*
* NETWORK ASCII LIBRARY
*
* Filename : net_ascii.c
* Version : V1.89
* Programmer(s) : ITJ
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* INCLUDE FILES
*********************************************************************************************************
*/
#define NET_ASCII_MODULE
#include <net.h>
/*$PAGE*/
/*
*********************************************************************************************************
* LOCAL DEFINES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL CONSTANTS
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL DATA TYPES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL TABLES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL GLOBAL VARIABLES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL FUNCTION PROTOTYPES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL CONFIGURATION ERRORS
*********************************************************************************************************
*/
/*$PAGE*/
/*
*********************************************************************************************************
* NetASCII_Str_to_MAC()
*
* Description : Convert a MAC address ASCII string to a MAC address.
*
* Argument(s) : paddr_mac_ascii Pointer to an ASCII string that contains a MAC address (see Note #1).
*
* paddr_mac Pointer to a memory buffer that will receive the converted MAC address
* (see Note #2) :
*
* MAC address represented by ASCII string, if NO errors.
*
* MAC address cleared to all zeros (see Note #2c), otherwise.
*
* perr Pointer to variable that will receive the return error code from this function :
*
* NET_ASCII_ERR_NONE MAC address successfully converted.
* NET_ASCII_ERR_NULL_PTR Argument 'paddr_mac_ascii'/'paddr_mac'
* passed a NULL pointer.
* NET_ASCII_ERR_INVALID_LEN Invalid ASCII string length.
* NET_ASCII_ERR_INVALID_CHAR Invalid ASCII character.
* NET_ASCII_ERR_INVALID_CHAR_LEN Invalid ASCII character length.
* NET_ASCII_ERR_INVALID_CHAR_SEQ Invalid ASCII character sequence.
*
* Return(s) : none.
*
* Caller(s) : Application.
*
* This function is a network protocol suite application interface (API) function & MAY be
* called by application function(s).
*
* Note(s) : (1) (a) The MAC address ASCII string MUST :
*
* (1) Include ONLY hexadecimal values & the colon character (':') ; ALL other
* characters are trapped as invalid, including any leading or trailing
* characters.
*
* (2) (A) Include EXACTLY six hexadecimal values ...
* (B) ... separated ...
* (C) ... by EXACTLY five colon characters.
*
* (3) Ensure that each hexadecimal value's number of digits does NOT exceed
* the maximum number of digits, NET_ASCII_CHAR_MAX_OCTET_ADDR_MAC (2).
*
* (b) In other words, the MAC address ASCII string separates six hexadecimal octet
* values by the colon character (':'). Each hexadecimal value represents one
* octet of the MAC address starting with the most significant octet in network
* order.
*
* MAC Address Examples :
*
* MAC ADDRESS ASCII STRING HEXADECIMAL EQUIVALENT
*
* "00:1A:07:AC:22:09" = 0x001A07AC2209
* "76:4E:01:D2:8C:0B" = 0x764E01D28C0B
* "80:Db:fE:0b:34:52" = 0X80DBFE0B3452
* -- -- -- --
* ^ ^ ^ ^
* | | | |
* MSO LSO MSO LSO
*
* where
*
* MSO Most Significant Octet in MAC Address
* LSO Least Significant Octet in MAC Address
*
*
* (2) (a) The size of the memory buffer that will receive the returned MAC address MUST be
* greater than or equal to NET_ASCII_NBR_OCTET_ADDR_MAC.
*
* (b) MAC address accessed by octets in memory buffer array.
*
* (c) MAC address memory array cleared in case of any error(s).
*********************************************************************************************************
*/
/*$PAGE*/
void NetASCII_Str_to_MAC (CPU_CHAR *paddr_mac_ascii,
CPU_INT08U *paddr_mac,
NET_ERR *perr)
{
CPU_CHAR *pchar_cur;
CPU_CHAR *pchar_prev;
CPU_INT08U *paddr_cur;
CPU_INT16U addr_octet_val;
CPU_INT16U addr_octet_val_dig;
CPU_INT32U addr_nbr_octet;
CPU_INT08U addr_nbr_octet_dig;
/* -------------- VALIDATE PTRS --------------- */
if (paddr_mac == (CPU_INT08U *)0) {
*perr = NET_ASCII_ERR_NULL_PTR;
return;
}
if (paddr_mac_ascii == (CPU_CHAR *)0) {
Mem_Clr((void *)paddr_mac, /* Clr rtn addr on err (see Note #2c). */
(CPU_SIZE_T)NET_ASCII_NBR_OCTET_ADDR_MAC);
*perr = NET_ASCII_ERR_NULL_PTR;
return;
}
/*$PAGE*/
pchar_cur = (CPU_CHAR *)paddr_mac_ascii;
pchar_prev = (CPU_CHAR *)0;
paddr_cur = (CPU_INT08U *)paddr_mac;
addr_octet_val = 0x0000;
addr_nbr_octet = 0;
addr_nbr_octet_dig = 0;
while ((pchar_cur != (CPU_CHAR *)0) && /* Parse ALL non-NULL chars in ASCII str. */
(*pchar_cur != (CPU_CHAR )0)) {
switch (*pchar_cur) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
addr_nbr_octet_dig++; /* If nbr digs > max (see Note #1a3); ... */
if (addr_nbr_octet_dig > NET_ASCII_CHAR_MAX_OCTET_ADDR_MAC) {
Mem_Clr((void *)paddr_mac, /* ... clr rtn addr (see Note #2c) ... */
(CPU_SIZE_T)NET_ASCII_NBR_OCTET_ADDR_MAC);
*perr = NET_ASCII_ERR_INVALID_CHAR_LEN; /* ... & rtn err. */
return;
}
switch (*pchar_cur) { /* Convert ASCII char into hex val. */
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
addr_octet_val_dig = (CPU_INT16U)(*pchar_cur - '0');
break;
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
addr_octet_val_dig = (CPU_INT16U)(*pchar_cur - 'A' + 10);
break;
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
addr_octet_val_dig = (CPU_INT16U)(*pchar_cur - 'a' + 10);
break;
default: /* See Note #1a1. */
Mem_Clr((void *)paddr_mac, /* Clr rtn addr on err (see Note #2c). */
(CPU_SIZE_T)NET_ASCII_NBR_OCTET_ADDR_MAC);
*perr = NET_ASCII_ERR_INVALID_CHAR;
return; /* Prevent 'break NOT reachable' warning. */
}
/* Merge ASCII char into hex val. */
addr_octet_val *= 16;
addr_octet_val += addr_octet_val_dig;
break;
/*$PAGE*/
case ':':
if (pchar_prev == (CPU_CHAR *)0) { /* If NO prev char (see Note #1a2B); ... */
Mem_Clr((void *)paddr_mac, /* ... clr rtn addr (see Note #2c) ... */
(CPU_SIZE_T)NET_ASCII_NBR_OCTET_ADDR_MAC);
*perr = NET_ASCII_ERR_INVALID_CHAR_SEQ; /* ... & rtn err. */
return;
}
if (*pchar_prev == (CPU_CHAR)':') { /* If prev char a colon (see Note #1a2B); ... */
Mem_Clr((void *)paddr_mac, /* ... clr rtn addr (see Note #2c) ... */
(CPU_SIZE_T)NET_ASCII_NBR_OCTET_ADDR_MAC);
*perr = NET_ASCII_ERR_INVALID_CHAR_SEQ; /* ... & rtn err. */
return;
}
addr_nbr_octet++;
if (addr_nbr_octet >= NET_ASCII_NBR_OCTET_ADDR_MAC) { /* If nbr octets > max (see Note #1a2A); ... */
Mem_Clr((void *)paddr_mac, /* ... clr rtn addr (see Note #2c) ... */
(CPU_SIZE_T)NET_ASCII_NBR_OCTET_ADDR_MAC);
*perr = NET_ASCII_ERR_INVALID_LEN; /* ... & rtn err. */
return;
}
/* Merge hex octet val into MAC addr. */
*paddr_cur++ = (CPU_INT08U)addr_octet_val;
addr_octet_val = 0x0000;
addr_nbr_octet_dig = 0;
break;
default: /* See Note #1a1. */
Mem_Clr((void *)paddr_mac, /* Clr rtn addr on err (see Note #2c). */
(CPU_SIZE_T)NET_ASCII_NBR_OCTET_ADDR_MAC);
*perr = NET_ASCII_ERR_INVALID_CHAR;
return; /* Prevent 'break NOT reachable' warning. */
}
pchar_prev = pchar_cur;
pchar_cur++;
}
if (pchar_cur == (CPU_CHAR *)0) { /* If ANY NULL ptr in ASCII str; .. */
Mem_Clr((void *)paddr_mac, /* .. clr rtn addr (see Note #2c) .. */
(CPU_SIZE_T)NET_ASCII_NBR_OCTET_ADDR_MAC);
*perr = NET_ASCII_ERR_NULL_PTR; /* .. & rtn err. */
return;
}
if (*pchar_prev == (CPU_CHAR)':') { /* If last char a colon (see Note #1a2B); .. */
Mem_Clr((void *)paddr_mac, /* .. clr rtn addr (see Note #2c) .. */
(CPU_SIZE_T)NET_ASCII_NBR_OCTET_ADDR_MAC);
*perr = NET_ASCII_ERR_INVALID_CHAR_SEQ; /* .. & rtn err. */
return;
}
addr_nbr_octet++;
if (addr_nbr_octet != NET_ASCII_NBR_OCTET_ADDR_MAC) { /* If != nbr MAC addr octets (see Note #1a2A); */
Mem_Clr((void *)paddr_mac, /* .. clr rtn addr (see Note #2c) .. */
(CPU_SIZE_T)NET_ASCII_NBR_OCTET_ADDR_MAC);
*perr = NET_ASCII_ERR_INVALID_LEN; /* .. & rtn err. */
return;
}
/* Merge hex octet val into final MAC addr. */
*paddr_cur = (CPU_INT08U)addr_octet_val;
*perr = NET_ASCII_ERR_NONE;
}
/*$PAGE*/
/*
*********************************************************************************************************
* NetASCII_MAC_to_Str()
*
* Description : Convert a MAC address into a MAC address ASCII string.
*
* Argument(s) : paddr_mac Pointer to a memory buffer that contains the MAC address (see Note #2).
*
* paddr_mac_ascii Pointer to an ASCII character array that will receive the return MAC
* address ASCII string from this function (see Note #1).
*
* hex_lower_case Format alphabetic hexadecimal characters in lower case :
*
* DEF_NO Format alphabetic hexadecimal characters in upper case.
* DEF_YES Format alphabetic hexadecimal characters in lower case.
*
* perr Pointer to variable that will receive the return error code from this function :
*
* NET_ASCII_ERR_NONE ASCII string successfully formatted.
* NET_ASCII_ERR_NULL_PTR Argument 'paddr_mac'/'paddr_mac_ascii'
* passed a NULL pointer.
*
* Return(s) : none.
*
* Caller(s) : Application.
*
* This function is a network protocol suite application interface (API) function & MAY be
* called by application function(s).
*
* Note(s) : (1) (a) (1) The return MAC address ASCII string ...
*
* (A) Formats EXACTLY six hexadecimal values ...
* (B) ... separated ...
* (C) ... by EXACTLY five colon characters.
*
* (2) The size of the ASCII character array that will receive the returned MAC address
* ASCII string MUST be greater than or equal to NET_ASCII_LEN_MAX_ADDR_MAC.
*
* (b) In other words, the MAC address ASCII string separates six hexadecimal octet values
* by the colon character (':'). Each hexadecimal value represents one octet of the
* MAC address starting with the most significant octet in network order.
*
* MAC Address Examples :
*
* MAC ADDRESS ASCII STRING HEXADECIMAL EQUIVALENT
*
* "00:1A:07:AC:22:09" = 0x001A07AC2209
* "76:4E:01:D2:8C:0B" = 0x764E01D28C0B
* "80:Db:fE:0b:34:52" = 0X80DBFE0B3452
* -- -- -- --
* ^ ^ ^ ^
* | | | |
* MSO LSO MSO LSO
*
* where
*
* MSO Most Significant Octet in MAC Address
* LSO Least Significant Octet in MAC Address
*
*
* (2) (a) The size of the memory buffer that contains the MAC address MUST be greater than
* or equal to NET_ASCII_NBR_OCTET_ADDR_MAC.
*
* (b) MAC address accessed by octets in memory buffer array.
*********************************************************************************************************
*/
/*$PAGE*/
void NetASCII_MAC_to_Str (CPU_INT08U *paddr_mac,
CPU_CHAR *paddr_mac_ascii,
CPU_BOOLEAN hex_lower_case,
NET_ERR *perr)
{
CPU_CHAR *pchar;
CPU_INT08U *paddr;
CPU_INT08U addr_octet_nbr_shifts;
CPU_INT08U addr_octet_val;
CPU_INT08U addr_octet_dig_val;
CPU_INT08U i;
CPU_INT08U j;
/* -------------- VALIDATE PTRS --------------- */
if (paddr_mac == (CPU_INT08U *)0) {
*perr = NET_ASCII_ERR_NULL_PTR;
return;
}
if (paddr_mac_ascii == (CPU_CHAR *)0) {
*perr = NET_ASCII_ERR_NULL_PTR;
return;
}
paddr = paddr_mac;
pchar = paddr_mac_ascii;
for (i = NET_ASCII_NBR_OCTET_ADDR_MAC; i > 0; i--) { /* Parse ALL addr octets. */
addr_octet_val = *paddr;
for (j = NET_ASCII_CHAR_MAX_OCTET_ADDR_MAC; j > 0; j--) { /* Parse ALL octet's hex digs. */
/* Calc cur octet's hex dig val. */
addr_octet_nbr_shifts = (j - 1) * DEF_NIBBLE_NBR_BITS;
addr_octet_dig_val = (addr_octet_val >> addr_octet_nbr_shifts) & DEF_NIBBLE_MASK;
/* Insert octet hex val ASCII dig. */
if (addr_octet_dig_val < 10) {
*pchar++ = (CPU_CHAR)(addr_octet_dig_val + '0');
} else {
if (hex_lower_case != DEF_YES) {
*pchar++ = (CPU_CHAR)(addr_octet_dig_val - 10 + 'A');
} else {
*pchar++ = (CPU_CHAR)(addr_octet_dig_val - 10 + 'a');
}
}
}
if (i > 1) { /* If NOT on last octet, append a colon char. */
*pchar++ = ':';
}
paddr++;
}
*pchar = (CPU_CHAR)0; /* Append NULL char. */
*perr = NET_ASCII_ERR_NONE;
}
/*$PAGE*/
/*
*********************************************************************************************************
* NetASCII_Str_to_IP()
*
* Description : Convert an IPv4 address in ASCII dotted-decimal notation to a network protocol IPv4 address
* in host-order.
*
* Argument(s) : paddr_ip_ascii Pointer to an ASCII string that contains a dotted-decimal IPv4 address
* (see Note #2).
*
* perr Pointer to variable that will receive the return error code from this function :
*
* NET_ASCII_ERR_NONE IPv4 address successfully converted.
* NET_ASCII_ERR_NULL_PTR Argument 'paddr_ip_ascii' passed a
* NULL pointer.
* NET_ASCII_ERR_INVALID_LEN Invalid ASCII string length.
* NET_ASCII_ERR_INVALID_CHAR Invalid ASCII character.
* NET_ASCII_ERR_INVALID_CHAR_LEN Invalid ASCII character length.
* NET_ASCII_ERR_INVALID_CHAR_VAL Invalid ASCII character value.
* NET_ASCII_ERR_INVALID_CHAR_SEQ Invalid ASCII character sequence.
*
* Return(s) : Host-order IPv4 address represented by ASCII string, if NO errors.
*
* NET_IP_ADDR_NONE, otherwise.
*
* Caller(s) : Application.
*
* This function is a network protocol suite application interface (API) function & MAY be
* called by application function(s).
*
* Note(s) : (1) RFC #1983 states that "dotted decimal notation ... refers [to] IP addresses of the
* form A.B.C.D; where each letter represents, in decimal, one byte of a four byte IP
* address".
*
* In other words, the dotted-decimal notation separates four decimal octet values by
* the dot, or period, character ('.'). Each decimal value represents one octet of
* the IP address starting with the most significant octet in network order.
*
* IP Address Examples :
*
* DOTTED DECIMAL NOTATION HEXADECIMAL EQUIVALENT
*
* 127.0.0.1 = 0x7F000001
* 192.168.1.64 = 0xC0A80140
* 255.255.255.0 = 0xFFFFFF00
* --- - -- --
* ^ ^ ^ ^
* | | | |
* MSO LSO MSO LSO
*
* where
*
* MSO Most Significant Octet in Dotted Decimal IP Address
* LSO Least Significant Octet in Dotted Decimal IP Address
*
*
* (2) The dotted-decimal ASCII string MUST :
*
* (a) Include ONLY decimal values & the dot, or period, character ('.') ; ALL other
* characters are trapped as invalid, including any leading or trailing characters.
*
* (b) (1) Include EXACTLY four decimal values ...
* (2) ... separated ...
* (3) ... by EXACTLY three dot characters.
*
* (c) Ensure that each decimal value does NOT exceed the maximum octet value (i.e. 255).
*
* (d) Ensure that each decimal value's number of decimal digits, including leading zeros,
* does NOT exceed the maximum number of digits, NET_ASCII_CHAR_MAX_OCTET_ADDR_IP (3).
*********************************************************************************************************
*/
/*$PAGE*/
NET_IP_ADDR NetASCII_Str_to_IP (CPU_CHAR *paddr_ip_ascii,
NET_ERR *perr)
{
CPU_CHAR *pchar_cur;
CPU_CHAR *pchar_prev;
NET_IP_ADDR addr_ip;
CPU_INT16U addr_octet_val;
CPU_INT32U addr_nbr_octet;
CPU_INT08U addr_nbr_octet_dig;
/* --------------- VALIDATE PTR --------------- */
if (paddr_ip_ascii == (CPU_CHAR *)0) {
*perr = NET_ASCII_ERR_NULL_PTR;
return (NET_IP_ADDR_NONE);
}
pchar_cur = (CPU_CHAR *)paddr_ip_ascii;
pchar_prev = (CPU_CHAR *)0;
addr_ip = NET_IP_ADDR_NONE;
addr_octet_val = 0x0000;
addr_nbr_octet = 0;
addr_nbr_octet_dig = 0;
while ((pchar_cur != (CPU_CHAR *)0) && /* Parse ALL non-NULL chars in ASCII str. */
(*pchar_cur != (CPU_CHAR )0)) {
switch (*pchar_cur) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
addr_nbr_octet_dig++; /* If nbr digs > max (see Note #2d), ... */
if (addr_nbr_octet_dig > NET_ASCII_CHAR_MAX_OCTET_ADDR_IP) {
*perr = NET_ASCII_ERR_INVALID_CHAR_LEN; /* ... rtn err. */
return (NET_IP_ADDR_NONE);
}
/* Convert & merge ASCII char into decimal val. */
addr_octet_val *= (CPU_INT16U)10;
addr_octet_val += (CPU_INT16U)(*pchar_cur - '0');
if (addr_octet_val > NET_ASCII_VAL_MAX_OCTET_ADDR_IP) {/* If octet val > max (see Note #2c), ... */
*perr = NET_ASCII_ERR_INVALID_CHAR_VAL; /* ... rtn err. */
return (NET_IP_ADDR_NONE);
}
break;
case '.':
if (pchar_prev == (CPU_CHAR *)0) { /* If NO prev char (see Note #2b2), ... */
*perr = NET_ASCII_ERR_INVALID_CHAR_SEQ; /* ... rtn err. */
return (NET_IP_ADDR_NONE);
}
if (*pchar_prev == (CPU_CHAR)'.') { /* If prev char a dot (see Note #2b2), ... */
*perr = NET_ASCII_ERR_INVALID_CHAR_SEQ; /* ... rtn err. */
return (NET_IP_ADDR_NONE);
}
addr_nbr_octet++;
if (addr_nbr_octet >= NET_ASCII_NBR_OCTET_ADDR_IP) { /* If nbr octets > max (see Note #2b1), ... */
*perr = NET_ASCII_ERR_INVALID_LEN; /* ... rtn err. */
return (NET_IP_ADDR_NONE);
}
/* Merge decimal octet val into IP addr. */
addr_ip <<= DEF_OCTET_NBR_BITS;
addr_ip += (CPU_INT08U)addr_octet_val;
addr_octet_val = 0x0000;
addr_nbr_octet_dig = 0;
break;
default: /* See Note #2a. */
*perr = NET_ASCII_ERR_INVALID_CHAR;
return (NET_IP_ADDR_NONE); /* Prevent 'break NOT reachable' warning. */
}
pchar_prev = pchar_cur;
pchar_cur++;
}
/*$PAGE*/
if (pchar_cur == (CPU_CHAR *)0) { /* If ANY NULL ptr in ASCII str, .. */
*perr = NET_ASCII_ERR_NULL_PTR; /* .. rtn err. */
return (NET_IP_ADDR_NONE);
}
if (*pchar_prev == (CPU_CHAR)'.') { /* If last char a dot (see Note #2b2), .. */
*perr = NET_ASCII_ERR_INVALID_CHAR_SEQ; /* .. rtn err. */
return (NET_IP_ADDR_NONE);
}
addr_nbr_octet++;
if (addr_nbr_octet != NET_ASCII_NBR_OCTET_ADDR_IP) { /* If != nbr IP addr octets (see Note #2b1), .. */
*perr = NET_ASCII_ERR_INVALID_LEN; /* .. rtn err. */
return (NET_IP_ADDR_NONE);
}
/* Merge decimal octet val into final IP addr. */
addr_ip <<= DEF_OCTET_NBR_BITS;
addr_ip += (CPU_INT08U)addr_octet_val;
*perr = NET_ASCII_ERR_NONE;
return (addr_ip);
}
/*$PAGE*/
/*
*********************************************************************************************************
* NetASCII_IP_to_Str()
*
* Description : Convert a network protocol IPv4 address in host-order into a dotted-decimal notation ASCII
* string.
*
* Argument(s) : addr_ip IPv4 address.
*
* paddr_ip_ascii Pointer to an ASCII character array that will receive the return IP
* address ASCII string from this function (see Note #2).
*
* lead_zeros Prepend leading zeros option (see Note #3) :
*
* DEF_NO Do NOT prepend leading zeros to each decimal octet value.
* DEF_YES Prepend leading zeros to each decimal octet value.
*
* perr Pointer to variable that will receive the return error code from this function :
*
* NET_ASCII_ERR_NONE ASCII string successfully formatted.
* NET_ASCII_ERR_NULL_PTR Argument 'paddr_ip_ascii' passed a
* NULL pointer.
* NET_ASCII_ERR_INVALID_CHAR_LEN Invalid ASCII character length.
*
* Return(s) : none.
*
* Caller(s) : Application.
*
* This function is a network protocol suite application interface (API) function & MAY be
* called by application function(s).
*
* Note(s) : (1) RFC #1983 states that "dotted decimal notation ... refers [to] IP addresses of the
* form A.B.C.D; where each letter represents, in decimal, one byte of a four byte IP
* address".
*
* In other words, the dotted-decimal notation separates four decimal octet values by
* the dot, or period, character ('.'). Each decimal value represents one octet of
* the IP address starting with the most significant octet in network order.
*
* IP Address Examples :
*
* DOTTED DECIMAL NOTATION HEXADECIMAL EQUIVALENT
*
* 127.0.0.1 = 0x7F000001
* 192.168.1.64 = 0xC0A80140
* 255.255.255.0 = 0xFFFFFF00
* --- - -- --
* ^ ^ ^ ^
* | | | |
* MSO LSO MSO LSO
*
* where
*
* MSO Most Significant Octet in Dotted Decimal IP Address
* LSO Least Significant Octet in Dotted Decimal IP Address
*
*
* (2) The size of the ASCII character array that will receive the return IP address ASCII
* string MUST be greater than or equal to NET_ASCII_LEN_MAX_ADDR_IP.
*
* (3) (a) Leading zeros option prepends leading '0's prior to the first non-zero digit
* in each decimal octet value. The number of leading zeros is such that the
* decimal octet's number of decimal digits is equal to the maximum number of
* digits, NET_ASCII_CHAR_MAX_OCTET_ADDR_IP (3).
*
* (b) (1) If leading zeros option DISABLED ...
* (2) ... & the decimal value of the octet is zero; ...
* (3) ... then one digit of '0' value is formatted.
*
* This is NOT a leading zero; but a single decimal digit of '0' value.
*********************************************************************************************************
*/
/*$PAGE*/
void NetASCII_IP_to_Str (NET_IP_ADDR addr_ip,
CPU_CHAR *paddr_ip_ascii,
CPU_BOOLEAN lead_zeros,
NET_ERR *perr)
{
CPU_CHAR *pchar;
CPU_INT08U base_10_val_start;
CPU_INT08U base_10_val;
CPU_INT08U addr_octet_nbr_shifts;
CPU_INT08U addr_octet_val;
CPU_INT08U addr_octet_dig_nbr;
CPU_INT08U addr_octet_dig_val;
CPU_INT16U i;
/* -------------- VALIDATE PTR ---------------- */
if (paddr_ip_ascii == (CPU_CHAR *)0) {
*perr = NET_ASCII_ERR_NULL_PTR;
return;
}
/* ------------ VALIDATE NBR CHAR ------------- */
#if ((NET_ASCII_CHAR_MAX_OCTET_ADDR_IP < NET_ASCII_CHAR_MIN_OCTET ) || \
(NET_ASCII_CHAR_MAX_OCTET_ADDR_IP > NET_ASCII_CHAR_MAX_OCTET_08))
*paddr_ip_ascii = (CPU_CHAR)0;
*perr = NET_ASCII_ERR_INVALID_CHAR_LEN;
return;
#endif
pchar = paddr_ip_ascii;
base_10_val_start = 1;
for (i = 1; i < NET_ASCII_CHAR_MAX_OCTET_ADDR_IP; i++) { /* Calc starting dig val. */
base_10_val_start *= 10;
}
for (i = NET_ASCII_NBR_OCTET_ADDR_IP; i > 0; i--) { /* Parse ALL addr octets. */
/* Calc cur addr octet val. */
addr_octet_nbr_shifts = (i - 1) * DEF_OCTET_NBR_BITS;
addr_octet_val = (CPU_INT08U)((addr_ip >> addr_octet_nbr_shifts) & DEF_OCTET_MASK);
base_10_val = base_10_val_start;
while (base_10_val > 0) { /* Parse ALL octet digs. */
addr_octet_dig_nbr = addr_octet_val / base_10_val;
if ((addr_octet_dig_nbr > 0) || /* If octet dig val > 0, .. */
(base_10_val == 1) || /* .. OR on least-significant octet dig, .. */
(lead_zeros == DEF_YES)) { /* .. OR lead zeros opt ENABLED (see Note #3), */
/* .. calc & insert octet val ASCII dig. */
addr_octet_dig_val = (CPU_INT08U)(addr_octet_dig_nbr % 10 );
*pchar++ = (CPU_CHAR )(addr_octet_dig_val + '0');
}
base_10_val /= 10; /* Shift to next least-significant octet dig. */
}
if (i > 1) { /* If NOT on last octet, append a dot char. */
*pchar++ = '.';
}
}
*pchar = (CPU_CHAR)0; /* Append NULL char. */
*perr = NET_ASCII_ERR_NONE;
}