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