mac.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /* $Id$ */
  2. /*
  3. * Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  4. * Copyright (c) 2013-2018 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  5. *
  6. * The Tcpreplay Suite of tools is free software: you can redistribute it
  7. * and/or modify it under the terms of the GNU General Public License as
  8. * published by the Free Software Foundation, either version 3 of the
  9. * License, or with the authors permission any later version.
  10. *
  11. * The Tcpreplay Suite is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with the Tcpreplay Suite. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "config.h"
  20. #include "defines.h"
  21. #include "common.h"
  22. #include <string.h>
  23. #include <stdlib.h>
  24. #include <limits.h>
  25. #include <ctype.h>
  26. #include "mac.h"
  27. /**
  28. * converts a string representation of a MAC address, based on
  29. * non-portable ether_aton()
  30. */
  31. void
  32. mac2hex(const char *mac, u_char *dst, int len)
  33. {
  34. int i;
  35. char *pp;
  36. if (len < 6)
  37. return;
  38. while (isspace(*mac))
  39. mac++;
  40. /* expect 6 hex octets separated by ':' or space/NUL if last octet */
  41. for (i = 0; i < 6; i++) {
  42. long l = strtol(mac, &pp, 16);
  43. if (pp == mac || l > 0xFF || l < 0)
  44. return;
  45. if (!(*pp == ':' || (i == 5 && (isspace(*pp) || *pp == '\0'))))
  46. return;
  47. dst[i] = (u_char) l;
  48. mac = pp + 1;
  49. }
  50. }
  51. /**
  52. * converts a string representation of TWO MAC addresses, which
  53. * are comma deliminated into two hex values. Either *first or *second
  54. * can be NULL if there is nothing before or after the comma.
  55. * returns:
  56. * 1 = first mac
  57. * 2 = second mac
  58. * 3 = both mac's
  59. * 0 = none
  60. */
  61. int
  62. dualmac2hex(const char *dualmac, u_char *first, u_char *second, int len)
  63. {
  64. char *tok = NULL, *temp, *string;
  65. int ret = 0;
  66. string = safe_strdup(dualmac);
  67. /* if we've only got a comma, then return NULL's */
  68. if (len <= 1) {
  69. second = first = NULL;
  70. goto done;
  71. }
  72. temp = strtok_r(string, ",", &tok);
  73. if (strlen(temp)) {
  74. mac2hex(temp, first, len);
  75. ret = 1;
  76. }
  77. temp = strtok_r(NULL, ",", &tok);
  78. /* temp is null if no comma */
  79. if (temp != NULL) {
  80. if (strlen(temp)) {
  81. mac2hex(temp, second, len);
  82. ret += 2;
  83. }
  84. }
  85. done:
  86. safe_free(string);
  87. return ret;
  88. }
  89. /**
  90. * Figures out if a MAC is listed in a comma delimited
  91. * string of MAC addresses.
  92. * returns TCPR_DIR_C2S if listed
  93. * returns TCPR_DIR_S2C if not listed
  94. */
  95. tcpr_dir_t
  96. macinstring(const char *macstring, const u_char *mac)
  97. {
  98. char *tok = NULL, *tempstr, *ourstring;
  99. u_char tempmac[6];
  100. int len = 6, ret = TCPR_DIR_S2C;
  101. ourstring = safe_strdup(macstring);
  102. memset(&tempmac[0], 0, sizeof(tempmac));
  103. tempstr = strtok_r(ourstring, ",", &tok);
  104. if (strlen(tempstr)) {
  105. mac2hex(tempstr, tempmac, len);
  106. if (memcmp(mac, tempmac, len) == 0) {
  107. dbgx(3, "Packet matches: " MAC_FORMAT " sending out primary.\n", MAC_STR(tempmac));
  108. ret = TCPR_DIR_C2S;
  109. goto EXIT_MACINSTRING;
  110. }
  111. } else {
  112. goto EXIT_MACINSTRING;
  113. }
  114. while ((tempstr = strtok_r(NULL, ",", &tok)) != NULL) {
  115. mac2hex(tempstr, tempmac, len);
  116. if (memcmp(mac, tempmac, len) == 0) {
  117. ret = TCPR_DIR_C2S;
  118. dbgx(3, "Packet matches: " MAC_FORMAT " sending out primary.\n", MAC_STR(tempmac));
  119. goto EXIT_MACINSTRING;
  120. }
  121. }
  122. EXIT_MACINSTRING:
  123. safe_free(ourstring);
  124. #ifdef DEBUG
  125. if (ret == TCPR_DIR_S2C)
  126. dbg(3, "Packet doesn't match any MAC addresses sending out secondary.\n");
  127. #endif
  128. return ret;
  129. }