]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/ip/httpd/classify.c
ip/tftpd: remove sunkernel hack
[plan9front.git] / sys / src / cmd / ip / httpd / classify.c
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <ndb.h>
5 #include "whois.h"
6
7 typedef struct Country Country;
8
9 struct Country
10 {
11         char *code;
12         char *name;
13 };
14
15 Country badc[] =
16 {
17         {"af", "afghanistan"},
18         {"cu", "cuba"},
19         {"ir", "iran"},
20         {"iq", "iraq"},
21         {"ly", "libya"},
22         {"kp", "north korea"},
23         {"sd", "sudan"},
24         {"sy", "syria"},
25         { 0, 0 }
26 };
27
28 Country goodc[] =
29 {
30         // the original, us and canada
31         {"us", "united states of america"},
32         {"ca", "canada"},
33         {"gov", "gov"},
34         {"mil", "mil"},
35
36         // the european union
37         { "eu", "european union" },
38         { "be", "belgium" },
39         { "de", "germany" },
40         { "fr", "france" },
41         { "it", "italy" },
42         { "lu", "luxembourg" },
43         { "nl", "netherlands" },
44         { "dk", "denmark" },
45         { "ie", "ireland" },
46         { "gb", "great britain" },
47         { "uk", "united kingdom" },
48         { "gr", "greece" },
49         { "es", "spain" },
50         { "pt", "portugal" },
51         { "au", "australia" },
52         { "fi", "finland" },
53         { "se", "sweden" },
54
55         // the rest
56         {"au", "australia"},
57         {"no", "norway"},
58         {"cz", "czech republic"},
59         {"hu", "hungary"},
60         {"pl", "poland"},
61         {"jp", "japan"},
62         {"ch", "switzerland"},
63         {"nz", "new zealand"},
64         { 0, 0 }
65 };
66
67 char *gov[] =
68 {
69         "gov",
70         "gouv",
71         "mil",
72         "government",
73         0,
74 };
75
76 Country allc[] =
77 {
78         { "ad", "andorra" },
79         { "ae", "united arab emirates" },
80         { "af", "afghanistan" },
81         { "ag", "antigua and barbuda" },
82         { "ai", "anguilla" },
83         { "al", "albania" },
84         { "am", "armenia" },
85         { "an", "netherlands antilles" },
86         { "ao", "angola" },
87         { "aq", "antarctica" },
88         { "ar", "argentina" },
89         { "as", "american samoa" },
90         { "at", "austria" },
91         { "au", "australia" },
92         { "aw", "aruba" },
93         { "az", "azerbaijan" },
94         { "ba", "bosnia and herzegovina" },
95         { "bb", "barbados" },
96         { "bd", "bangladesh" },
97         { "be", "belgium" },
98         { "bf", "burkina faso" },
99         { "bg", "bulgaria" },
100         { "bh", "bahrain" },
101         { "bi", "burundi" },
102         { "bj", "benin" },
103         { "bm", "bermuda" },
104         { "bn", "brunei darussalam" },
105         { "bo", "bolivia" },
106         { "br", "brazil" },
107         { "bs", "bahamas" },
108         { "bt", "bhutan" },
109         { "bu", "burma" },
110         { "bv", "bouvet island" },
111         { "bw", "botswana" },
112         { "by", "belarus" },
113         { "bz", "belize" },
114         { "ca", "canada" },
115         { "cc", "cocos (keeling) islands" },
116         { "cf", "central african republic" },
117         { "cg", "congo" },
118         { "ch", "switzerland" },
119         { "ci", "cote d'ivoire (ivory coast)" },
120         { "ck", "cook islands" },
121         { "cl", "chile" },
122         { "cm", "cameroon" },
123         { "cn", "china" },
124         { "co", "colombia" },
125         { "cr", "costa rica" },
126         { "cs", "czechoslovakia (former)" },
127         { "ct", "canton and enderbury island" },
128         { "cu", "cuba" },
129         { "cv", "cape verde" },
130         { "cx", "christmas island" },
131         { "cy", "cyprus" },
132         { "cz", "czech republic" },
133         { "dd", "german democratic republic" },
134         { "de", "germany" },
135         { "dj", "djibouti" },
136         { "dk", "denmark" },
137         { "dm", "dominica" },
138         { "do", "dominican republic" },
139         { "dz", "algeria" },
140         { "ec", "ecuador" },
141         { "ee", "estonia" },
142         { "eg", "egypt" },
143         { "eh", "western sahara" },
144         { "er", "eritrea" },
145         { "es", "spain" },
146         { "et", "ethiopia" },
147         { "eu", "european union" },
148         { "fi", "finland" },
149         { "fj", "fiji" },
150         { "fk", "falkland islands (malvinas)" },
151         { "fm", "micronesia" },
152         { "fo", "faroe islands" },
153         { "fr", "france" },
154         { "fx", "france, metropolitan" },
155         { "ga", "gabon" },
156         { "gb", "great britain (uk)" },
157         { "gd", "grenada" },
158         { "ge", "georgia" },
159         { "gf", "french guiana" },
160         { "gh", "ghana" },
161         { "gi", "gibraltar" },
162         { "gl", "greenland" },
163         { "gm", "gambia" },
164         { "gn", "guinea" },
165         { "gp", "guadeloupe" },
166         { "gq", "equatorial guinea" },
167         { "gr", "greece" },
168         { "gs", "s. georgia and s. sandwich isls." },
169         { "gt", "guatemala" },
170         { "gu", "guam" },
171         { "gw", "guinea-bissau" },
172         { "gy", "guyana" },
173         { "hk", "hong kong" },
174         { "hm", "heard and mcdonald islands" },
175         { "hn", "honduras" },
176         { "hr", "croatia (hrvatska)" },
177         { "ht", "haiti" },
178         { "hu", "hungary" },
179         { "id", "indonesia" },
180         { "ie", "ireland" },
181         { "il", "israel" },
182         { "in", "india" },
183         { "io", "british indian ocean territory" },
184         { "iq", "iraq" },
185         { "ir", "iran" },
186         { "is", "iceland" },
187         { "it", "italy" },
188         { "jm", "jamaica" },
189         { "jo", "jordan" },
190         { "jp", "japan" },
191         { "jt", "johnston island" },
192         { "ke", "kenya" },
193         { "kg", "kyrgyzstan" },
194         { "kh", "cambodia (democratic kampuchea)" },
195         { "ki", "kiribati" },
196         { "km", "comoros" },
197         { "kn", "saint kitts and nevis" },
198         { "kp", "korea (north)" },
199         { "kr", "korea (south)" },
200         { "kw", "kuwait" },
201         { "ky", "cayman islands" },
202         { "kz", "kazakhstan" },
203         { "la", "laos" },
204         { "lb", "lebanon" },
205         { "lc", "saint lucia" },
206         { "li", "liechtenstein" },
207         { "lk", "sri lanka" },
208         { "lr", "liberia" },
209         { "ls", "lesotho" },
210         { "lt", "lithuania" },
211         { "lu", "luxembourg" },
212         { "lv", "latvia" },
213         { "ly", "libya" },
214         { "ma", "morocco" },
215         { "mc", "monaco" },
216         { "md", "moldova" },
217         { "mg", "madagascar" },
218         { "mh", "marshall islands" },
219         { "mi", "midway islands" },
220         { "mk", "macedonia" },
221         { "ml", "mali" },
222         { "mm", "myanmar" },
223         { "mn", "mongolia" },
224         { "mo", "macau" },
225         { "mp", "northern mariana islands" },
226         { "mq", "martinique" },
227         { "mr", "mauritania" },
228         { "ms", "montserrat" },
229         { "mt", "malta" },
230         { "mu", "mauritius" },
231         { "mv", "maldives" },
232         { "mw", "malawi" },
233         { "mx", "mexico" },
234         { "my", "malaysia" },
235         { "mz", "mozambique" },
236         { "na", "namibia" },
237         { "nc", "new caledonia" },
238         { "ne", "niger" },
239         { "nf", "norfolk island" },
240         { "ng", "nigeria" },
241         { "ni", "nicaragua" },
242         { "nl", "netherlands" },
243         { "no", "norway" },
244         { "np", "nepal" },
245         { "nq", "dronning maud land" },
246         { "nr", "nauru" },
247         { "nt", "neutral zone" },
248         { "nu", "niue" },
249         { "nz", "new zealand (aotearoa)" },
250         { "om", "oman" },
251         { "pa", "panama" },
252         { "pc", "pacific islands" },
253         { "pe", "peru" },
254         { "pf", "french polynesia" },
255         { "pg", "papua new guinea" },
256         { "ph", "philippines" },
257         { "pk", "pakistan" },
258         { "pl", "poland" },
259         { "pm", "st. pierre and miquelon" },
260         { "pn", "pitcairn" },
261         { "pr", "puerto rico" },
262         { "pu", "united states misc. pacific islands" },
263         { "pt", "portugal" },
264         { "pw", "palau" },
265         { "py", "paraguay" },
266         { "qa", "qatar" },
267         { "re", "reunion" },
268         { "ro", "romania" },
269         { "ru", "russian federation" },
270         { "rw", "rwanda" },
271         { "sa", "saudi arabia" },
272         { "sb", "solomon islands" },
273         { "sc", "seychelles" },
274         { "sd", "sudan" },
275         { "se", "sweden" },
276         { "sg", "singapore" },
277         { "sh", "st. helena" },
278         { "si", "slovenia" },
279         { "sj", "svalbard and jan mayen islands" },
280         { "sk", "slovak republic" },
281         { "sl", "sierra leone" },
282         { "sm", "san marino" },
283         { "sn", "senegal" },
284         { "so", "somalia" },
285         { "sr", "suriname" },
286         { "st", "sao tome and principe" },
287         { "su", "ussr (former)" },
288         { "sv", "el salvador" },
289         { "sy", "syria" },
290         { "sz", "swaziland" },
291         { "tc", "turks and caicos islands" },
292         { "td", "chad" },
293         { "tf", "french southern territories" },
294         { "tg", "togo" },
295         { "th", "thailand" },
296         { "tj", "tajikistan" },
297         { "tk", "tokelau" },
298         { "tm", "turkmenistan" },
299         { "tn", "tunisia" },
300         { "to", "tonga" },
301         { "tp", "east timor" },
302         { "tr", "turkey" },
303         { "tt", "trinidad and tobago" },
304         { "tv", "tuvalu" },
305         { "tw", "taiwan" },
306         { "tz", "tanzania" },
307         { "ua", "ukraine" },
308         { "ug", "uganda" },
309         { "uk", "united kingdom" },
310         { "um", "us minor outlying islands" },
311         { "us", "united states" },
312         { "uy", "uruguay" },
313         { "uz", "uzbekistan" },
314         { "va", "vatican city state (holy see)" },
315         { "vc", "saint vincent and the grenadines" },
316         { "ve", "venezuela" },
317         { "vg", "virgin islands (british)" },
318         { "vi", "virgin islands (u.s.)" },
319         { "vn", "viet nam" },
320         { "vu", "vanuatu" },
321         { "wf", "wallis and futuna islands" },
322         { "wk", "wake island" },
323         { "ws", "samoa" },
324         { "yd", "democratic yemen" },
325         { "ye", "yemen" },
326         { "yt", "mayotte" },
327         { "yu", "yugoslavia" },
328         { "za", "south africa" },
329         { "zm", "zambia" },
330         { "zr", "zaire" },
331         { "zw", "zimbabwe" },
332
333         {"gov", "gov"},
334         {"mil", "mil"},
335
336         { 0, 0 }
337 };
338
339 int classdebug;
340
341 static int
342 incountries(char *s, Country *cp)
343 {
344         for(; cp->code != 0; cp++)
345                 if(cistrcmp(s, cp->code) == 0
346                 || cistrcmp(s, cp->name) == 0)
347                         return 1;
348         return 0;
349 }
350
351 static int
352 indomains(char *s, char **dp)
353 {
354         for(; *dp != nil; dp++)
355                 if(cistrcmp(s, *dp) == 0)
356                         return 1;
357
358         return 0;
359 }
360
361 int
362 classify(char *ip, Ndbtuple *t)
363 {
364         int isgov, iscountry, isbadc, isgoodc;
365         char dom[256];
366         char *df[128];
367         Ndbtuple *nt, *x;
368         int n;
369
370         isgov = iscountry = isbadc = 0;
371         isgoodc = 1;
372         
373         for(nt = t; nt != nil; nt = nt->entry){
374                 if(strcmp(nt->attr, "country") == 0){
375                         iscountry = 1;
376                         if(incountries(nt->val, badc)){
377                                 if(classdebug)fprint(2, "isbadc\n");
378                                 isbadc = 1;
379                                 isgoodc = 0;
380                         } else if(!incountries(nt->val, goodc)){
381                                 if(classdebug)fprint(2, "!isgoodc\n");
382                                 isgoodc = 0;
383                         }
384                 }
385
386                 /* domain names can always hurt, even without forward verification */
387                 if(strcmp(nt->attr, "dom") == 0){
388                         strncpy(dom, nt->val, sizeof dom);
389                         dom[sizeof(dom)-1] = 0;
390                         n = getfields(dom, df, nelem(df), 0, ".");
391
392                         /* a bad country in a domain name is always believed */
393                         if(incountries(df[n-1], badc)){
394                                 if(classdebug)fprint(2, "isbadc dom\n");
395                                 isbadc = 1;
396                                 isgoodc = 0;
397                         }
398
399                         /* a goverment in a domain name is always believed */
400                         if(n > 1 && indomains(df[n-2], gov))
401                                 isgov = 1;
402                 }
403         }
404         if(iscountry == 0){
405                 /* did the forward lookup work? */
406                 for(nt = t; nt != nil; nt = nt->entry){
407                         if(strcmp(nt->attr, "ip") == 0 && strcmp(nt->val, ip) == 0)
408                                 break;
409                 }
410
411                 /* see if the domain name ends in a country code */
412                 if(nt != nil && (x = ndbfindattr(t, nt, "dom")) != nil){
413                         strncpy(dom, x->val, sizeof dom);
414                         dom[sizeof(dom)-1] = 0;
415                         n = getfields(dom, df, nelem(df), 0, ".");
416                         if(incountries(df[n-1], allc))
417                                 iscountry = 1;
418                 }
419         }
420         if(iscountry == 0)
421                 return Cunknown;
422         if(isbadc)
423                 return Cbadc;
424         if(!isgoodc && isgov)
425                 return Cbadgov;
426         return Cok;
427 }