📄 firewall.c
字号:
#define _GNU_SOURCE#include <stdio.h>#include <ctype.h>#include <stdlib.h>#include <string.h>#include <firewall.h>#define TRUE 1#define FALSE 0/* Function parseEntry: Input: current position in string Output: List of strings corresponding to one unit (uids, programs, IP-addresses or ports, if successful NULL, if unsuccessful, and errno set accordingly */struct ElementList *parseEntry (char **line, int* errno) { *errno = 0; /* No error yet */ char *position = *line; struct ElementList *item; char *tmp; int finished = FALSE; struct ElementList *head = NULL; struct ElementList *previous = NULL; /* check whether we have reached end of string */ if (*position == '\0') { fprintf (stderr, "premature end of string reached while parsing!\n"); return NULL; } /* ignore white space */ while (isblank(*position)) { position++; } /* capture special case of * */ if (*position == '*') { /* next character must be space or end of line */ tmp = position + 1; if (!isblank (*tmp) && (*tmp != '\0')) { fprintf (stderr, "* must be followed by space or must appear at the end of the line \n"); return NULL; } item = malloc (sizeof (struct ElementList)); if (!item) { fprintf (stderr, "Couldn't allocate memory!\n"); exit (1); } item->element = strdup ("*"); /* to be able to use free later */ item->next = NULL; position ++; *line = position; return (item); } /* now check entries */ while (!finished) { tmp = position; /* have next entry now */ while (*tmp && (!isblank (*tmp)) && (*tmp != ',')) { tmp++; } if (tmp == position) { *errno = 1; /* fprintf (stderr, "Illegal format in string %s\n", position); */ return NULL; } /* create new entry */ item = malloc (sizeof (struct ElementList)); if (!item) { fprintf (stderr, "Couldn't allocate memory!\n"); exit (1); } item->element = malloc (tmp -position + 1); if (!(item->element)) { fprintf (stderr, "Couldn't allocate memory!\n"); exit (1); } item->element = strncpy (item->element, position, tmp -position ); item->element[tmp - position] = '\0'; item->next = NULL; /* printf ("Added string %s\n", item->element);*/ /* add to list */ if (previous) { previous->next = item; } if (!head) { head = item; } previous = item; position = tmp; /* Skip over comma and following spaces */ if (*position == ',') { position++; while (isblank(*position)) { position++; } } else { finished = TRUE; } } *line = position; return (head);} /* turns string into number; checks whether number is between 0 and 255 advances character pointer */int extractNumber (char **s) { int n = 0; while (isdigit (**s)) { n = 10*n + (**s - '0'); (*s)++; } if (n >= 256) { return -1; } return (n);}/* checks whether string is IP-address */int isIPAddress (char *s) { if (extractNumber (&s) == -1) { return FALSE; } if (*s != '.') { return FALSE; } s++; if (extractNumber (&s) == -1) { return FALSE; } if (*s != '.') { return FALSE; } s++; if (extractNumber (&s) == -1) { return FALSE; } if (*s != '.') { return FALSE; } s++; if (extractNumber (&s) == -1) { return FALSE; } return TRUE;}/* frees a list of elements */ void freeElementList (struct ElementList *list) { struct ElementList *tmp; while (list) { tmp = list->next; free (list->element); free (list); list = tmp; }}/* parses a string and returns either a configuration entry or a NULL-pointer. In the latter case, errno is set to the appropriate error. */struct ConfigLine *parseLine (char *line, int *errno) { struct ConfigLine *entry; struct ElementList *tmp; char *IPAddressString; int length; /* chop off finishing newline-character if present */ length = strlen (line); if ((length > 0) && (line[length -1] = '\n')) { line[length - 1] = '\0'; } *errno = 0; entry = malloc (sizeof (struct ConfigLine)); if (!entry) { fprintf (stderr, "Out of memory! \n"); exit (1); } entry->uids = parseEntry (&line, errno); if (!entry->uids) { free (entry); *errno = ILLEGAL_UID; return NULL; } entry->programs = parseEntry (&line, errno); if (!entry->programs) { freeElementList (entry->uids); free (entry); *errno = ILLEGAL_PROGRAM; return NULL; } entry->IPAddresses = parseEntry (&line, errno); if (!entry->IPAddresses) { freeElementList (entry->uids); freeElementList (entry->programs); free (entry); *errno = ILLEGAL_IP_ADDRESS; return NULL; } tmp = entry->IPAddresses; while (tmp) { IPAddressString = tmp->element; if (strcmp (IPAddressString, "*") && !isIPAddress (IPAddressString)){ freeElementList (entry->uids); freeElementList (entry->programs); freeElementList (entry->IPAddresses); free (entry); *errno = ILLEGAL_IP_ADDRESS; return NULL; } tmp = tmp->next; } entry->ports = parseEntry (&line, errno); if (!entry->ports) { freeElementList (entry->uids); freeElementList (entry->programs); freeElementList (entry->IPAddresses); free (entry); *errno = ILLEGAL_PORT; return NULL; } /* check whether we have reached end of line */ while (*line && isblank (*line)) { line++; } if (*line) { freeElementList (entry->uids); freeElementList (entry->programs); freeElementList (entry->IPAddresses); free (entry); *errno = ILLEGAL_PORT; return NULL; } /* Everything OK, can return entry */ return entry;} int strCompare (char *s1, char* s2) { int result = strcmp (s1, s2); if (result != 0) { if (strcmp (s1, "*") == 0) { return 1; } else if (strcmp (s2, "*") == 0) { return -1; } } return result;}/* compare two entries. Only port number relevant. Function usable for quicksort */ int compareEntry (const void *ventry1, const void *ventry2) { struct ConfigEntry *entry1; struct ConfigEntry *entry2; entry1 = (*((struct FirewallConfig **) ventry1))->entry; entry2 = (*((struct FirewallConfig **) ventry2))->entry; /* special case of 0 needs to be dealt with first */ if (entry1->port == 0) { return 1; } if (entry2->port == 0) { return -1; } if (entry1->port < entry2->port) { return -1; } if (entry1->port > entry2->port) { return 1; } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -