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 } 428