forked from agl/gatling
-
Notifications
You must be signed in to change notification settings - Fork 0
/
matchiprange.c
147 lines (138 loc) · 3.41 KB
/
matchiprange.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/*
pass the name of a rules files as argv[1]
then pipe in the gatling log file processed by acc on stdin
on stdout you'll get those lines annotated by the network name that matched a rule
rules look like this:
inetnum: 10.0.0.0 - 10.255.255.255
netname: reserved 10.* range
This format is the convention of the RIPE whois records for IP objects
*/
#include <string.h>
#include <buffer.h>
#include <scan.h>
#include <unistd.h>
#include <errmsg.h>
#include <str.h>
#include <fmt.h>
#include <ctype.h>
#include <ip6.h>
char _buf[8192];
struct net {
char first[16],last[16];
char* name;
struct net* next;
}* root,** next=&root,* cur;
int main(int argc,char* argv[]) {
buffer b;
char line[2048];
int r,whined;
size_t lineno=0;
if (!argv[1])
die(0,"usage: ",argv[0]," ip-ranges.txt");
if (buffer_mmapread(&b,argv[1]))
diesys(1,"open");
while ((r=buffer_getline(&b,line,sizeof line))>=0) {
char linenoasc[10];
char* c;
++lineno;
linenoasc[fmt_ulong(linenoasc,lineno)]=0;
if (r==0 && line[r]!='\n') break;
line[r]=0;
if (str_start(line,"inetnum:")) {
c=line+8;
parseiprange:
for (; *c==' ' || *c=='\t'; ++c) ;
if (isxdigit(*c)) {
char* d=strstr(c," - ");
if (d) {
d+=3;
while (*d==' ' || *d=='\t') ++d;
*next=malloc(sizeof(struct net));
if (!*next) die(1,"out of memory");
cur=*next;
cur->name="";
r=scan_ip6(c,cur->first);
if (c[r]!=' ')
die(1,"parse error in line ",linenoasc);
r=scan_ip6(d,cur->last);
if (d[r]!=0)
die(1,"parse error in line ",linenoasc);
}
}
} else if (str_start(line,"netname:")) {
c=line+8;
parsenetname:
for (; *c==' ' || *c=='\t'; ++c) ;
if (cur) {
cur->name=strdup(c);
#if 0
{
char a[FMT_IP6];
char b[FMT_IP6];
a[fmt_ip6c(a,cur->first)]=0;
b[fmt_ip6c(b,cur->last)]=0;
buffer_putmflush(buffer_1,"debug: ",a," - ",b," -> \"",cur->name,"\"\n");
}
#endif
}
} else if (str_start(line,"NetRange:")) {
c=line+9;
goto parseiprange;
} else if (str_start(line,"NetName:")) {
c=line+8;
goto parsenetname;
}
}
buffer_close(&b);
lineno=0; whined=0;
while ((r=buffer_getline(buffer_0,line,sizeof line))>0) {
char* c=line;
++lineno;
line[r]=0;
if (line[0]=='@') { // before tai64nlocal
if (r<35) goto kaputt;
c+=26;
if (*c==' ') ++c;
} else if (isdigit(line[0]) && line[4]=='-') { // after tai64nlocal
c+=30;
if (r<39) goto kaputt;
if (*c==' ') ++c;
} else {
kaputt:
if (whined != lineno-1) {
char linenoasc[10];
linenoasc[fmt_ulong(linenoasc,lineno)]=0;
carp("parse error on line ",linenoasc);
}
whined=lineno;
}
if (str_start(c,"GET") || str_start(c,"POST")) {
char ip[16];
while (*c && *c!=' ') ++c;
++c;
if (*c=='/')
die(1,"run gatling log through acc first");
/* next word is the IP address */
r=scan_ip6(c,ip);
if (c[r]!=' ') goto kaputt;
#if 0
{
char a[FMT_IP6];
char b[FMT_IP6];
a[fmt_ip6c(a,cur->first)]=0;
b[fmt_ip6c(b,cur->last)]=0;
buffer_putmflush(buffer_1,"debug: ",a," - ",b," -> \"",cur->name,"\"\n");
}
#endif
for (cur=root; cur; cur=cur->next) {
if (!cur->name)
die(0,"no netname");
if (byte_diff(ip,16,cur->first) >= 0 && byte_diff(ip,16,cur->last) <= 0) {
buffer_putmflush(buffer_1,line," -> \"",cur->name,"\"\n");
break;
}
}
}
}
return 0;
}