util.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  4. *
  5. * Copyright 2018 (c) Stefan Profanter, fortiss GmbH
  6. */
  7. #ifndef UA_HELPER_H_
  8. #define UA_HELPER_H_
  9. #include <open62541/types.h>
  10. _UA_BEGIN_DECLS
  11. /**
  12. * Endpoint URL Parser
  13. * -------------------
  14. * The endpoint URL parser is generally useful for the implementation of network
  15. * layer plugins. */
  16. /* Split the given endpoint url into hostname, port and path. All arguments must
  17. * be non-NULL. EndpointUrls have the form "opc.tcp://hostname:port/path", port
  18. * and path may be omitted (together with the prefix colon and slash).
  19. *
  20. * @param endpointUrl The endpoint URL.
  21. * @param outHostname Set to the parsed hostname. The string points into the
  22. * original endpointUrl, so no memory is allocated. If an IPv6 address is
  23. * given, hostname contains e.g. '[2001:0db8:85a3::8a2e:0370:7334]'
  24. * @param outPort Set to the port of the url or left unchanged.
  25. * @param outPath Set to the path if one is present in the endpointUrl.
  26. * Starting or trailing '/' are NOT included in the path. The string
  27. * points into the original endpointUrl, so no memory is allocated.
  28. * @return Returns UA_STATUSCODE_BADTCPENDPOINTURLINVALID if parsing failed. */
  29. UA_StatusCode UA_EXPORT
  30. UA_parseEndpointUrl(const UA_String *endpointUrl, UA_String *outHostname,
  31. UA_UInt16 *outPort, UA_String *outPath);
  32. /* Split the given endpoint url into hostname, vid and pcp. All arguments must
  33. * be non-NULL. EndpointUrls have the form "opc.eth://<host>[:<VID>[.PCP]]".
  34. * The host is a MAC address, an IP address or a registered name like a
  35. * hostname. The format of a MAC address is six groups of hexadecimal digits,
  36. * separated by hyphens (e.g. 01-23-45-67-89-ab). A system may also accept
  37. * hostnames and/or IP addresses if it provides means to resolve it to a MAC
  38. * address (e.g. DNS and Reverse-ARP).
  39. *
  40. * Note: currently only parsing MAC address is supported.
  41. *
  42. * @param endpointUrl The endpoint URL.
  43. * @param vid Set to VLAN ID.
  44. * @param pcp Set to Priority Code Point.
  45. * @return Returns UA_STATUSCODE_BADINTERNALERROR if parsing failed. */
  46. UA_StatusCode UA_EXPORT
  47. UA_parseEndpointUrlEthernet(const UA_String *endpointUrl, UA_String *target,
  48. UA_UInt16 *vid, UA_Byte *pcp);
  49. /* Convert given byte string to a positive number. Returns the number of valid
  50. * digits. Stops if a non-digit char is found and returns the number of digits
  51. * up to that point. */
  52. size_t UA_EXPORT
  53. UA_readNumber(UA_Byte *buf, size_t buflen, UA_UInt32 *number);
  54. /* Same as UA_ReadNumber but with a base parameter */
  55. size_t UA_EXPORT
  56. UA_readNumberWithBase(const UA_Byte *buf, size_t buflen,
  57. UA_UInt32 *number, UA_Byte base);
  58. #ifndef UA_MIN
  59. #define UA_MIN(A,B) (A > B ? B : A)
  60. #endif
  61. #ifndef UA_MAX
  62. #define UA_MAX(A,B) (A > B ? A : B)
  63. #endif
  64. /**
  65. * Convenience macros for complex types
  66. * ------------------------------------ */
  67. #define UA_PRINTF_GUID_FORMAT "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x"
  68. #define UA_PRINTF_GUID_DATA(GUID) (GUID).data1, (GUID).data2, (GUID).data3, \
  69. (GUID).data4[0], (GUID).data4[1], (GUID).data4[2], (GUID).data4[3], \
  70. (GUID).data4[4], (GUID).data4[5], (GUID).data4[6], (GUID).data4[7]
  71. #define UA_PRINTF_STRING_FORMAT "\"%.*s\""
  72. #define UA_PRINTF_STRING_DATA(STRING) (int)(STRING).length, (STRING).data
  73. /**
  74. * Helper functions for converting data types
  75. * ------------------------------------ */
  76. /* Converts a bytestring to the corresponding base64 encoded string
  77. * representation.
  78. *
  79. * @param byteString the original byte string
  80. * @param str the resulting base64 encoded byte string
  81. *
  82. * Returns UA_STATUSCODE_GOOD on success. */
  83. UA_StatusCode UA_EXPORT
  84. UA_ByteString_toBase64String(const UA_ByteString *byteString, UA_String *str);
  85. /* Converts a node id to the corresponding string representation.
  86. * It can be one of:
  87. * - Numeric: ns=0;i=123
  88. * - String: ns=0;s=Some String
  89. * - Guid: ns=0;g=A123456C-0ABC-1A2B-815F-687212AAEE1B
  90. * - ByteString: ns=0;b=AA== */
  91. UA_StatusCode UA_EXPORT
  92. UA_NodeId_toString(const UA_NodeId *nodeId, UA_String *nodeIdStr);
  93. /* Compare memory in constant time to mitigate timing attacks.
  94. * Returns true if ptr1 and ptr2 are equal for length bytes. */
  95. static UA_INLINE UA_Boolean
  96. UA_constantTimeEqual(const void *ptr1, const void *ptr2, size_t length) {
  97. volatile const UA_Byte *a = (volatile const UA_Byte *)ptr1;
  98. volatile const UA_Byte *b = (volatile const UA_Byte *)ptr2;
  99. volatile UA_Byte c = 0;
  100. for(size_t i = 0; i < length; ++i) {
  101. UA_Byte x = a[i], y = b[i];
  102. c |= x ^ y;
  103. }
  104. return !c;
  105. }
  106. _UA_END_DECLS
  107. #endif /* UA_HELPER_H_ */