list.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. /* $Id$ */
  2. /*
  3. * Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  4. * Copyright (c) 2013-2017 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. /*
  20. * A generic method to parse a list of integers which are
  21. * delimited by commas and dashes to indicate individual
  22. * numbers and ranges
  23. * Provides both a way to process the list and determine
  24. * if an integer exists in the list.
  25. */
  26. #include "config.h"
  27. #include "defines.h"
  28. #include "common.h"
  29. #include <stdlib.h>
  30. #include <string.h>
  31. #include <sys/types.h>
  32. #include <regex.h>
  33. #include <errno.h>
  34. /**
  35. * Creates a new tcpr_list entry. Malloc's memory.
  36. */
  37. tcpr_list_t *
  38. new_list()
  39. {
  40. tcpr_list_t *newlist;
  41. newlist = (tcpr_list_t *)safe_malloc(sizeof(tcpr_list_t));
  42. return (newlist);
  43. }
  44. /**
  45. * Processes a string (ourstr) containing the list in human readable
  46. * format and places the data in **list and finally returns 1 for
  47. * success, 0 for fail.
  48. */
  49. int
  50. parse_list(tcpr_list_t ** listdata, char *ourstr)
  51. {
  52. tcpr_list_t *listcur, *list_ptr;
  53. char *this = NULL;
  54. char *first, *second;
  55. int rcode;
  56. regex_t preg;
  57. char ebuf[EBUF_SIZE];
  58. char regex[] = "^[0-9]+(-[0-9]+)?$";
  59. char *token = NULL;
  60. u_int i;
  61. /* compile the regex first */
  62. if ((rcode = regcomp(&preg, regex, REG_EXTENDED | REG_NOSUB)) != 0) {
  63. regerror(rcode, &preg, ebuf, sizeof(ebuf));
  64. errx(-1, "Unable to compile regex (%s): %s", regex, ebuf);
  65. }
  66. /* first iteration */
  67. this = strtok_r(ourstr, ",", &token);
  68. first = this;
  69. second = NULL;
  70. /* regex test */
  71. if (regexec(&preg, this, 0, NULL, 0) != 0) {
  72. warnx("Unable to parse: %s", this);
  73. return 0;
  74. }
  75. *listdata = new_list();
  76. list_ptr = *listdata;
  77. listcur = list_ptr;
  78. for (i = 0; i < strlen(this); i++) {
  79. if (this[i] == '-') {
  80. this[i] = '\0';
  81. second = &this[i + 1];
  82. }
  83. }
  84. list_ptr->min = strtoull(first, NULL, 0);
  85. if (second != NULL) {
  86. list_ptr->max = strtoull(second, NULL, 0);
  87. }
  88. else {
  89. list_ptr->max = list_ptr->min;
  90. }
  91. while (1) {
  92. this = strtok_r(NULL, ",", &token);
  93. if (this == NULL)
  94. break;
  95. first = this;
  96. second = NULL;
  97. /* regex test */
  98. if (regexec(&preg, this, 0, NULL, 0) != 0) {
  99. warnx("Unable to parse: %s", this);
  100. return 0;
  101. }
  102. listcur->next = new_list();
  103. listcur = listcur->next;
  104. for (i = 0; i < strlen(this); i++) {
  105. if (this[i] == '-') {
  106. this[i] = '\0';
  107. second = &this[i + 1];
  108. }
  109. }
  110. listcur->min = strtoull(first, NULL, 0);
  111. if (second != NULL) {
  112. listcur->max = strtoull(second, NULL, 0);
  113. }
  114. else {
  115. listcur->max = listcur->min;
  116. }
  117. }
  118. return 1;
  119. }
  120. /**
  121. * Checks to see if the given integer exists in the LIST.
  122. */
  123. tcpr_dir_t
  124. check_list(tcpr_list_t * list, COUNTER value)
  125. {
  126. tcpr_list_t *current;
  127. current = list;
  128. do {
  129. if ((current->min != 0) && (current->max != 0)) {
  130. if ((value >= current->min) && (value <= current->max))
  131. return TCPR_DIR_C2S;
  132. }
  133. else if (current->min == 0) {
  134. if (value <= current->max)
  135. return TCPR_DIR_C2S;
  136. }
  137. else if (current->max == 0) {
  138. if (value >= current->min)
  139. return TCPR_DIR_C2S;
  140. }
  141. if (current->next != NULL) {
  142. current = current->next;
  143. }
  144. else {
  145. current = NULL;
  146. }
  147. } while (current != NULL);
  148. return TCPR_DIR_S2C;
  149. }
  150. /**
  151. * Free's all the memory associated with the given LIST
  152. */
  153. void
  154. free_list(tcpr_list_t * list)
  155. {
  156. /* recursively go down the list */
  157. if (list->next != NULL)
  158. free_list(list->next);
  159. safe_free(list);
  160. }