parent
03aa84720a
commit
c9e2c11fb3
4 changed files with 94 additions and 98 deletions
|
@ -1,27 +1,22 @@
|
|||
#include "parser.c"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "parser.c"
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
int check_rules(struct Rule **rules, size_t num_rules, struct IP *ip,
|
||||
Port *port) {
|
||||
int check_rules(struct Rule** rules, size_t num_rules, struct IP* ip, Port* port) {
|
||||
for (size_t i = 0; i < num_rules; i += 1) {
|
||||
struct Rule *r = rules[i];
|
||||
struct Rule* r = rules[i];
|
||||
|
||||
int ip_matches = FALSE;
|
||||
int port_matches = FALSE;
|
||||
|
||||
if ((r->ip.end != NULL && compare_ip(ip, &r->ip.start) > -1 &&
|
||||
compare_ip(ip, r->ip.end) < 1) ||
|
||||
compare_ip(ip, &r->ip.start) == 0) {
|
||||
if ((r->ip.end != NULL && compare_ip(ip, &r->ip.start) > -1 && compare_ip(ip, r->ip.end) < 1) || compare_ip(ip, &r->ip.start) == 0) {
|
||||
ip_matches = TRUE;
|
||||
}
|
||||
|
||||
if ((r->port.end != NULL && akpa_numcmp(*port, r->port.start) > -1 &&
|
||||
akpa_numcmp(*port, *r->port.end) < 1) ||
|
||||
akpa_numcmp(*port, r->port.start) == 0) {
|
||||
if ((r->port.end != NULL && akpa_numcmp(*port, r->port.start) > -1 && akpa_numcmp(*port, *r->port.end) < 1) || akpa_numcmp(*port, r->port.start) == 0) {
|
||||
port_matches = TRUE;
|
||||
}
|
||||
|
||||
|
@ -33,26 +28,26 @@ int check_rules(struct Rule **rules, size_t num_rules, struct IP *ip,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc < 4) {
|
||||
fprintf(stderr, "Usage: %s FILENAME IP_ADDR PORT\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t num_parsed_rules;
|
||||
struct Rule **parsed_rules = parse_file(argv[1], &num_parsed_rules);
|
||||
struct Rule** parsed_rules = parse_file(argv[1], &num_parsed_rules);
|
||||
|
||||
if (parsed_rules == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct IP *ip = (struct IP *)malloc(sizeof(struct IP));
|
||||
struct IP* ip = (struct IP*) malloc(sizeof(struct IP));
|
||||
if (parse_ip(argv[2], ip) == NULL) {
|
||||
fprintf(stderr, "Failed to parse IP\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
Port *port = (Port *)malloc(sizeof(Port));
|
||||
Port* port = (Port*) malloc(sizeof(Port));
|
||||
if (parse_port(argv[3], port) == NULL) {
|
||||
fprintf(stderr, "Failed to parse port\n");
|
||||
return 1;
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
//
|
||||
// Created by akp on 05/10/23.
|
||||
//
|
||||
#include "types.c"
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include "types.c"
|
||||
|
||||
enum ParseState {
|
||||
ParseState_ip1,
|
||||
|
@ -13,10 +13,10 @@ enum ParseState {
|
|||
ParseState_port2,
|
||||
};
|
||||
|
||||
// parse_ip parses an IP address line starting at startptr. Returns the ending
|
||||
// position of the pointer in line. Returns NULL on failure.
|
||||
char *parse_ip(char *startptr, struct IP *ip) {
|
||||
char *endptr = startptr;
|
||||
// parse_ip parses an IP address line starting at startptr. Returns the ending position of the pointer in line.
|
||||
// Returns NULL on failure.
|
||||
char* parse_ip(char* startptr, struct IP* ip) {
|
||||
char* endptr = startptr;
|
||||
|
||||
for (int i = 0; i < 4; i += 1) {
|
||||
long n = strtol(endptr, &endptr, 10);
|
||||
|
@ -26,7 +26,7 @@ char *parse_ip(char *startptr, struct IP *ip) {
|
|||
ip->val[i] = n;
|
||||
|
||||
if (i != 3) {
|
||||
if (*endptr != '.' || *(endptr + 1) == '\0') {
|
||||
if (*endptr != '.' || *(endptr+1) == '\0') {
|
||||
return NULL;
|
||||
} else {
|
||||
endptr += 1;
|
||||
|
@ -39,10 +39,10 @@ char *parse_ip(char *startptr, struct IP *ip) {
|
|||
return endptr;
|
||||
}
|
||||
|
||||
// parse_port parses a port starting at startptr. Returns the ending position of
|
||||
// the pointer in line. Returns NULL on failure.
|
||||
char *parse_port(char *startptr, Port *port) {
|
||||
char *end;
|
||||
// parse_port parses a port starting at startptr. Returns the ending position of the pointer in line.
|
||||
// Returns NULL on failure.
|
||||
char* parse_port(char* startptr, Port* port) {
|
||||
char* end;
|
||||
long n = strtol(startptr, &end, 10);
|
||||
if (n > USHRT_MAX || n < 0)
|
||||
return NULL;
|
||||
|
@ -50,10 +50,9 @@ char *parse_port(char *startptr, Port *port) {
|
|||
return end;
|
||||
}
|
||||
|
||||
// parse_rule parses a rule out a string, line. The result is saved to result,
|
||||
// which must be allocated by the caller. The return value is the ending
|
||||
// position of the rule in the string.
|
||||
char *parse_rule(char line[], struct Rule *result) {
|
||||
// parse_rule parses a rule out a string, line. The result is saved to result, which must be allocated by the caller.
|
||||
// The return value is the ending position of the rule in the string.
|
||||
char* parse_rule(char line[], struct Rule* result) {
|
||||
enum ParseState state = ParseState_ip1;
|
||||
|
||||
result->ip.end = NULL;
|
||||
|
@ -62,65 +61,65 @@ char *parse_rule(char line[], struct Rule *result) {
|
|||
int ptr = 0;
|
||||
for (;;) {
|
||||
switch (state) {
|
||||
case ParseState_ip1: {
|
||||
char *end = parse_ip(line + ptr, &result->ip.start);
|
||||
if (end == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
ptr = (int)(end - line);
|
||||
case ParseState_ip1: {
|
||||
char *end = parse_ip(line + ptr, &result->ip.start);
|
||||
if (end == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
ptr = (int)(end - line);
|
||||
|
||||
switch (line[ptr-1]) {
|
||||
case '-':
|
||||
state = ParseState_ip2;
|
||||
break;
|
||||
case ' ':
|
||||
state = ParseState_port1;
|
||||
break;
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
|
||||
switch (line[ptr - 1]) {
|
||||
case '-':
|
||||
state = ParseState_ip2;
|
||||
break;
|
||||
case ' ':
|
||||
}
|
||||
case ParseState_ip2: {
|
||||
result->ip.end = (struct IP *) malloc(sizeof(struct IP));
|
||||
|
||||
char *end = parse_ip(line + ptr, result->ip.end);
|
||||
if (end == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
ptr = (int) (end - line);
|
||||
|
||||
state = ParseState_port1;
|
||||
break;
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
case ParseState_port1: {
|
||||
char* end = parse_port(line + ptr, &result->port.start);
|
||||
if (end == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
ptr = (int)(end - line);
|
||||
|
||||
break;
|
||||
}
|
||||
case ParseState_ip2: {
|
||||
result->ip.end = (struct IP *)malloc(sizeof(struct IP));
|
||||
if (line[ptr] == '-') {
|
||||
ptr += 1;
|
||||
state = ParseState_port2;
|
||||
} else {
|
||||
goto finished_parsing;
|
||||
}
|
||||
|
||||
char *end = parse_ip(line + ptr, result->ip.end);
|
||||
if (end == NULL) {
|
||||
goto fail;
|
||||
break;
|
||||
}
|
||||
ptr = (int)(end - line);
|
||||
case ParseState_port2: {
|
||||
result->port.end = (Port*) malloc(sizeof(Port));
|
||||
|
||||
state = ParseState_port1;
|
||||
break;
|
||||
}
|
||||
case ParseState_port1: {
|
||||
char *end = parse_port(line + ptr, &result->port.start);
|
||||
if (end == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
ptr = (int)(end - line);
|
||||
char* end = parse_port(line + ptr, result->port.end);
|
||||
if (end == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
ptr = (int)(end - line);
|
||||
|
||||
if (line[ptr] == '-') {
|
||||
ptr += 1;
|
||||
state = ParseState_port2;
|
||||
} else {
|
||||
goto finished_parsing;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case ParseState_port2: {
|
||||
result->port.end = (Port *)malloc(sizeof(Port));
|
||||
|
||||
char *end = parse_port(line + ptr, result->port.end);
|
||||
if (end == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
ptr = (int)(end - line);
|
||||
|
||||
goto finished_parsing;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -140,16 +139,16 @@ finished_parsing:
|
|||
|
||||
return line + ptr;
|
||||
|
||||
fail:
|
||||
fail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define MAX_RULES 128
|
||||
|
||||
// parse_file parses a set of rules from the file named fname. The memory used
|
||||
// by the return value should be freed by the caller. If the return value is
|
||||
// by the return value should be freed by the caller. If the return value is
|
||||
// NULL, an error was encoutered and echo'd.
|
||||
struct Rule **parse_file(char fname[], size_t *num_parsed_rules) {
|
||||
struct Rule** parse_file(char fname[], size_t* num_parsed_rules) {
|
||||
int is_stdin = strcmp(fname, "--") == 0;
|
||||
|
||||
FILE *fp = NULL;
|
||||
|
@ -164,7 +163,7 @@ struct Rule **parse_file(char fname[], size_t *num_parsed_rules) {
|
|||
}
|
||||
}
|
||||
|
||||
struct Rule **parsed_rules = malloc(sizeof(struct Rule *) * MAX_RULES);
|
||||
struct Rule** parsed_rules = malloc(sizeof(struct Rule*) * MAX_RULES);
|
||||
*num_parsed_rules = 0;
|
||||
|
||||
char *line = NULL;
|
||||
|
@ -174,8 +173,8 @@ struct Rule **parse_file(char fname[], size_t *num_parsed_rules) {
|
|||
fprintf(stderr, "Too many rules\n");
|
||||
return NULL;
|
||||
}
|
||||
struct Rule *rule = (struct Rule *)malloc(sizeof(struct Rule));
|
||||
char *endptr = parse_rule(line, rule);
|
||||
struct Rule* rule = (struct Rule*) malloc(sizeof(struct Rule));
|
||||
char* endptr = parse_rule(line, rule);
|
||||
if (endptr == NULL || *endptr != '\n') {
|
||||
fprintf(stderr, "Ill formed rule: %s\n", line);
|
||||
return NULL;
|
||||
|
@ -183,8 +182,7 @@ struct Rule **parse_file(char fname[], size_t *num_parsed_rules) {
|
|||
parsed_rules[*num_parsed_rules] = rule;
|
||||
(*num_parsed_rules) += 1;
|
||||
}
|
||||
if (!feof(fp)) { // When we get here, getline has always returned -1 but may
|
||||
// or may not have reached EOF.
|
||||
if (!feof(fp)) { // When we get here, getline has always returned -1 but may or may not have reached EOF.
|
||||
// If it hasn't reached EOF, an error was thrown.
|
||||
perror("Read line");
|
||||
return NULL;
|
||||
|
|
|
@ -1,25 +1,26 @@
|
|||
#include "parser.c"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "parser.c"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Usage: %s FILENAME\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
size_t num_parsed_rules;
|
||||
struct Rule **parsed_rules = parse_file(argv[1], &num_parsed_rules);
|
||||
struct Rule** parsed_rules = parse_file(argv[1], &num_parsed_rules);
|
||||
|
||||
if (parsed_rules == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
qsort(parsed_rules, num_parsed_rules, sizeof(struct Rule *),
|
||||
&compare_rule_v);
|
||||
qsort(parsed_rules, num_parsed_rules, sizeof(struct Rule*), &compare_rule_v);
|
||||
|
||||
for (int i = 0; i < num_parsed_rules; i += 1) {
|
||||
struct Rule *r = parsed_rules[i];
|
||||
struct Rule* r = parsed_rules[i];
|
||||
print_rule(r);
|
||||
printf("\n");
|
||||
free_rule(r);
|
||||
|
|
|
@ -32,7 +32,7 @@ struct Rule {
|
|||
struct PortRange port;
|
||||
};
|
||||
|
||||
int compare_rule(struct Rule *a, struct Rule *b) {
|
||||
int compare_rule(struct Rule* a, struct Rule* b) {
|
||||
int result = compare_ip(&a->ip.start, &b->ip.start);
|
||||
|
||||
if (result == 0) {
|
||||
|
@ -42,11 +42,11 @@ int compare_rule(struct Rule *a, struct Rule *b) {
|
|||
return result;
|
||||
}
|
||||
|
||||
int compare_rule_v(const void *a, const void *b) {
|
||||
return compare_rule(*((struct Rule **)a), *((struct Rule **)b));
|
||||
int compare_rule_v(const void* a, const void* b) {
|
||||
return compare_rule(*((struct Rule**) a), *((struct Rule**) b));
|
||||
}
|
||||
|
||||
void free_rule(struct Rule *r) {
|
||||
void free_rule(struct Rule* r) {
|
||||
if (r->ip.end != NULL) {
|
||||
free(r->ip.end);
|
||||
}
|
||||
|
@ -60,9 +60,11 @@ void print_ip(struct IP *ip) {
|
|||
printf("%d.%d.%d.%d", ip->val[0], ip->val[1], ip->val[2], ip->val[3]);
|
||||
}
|
||||
|
||||
void print_port(Port port) { printf("%d", port); }
|
||||
void print_port(Port port) {
|
||||
printf("%d", port);
|
||||
}
|
||||
|
||||
void print_rule(struct Rule *r) {
|
||||
void print_rule(struct Rule* r) {
|
||||
print_ip(&r->ip.start);
|
||||
if (r->ip.end != NULL) {
|
||||
printf("-");
|
||||
|
|
Reference in a new issue