util.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. // SPDX-License-Identifier: Apache-2.0
  2. // Copyright 2015-2021 Espressif Systems (Shanghai) PTE LTD
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. //
  15. /** Includes **/
  16. #include "util.h"
  17. #include "posix/ctype.h"
  18. #include "string.h"
  19. /** Constants/Macros **/
  20. /** Exported variables **/
  21. /** Function declaration **/
  22. /** Exported Functions **/
  23. /*
  24. * Check whether "cp" is a valid ascii representation
  25. * of an Internet address and convert to a binary address.
  26. * Returns 1 if the address is valid, 0 if not.
  27. * This replaces inet_addr, the return value from which
  28. * cannot distinguish between failure and a local broadcast address.
  29. */
  30. int ipv4_addr_aton(const char *cp, uint32_t *ip_uint32)
  31. {
  32. u_long val, base, n;
  33. char c;
  34. u_long parts[4], *pp = parts;
  35. for (;;) {
  36. /*
  37. * Collect number up to ``.''.
  38. * Values are specified as for C:
  39. * 0x=hex, 0=octal, other=decimal.
  40. */
  41. val = 0; base = 10;
  42. if (*cp == '0') {
  43. if (*++cp == 'x' || *cp == 'X')
  44. base = 16, cp++;
  45. else
  46. base = 8;
  47. }
  48. while ((c = *cp) != '\0') {
  49. if (isascii(c) && isdigit(c)) {
  50. val = (val * base) + (c - '0');
  51. cp++;
  52. continue;
  53. }
  54. if (base == 16 && isascii(c) && isxdigit(c)) {
  55. val = (val << 4) +
  56. (c + 10 - (islower(c) ? 'a' : 'A'));
  57. cp++;
  58. continue;
  59. }
  60. break;
  61. }
  62. if (*cp == '.') {
  63. /*
  64. * Internet format:
  65. * a.b.c.d
  66. * a.b.c (with c treated as 16-bits)
  67. * a.b (with b treated as 24 bits)
  68. */
  69. if (pp >= parts + 3 || val > 0xff)
  70. return (0);
  71. *pp++ = val, cp++;
  72. } else
  73. break;
  74. }
  75. /*
  76. * Check for trailing characters.
  77. */
  78. if (*cp && (!isascii((uint8_t)*cp) || !isspace((uint8_t)*cp)))
  79. return (0);
  80. /*
  81. * Concoct the address according to
  82. * the number of parts specified.
  83. */
  84. n = pp - parts + 1;
  85. switch (n) {
  86. case 1: /* a -- 32 bits */
  87. break;
  88. case 2: /* a.b -- 8.24 bits */
  89. if (val > 0xffffff)
  90. return (0);
  91. val |= parts[0] << 24;
  92. break;
  93. case 3: /* a.b.c -- 8.8.16 bits */
  94. if (val > 0xffff)
  95. return (0);
  96. val |= (parts[0] << 24) | (parts[1] << 16);
  97. break;
  98. case 4: /* a.b.c.d -- 8.8.8.8 bits */
  99. if (val > 0xff)
  100. return (0);
  101. val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
  102. break;
  103. }
  104. if(ip_uint32) {
  105. *ip_uint32 = hton_long(val);
  106. }
  107. return (1);
  108. }
  109. /**
  110. * @brief convert ip in int to string
  111. *
  112. * @param addr ip address in network order to convert
  113. * @param buf target buffer where the string is stored
  114. * @param buflen length of buf
  115. * @return either pointer to buf which now holds the ASCII
  116. * representation of addr or NULL if buf was too small
  117. */
  118. char * ipv4_addr_ntoa(uint32_t addr, char *buf, int buflen)
  119. {
  120. char inv[3];
  121. char *rp;
  122. uint8_t *ap;
  123. uint8_t rem;
  124. uint8_t n;
  125. uint8_t i;
  126. int len = 0;
  127. uint32_t addr_nw = ntoh_long(addr);
  128. rp = buf;
  129. ap = (uint8_t *)&addr_nw;
  130. for (n = 0; n < 4; n++) {
  131. i = 0;
  132. do {
  133. rem = *ap % (uint8_t)10;
  134. *ap /= (uint8_t)10;
  135. inv[i++] = (char)('0' + rem);
  136. } while (*ap);
  137. while (i--) {
  138. if (len++ >= buflen) {
  139. return NULL;
  140. }
  141. *rp++ = inv[i];
  142. }
  143. if (len++ >= buflen) {
  144. return NULL;
  145. }
  146. *rp++ = '.';
  147. ap++;
  148. }
  149. *--rp = 0;
  150. return buf;
  151. }
  152. /**
  153. * @brief Convert mac string to byte stream
  154. * @param out - output mac in bytes
  155. * s - input mac string
  156. * @retval STM_OK/STM_FAIL
  157. */
  158. stm_ret_t convert_mac_to_bytes(uint8_t *out, const char *s)
  159. {
  160. int mac[MAC_LEN] = {0};
  161. int num_bytes = 0;
  162. if (!s || (strlen(s) < MIN_MAC_STRING_LEN)) {
  163. return STM_FAIL;
  164. }
  165. num_bytes = sscanf(s, "%2x:%2x:%2x:%2x:%2x:%2x",
  166. &mac[0],&mac[1], &mac[2], &mac[3], &mac[4], &mac[5]);
  167. if ((num_bytes < MAC_LEN) ||
  168. (mac[0] > 0xFF) ||
  169. (mac[1] > 0xFF) ||
  170. (mac[2] > 0xFF) ||
  171. (mac[3] > 0xFF) ||
  172. (mac[4] > 0xFF) ||
  173. (mac[5] > 0xFF)) {
  174. return STM_FAIL;
  175. }
  176. out[0] = mac[0]&0xff;
  177. out[1] = mac[1]&0xff;
  178. out[2] = mac[2]&0xff;
  179. out[3] = mac[3]&0xff;
  180. out[4] = mac[4]&0xff;
  181. out[5] = mac[5]&0xff;
  182. return STM_OK;
  183. }
  184. /**
  185. * @brief compare two buff in bytes
  186. * @param buff1 - in bytes
  187. * buff2 - in bytes
  188. * @retval 1 if same, else 0
  189. */
  190. uint8_t is_same_buff(void *buff1, void *buff2, uint16_t len)
  191. {
  192. uint16_t idx;
  193. uint8_t *b1 = (uint8_t*)buff1;
  194. uint8_t *b2 = (uint8_t*)buff2;
  195. if ((b1 == NULL) && (b2==NULL)) {
  196. if(len) {
  197. return 0;
  198. }
  199. return 1;
  200. }
  201. if(!b1 || !b2) {
  202. return 0;
  203. }
  204. /* Function assumes buff1 and buff2 are allocated for len */
  205. for (idx=0; idx < len; idx++) {
  206. if (*b1 != *b2) {
  207. return 0;
  208. }
  209. b1++;
  210. b2++;
  211. }
  212. return 1;
  213. }
  214. /**
  215. * @brief Get ip in 32bit from dotted string notation
  216. * @param ip_s - input ip address in string
  217. * ip_x - output ip address in 32 bit
  218. * @retval STM_OK/STM_FAIL
  219. */
  220. stm_ret_t get_ipaddr_from_str(const char *ip_s, uint32_t *ip_x)
  221. {
  222. uint32_t ip_nw = 0;
  223. if (! ipv4_addr_aton(ip_s, &ip_nw))
  224. {
  225. return STM_FAIL;
  226. }
  227. /* ipv4_addr_aton does conversion in network order. reverse */
  228. *ip_x = ntoh_long(ip_nw);
  229. return STM_OK;
  230. }