Skip to Content
[CAIDA - Center for Applied Internet Data Analysis logo]
The Center for Applied Internet Data Analysis
corsaro_geo.c
1 /*
2  * corsaro
3  *
4  * Alistair King, CAIDA, UC San Diego
5  * corsaro-info@caida.org
6  *
7  * Copyright (C) 2012 The Regents of the University of California.
8  *
9  * This file is part of corsaro.
10  *
11  * corsaro is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation, either version 3 of the License, or
14  * (at your option) any later version.
15  *
16  * corsaro is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with corsaro. If not, see <http://www.gnu.org/licenses/>.
23  *
24  */
25 
26 #include "config.h"
27 #include "corsaro_int.h"
28 
29 #include <assert.h>
30 #include <stdlib.h>
31 #include <string.h>
32 
33 #include "patricia.h"
34 #include "utils.h"
35 
36 #include "corsaro_log.h"
37 
38 #include "corsaro_geo.h"
39 
44 static const char *provider_names[] = {
45  NULL,
46  "maxmind",
47  "netacq-edge",
48  "pfx2as",
49 };
50 
51 #define STATE(type, ds) \
52  ((corsaro_geo_datastructure_state_##type##_t*)(ds)->state)
53 
56 typedef struct corsaro_geo_datastructure_state_patricia
57 {
58  patricia_tree_t *trie;
59 } corsaro_geo_datastructure_state_patricia_t;
60 
61 static int patricia_init(corsaro_t *corsaro, corsaro_geo_datastructure_t *ds)
62 {
63  /* the ds structure is malloc'd already, we just need to init the state */
64 
65  assert(STATE(patricia, ds) == NULL);
66 
67  if((ds->state = malloc(sizeof(corsaro_geo_datastructure_state_patricia_t)))
68  == NULL)
69  {
70  corsaro_log(__func__, corsaro, "could not malloc patricia state");
71  return -1;
72  }
73 
75  STATE(patricia, ds)->trie = New_Patricia(32);
76  assert(STATE(patricia, ds)->trie != NULL);
77 
78  return 0;
79 }
80 
81 static void patricia_free(corsaro_geo_datastructure_t *ds)
82 {
83  if(ds == NULL)
84  {
85  return;
86  }
87 
88  if(STATE(patricia, ds) != NULL)
89  {
90  if(STATE(patricia, ds)->trie != NULL)
91  {
92  Destroy_Patricia(STATE(patricia, ds)->trie, NULL);
93  STATE(patricia, ds)->trie = NULL;
94  }
95  free(STATE(patricia, ds));
96  ds->state = NULL;
97  }
98 
99  free(ds);
100 
101  return;
102 }
103 
104 static int patricia_add_prefix(corsaro_t *corsaro,
106  uint32_t addr, uint8_t mask,
108 {
109  assert(corsaro != NULL && ds != NULL && ds->state != NULL);
110  patricia_tree_t *trie = STATE(patricia, ds)->trie;
111  assert(trie != NULL);
112 
113  prefix_t trie_pfx;
115  trie_pfx.family = AF_INET;
116  trie_pfx.ref_count = 0;
117  patricia_node_t *trie_node;
118 
119  trie_pfx.bitlen = mask;
120  trie_pfx.add.sin.s_addr = addr;
121  if((trie_node = patricia_lookup(trie, &trie_pfx)) == NULL)
122  {
123  corsaro_log(__func__, corsaro, "failed to insert prefix in trie");
124  return -1;
125  }
126  trie_node->data = record;
127 
128  return 0;
129 }
130 
131 static corsaro_geo_record_t *patricia_lookup_record(corsaro_t *corsaro,
133  uint32_t addr)
134 {
135  assert(corsaro != NULL && ds != NULL && ds->state != NULL);
136  patricia_tree_t *trie = STATE(patricia, ds)->trie;
137  assert(trie != NULL);
138 
139  patricia_node_t *node = NULL;
140  prefix_t pfx;
142  pfx.family = AF_INET;
143  pfx.bitlen = 32;
144  pfx.ref_count = 0;
145  pfx.add.sin.s_addr = addr;
146 
147  if((node = patricia_search_best2(trie, &pfx, 1)) == NULL)
148  {
149  return NULL;
150  }
151  else
152  {
153  return node->data;
154  }
155 
156  return NULL;
157 }
158 
159 static corsaro_geo_datastructure_t patricia_ds =
160  {
162  "patricia",
163  patricia_init,
164  patricia_free,
165  patricia_add_prefix,
166  patricia_lookup_record,
167  NULL,
168  };
169 
170 static void free_record(corsaro_geo_record_t *record)
171 {
172  if(record == NULL)
173  {
174  return;
175  }
176 
177  /* free the strings */
178  if(record->city != NULL)
179  {
180  free(record->city);
181  record->city = NULL;
182  }
183 
184  if(record->post_code != NULL)
185  {
186  free(record->post_code);
187  record->post_code = NULL;
188  }
189 
190  if(record->asn != NULL)
191  {
192  free(record->asn);
193  record->asn = NULL;
194  record->asn_cnt = 0;
195  }
196 
197  free(record);
198  return;
199 }
200 
201 /* --- Public functions below here -- */
202 
204 {
205  assert(ARR_CNT(provider_names) == CORSARO_GEO_PROVIDER_MAX+1);
206 
207  if(id > CORSARO_GEO_PROVIDER_MAX || id <= 0)
208  {
209  return NULL;
210  }
211 
212  return provider_names[id];
213 }
214 
216 {
217  assert(ARR_CNT(provider_names) == CORSARO_GEO_PROVIDER_MAX+1);
218 
219  return provider_names;
220 }
221 
223  corsaro_t *corsaro,
224  corsaro_geo_provider_id_t provider_id,
226  corsaro_geo_provider_default_t set_default)
227 {
228  corsaro_geo_provider_t *provider;
229  /* first, create the struct */
230  if((provider = malloc_zero(sizeof(corsaro_geo_provider_t))) == NULL)
231  {
232  corsaro_log(__func__, corsaro, "could not malloc corsaro_geo_provider_t");
233  return NULL;
234  }
235 
236  assert(provider_id > 0 && provider_id <= CORSARO_GEO_PROVIDER_MAX);
237 
238  /* set the fields */
239  provider->id = provider_id;
240  provider->name = corsaro_geo_get_provider_name(provider_id);
241 
242  /* initialize the record hash */
243  provider->all_records = kh_init(corsaro_geo_rechash);
244 
245  /* initialize the data structure */
246  if((provider->ds = malloc_zero(sizeof(corsaro_geo_datastructure_t))) == NULL)
247  {
248  corsaro_log(__func__, corsaro,
249  "could not malloc corsaro_geo_datastructure_t");
250  goto err;
251  }
252 
254  switch(ds_id)
255  {
257  memcpy(provider->ds, &patricia_ds, sizeof(corsaro_geo_datastructure_t));
258  break;
259 
260  default:
261  corsaro_log(__func__, corsaro, "invalid geolocation datastructure");
262  goto err;
263  }
264 
266  if(provider->ds->init(corsaro, provider->ds) != 0)
267  {
268  goto err;
269  }
270 
271  provider->records = NULL;
272 
273  /* poke it into corsaro */
274  assert(corsaro->packet != NULL);
275  corsaro->packet->geo_providers[provider_id - 1] = provider;
276 
277  if(set_default == CORSARO_GEO_PROVIDER_DEFAULT_YES)
278  {
279  corsaro->packet->geo_provider_default = provider;
280  }
281 
282  return provider;
283 
284  err:
285  if(provider != NULL)
286  {
287  if(provider->ds != NULL)
288  {
289  provider->ds->free(provider->ds);
290  provider->ds = NULL;
291  }
292  free(provider);
293  }
294  return NULL;
295 
296 }
297 
298 
300  corsaro_geo_provider_t *provider)
301 {
302  /* short circuit if someone passed us a NULL pointer */
303  if(provider == NULL)
304  {
305  return;
306  }
307 
308  /* chances are the packet got free'd before we did */
309  if(corsaro->packet != NULL)
310  {
311  /* ok, lets check if we were the default */
312  if(corsaro->packet->geo_provider_default == provider)
313  {
314  corsaro->packet->geo_provider_default = NULL;
315  }
316 
317  /* remove the pointer from corsaro */
318  corsaro->packet->geo_providers[provider->id - 1] = NULL;
319  }
320 
321  /* attempt to clear the records (just in case) */
322  corsaro_geo_provider_clear(provider);
323 
324  /* free the datastructure */
325  if(provider->ds != NULL)
326  {
327  provider->ds->free(provider->ds);
328  provider->ds = NULL;
329  }
330 
331  /* free the records hash */
332  if(provider->all_records != NULL)
333  {
334  /* this is where the records are free'd */
335  kh_free_vals(corsaro_geo_rechash, provider->all_records, free_record);
336  kh_destroy(corsaro_geo_rechash, provider->all_records);
337  provider->all_records = NULL;
338  }
339 
340  /* finally, free the actual provider structure */
341  free(provider);
342 
343  return;
344 }
345 
347  uint32_t id)
348 {
350  khiter_t khiter;
351  int khret;
352 
353  if((record = malloc_zero(sizeof(corsaro_geo_record_t))) == NULL)
354  {
355  return NULL;
356  }
357 
358  record->id = id;
359 
360  assert(kh_get(corsaro_geo_rechash, provider->all_records, id) ==
361  kh_end(provider->all_records));
362 
363  khiter = kh_put(corsaro_geo_rechash, provider->all_records, id, &khret);
364  kh_value(provider->all_records, khiter) = record;
365 
366  assert(kh_get(corsaro_geo_rechash, provider->all_records, id) !=
367  kh_end(provider->all_records));
368 
369  return record;
370 }
371 
373  uint32_t id)
374 {
375  khiter_t khiter;
376 
377  /* grab the corresponding record from the hash */
378  if((khiter = kh_get(corsaro_geo_rechash, provider->all_records, id))
379  == kh_end(provider->all_records))
380  {
381  return NULL;
382  }
383  return kh_val(provider->all_records, khiter);
384 }
385 
387  corsaro_geo_record_t ***records)
388 {
389  corsaro_geo_record_t **rec_arr = NULL;
390  corsaro_geo_record_t **rec_ptr = NULL;
391  int rec_cnt = kh_size(provider->all_records);
392  khiter_t i;
393 
394  /* if there are no records in the array, don't bother */
395  if(rec_cnt == 0)
396  {
397  *records = NULL;
398  return 0;
399  }
400 
401  /* first we malloc an array to hold all the records */
402  if((rec_arr = malloc(sizeof(corsaro_geo_record_t*) * rec_cnt)) == NULL)
403  {
404  return -1;
405  }
406 
407  rec_ptr = rec_arr;
408  /* insert all the records */
409  for(i = kh_begin(provider->all_records);
410  i != kh_end(provider->all_records);
411  ++i)
412  {
413  if(kh_exist(provider->all_records, i))
414  {
415  *rec_ptr = kh_value(provider->all_records, i);
416  rec_ptr++;
417  }
418  }
419 
420  /* return the array and the count */
421  *records = rec_arr;
422  return rec_cnt;
423 }
424 
426  corsaro_geo_provider_t *provider,
427  uint32_t addr,
428  uint8_t mask,
429  corsaro_geo_record_t *record)
430 {
431  assert(corsaro != NULL && provider != NULL && record != NULL);
432  assert(provider->ds != NULL);
433 
434  return provider->ds->add_prefix(corsaro, provider->ds, addr, mask, record);
435 }
436 
438  corsaro_geo_provider_t *provider,
439  uint32_t addr)
440 {
441  assert(corsaro != NULL && provider != NULL);
442  assert(provider->ds != NULL);
443 
444  return provider->ds->lookup_record(corsaro, provider->ds, addr);
445 }
446 
448 {
449  corsaro_geo_record_t *this = NULL;
450  int cnt = 0;
451 
452  assert(provider != NULL);
453 
454  while(provider->records != NULL)
455  {
456  this = provider->records;
457  provider->records = provider->records->next;
458  this->next = NULL;
459  cnt++;
460  }
461 
462  return cnt;
463 }
464 
466  corsaro_geo_record_t *record)
467 {
468  assert(provider != NULL);
469 
470  /* we allow a null record to be added as a convenience.
471  this allows the result of _lookup_record to be fed directly in here */
472  if(record == NULL)
473  {
474  return;
475  }
476 
477  assert(record->next == NULL);
478 
479  /* set the next of this record to the previous head */
480  record->next = provider->records;
481 
482  /* set the head to this record */
483  provider->records = record;
484 
485  return;
486 }
487 
488 
490 {
491  assert(corsaro != NULL && corsaro->packet != NULL);
492  return corsaro->packet->geo_provider_default;
493 }
494 
497 {
498  assert(corsaro != NULL && corsaro->packet != NULL);
499  assert(id > 0 && id <= CORSARO_GEO_PROVIDER_MAX);
500  return corsaro->packet->geo_providers[id - 1];
501 }
502 
504  const char *name)
505 {
506  corsaro_geo_provider_t *provider;
507  int i;
508 
509  for(i = 1; i <= CORSARO_GEO_PROVIDER_MAX; i++)
510  {
511  if((provider = corsaro_geo_get_by_id(corsaro, i)) != NULL &&
512  strncasecmp(provider->name, name, strlen(provider->name)) == 0)
513  {
514  return provider;
515  }
516  }
517 
518  return NULL;
519 }
520 
522  corsaro_geo_record_t *record)
523 {
524  assert(provider != NULL);
525 
526  /* they are asking for the beginning of the list, or there is no list */
527  if(record == NULL || provider->records == NULL)
528  {
529  return provider->records;
530  }
531 
532  /* otherwise, give them the next one */
533  return record->next;
534 }
535 
537 {
538  int i;
539  if(record == NULL)
540  {
541  return;
542  }
543 
544  fprintf(stdout,
545  "id: %"PRIu32", cc: %s, cont: %d, reg: %s, city: %s, post: %s, "
546  "lat: %f, long: %f, met: %"PRIu32", area: %"PRIu32", "
547  "speed: %s, asn: ",
548  record->id,
549  record->country_code,
550  record->continent_code,
551  record->region,
552  record->city,
553  record->post_code,
554  record->latitude,
555  record->longitude,
556  record->metro_code,
557  record->area_code,
558  record->conn_speed
559  );
560 
561  for(i=0; i<record->asn_cnt; i++)
562  {
563  fprintf(stdout, "%d", record->asn[i]);
564  if(i<record->asn_cnt-1)
565  fprintf(stdout, "_");
566  }
567  fprintf(stdout, "\n");
568 }
569 
570 /* ----- Class Helper Functions below here ------ */
571 
573 const char *corsaro_geo_maxmind_country_code_iso2[] = {
574  "--","AP","EU","AD","AE","AF","AG","AI","AL","AM","CW",
575  "AO","AQ","AR","AS","AT","AU","AW","AZ","BA","BB",
576  "BD","BE","BF","BG","BH","BI","BJ","BM","BN","BO",
577  "BR","BS","BT","BV","BW","BY","BZ","CA","CC","CD",
578  "CF","CG","CH","CI","CK","CL","CM","CN","CO","CR",
579  "CU","CV","CX","CY","CZ","DE","DJ","DK","DM","DO",
580  "DZ","EC","EE","EG","EH","ER","ES","ET","FI","FJ",
581  "FK","FM","FO","FR","SX","GA","GB","GD","GE","GF",
582  "GH","GI","GL","GM","GN","GP","GQ","GR","GS","GT",
583  "GU","GW","GY","HK","HM","HN","HR","HT","HU","ID",
584  "IE","IL","IN","IO","IQ","IR","IS","IT","JM","JO",
585  "JP","KE","KG","KH","KI","KM","KN","KP","KR","KW",
586  "KY","KZ","LA","LB","LC","LI","LK","LR","LS","LT",
587  "LU","LV","LY","MA","MC","MD","MG","MH","MK","ML",
588  "MM","MN","MO","MP","MQ","MR","MS","MT","MU","MV",
589  "MW","MX","MY","MZ","NA","NC","NE","NF","NG","NI",
590  "NL","NO","NP","NR","NU","NZ","OM","PA","PE","PF",
591  "PG","PH","PK","PL","PM","PN","PR","PS","PT","PW",
592  "PY","QA","RE","RO","RU","RW","SA","SB","SC","SD",
593  "SE","SG","SH","SI","SJ","SK","SL","SM","SN","SO",
594  "SR","ST","SV","SY","SZ","TC","TD","TF","TG","TH",
595  "TJ","TK","TM","TN","TO","TL","TR","TT","TV","TW",
596  "TZ","UA","UG","UM","US","UY","UZ","VA","VC","VE",
597  "VG","VI","VN","VU","WF","WS","YE","YT","RS","ZA",
598  "ZM","ME","ZW","A1","A2","O1","AX","GG","IM","JE",
599  "BL","MF", "BQ", "SS",
600  /* Alistair adds AN because Maxmind does not include it, but uses it */
601  "AN",
602 };
603 
605 const char *corsaro_geo_maxmind_country_code_iso3[] = {
606  "--","AP","EU","AND","ARE","AFG","ATG","AIA","ALB","ARM","CUW",
607  "AGO","ATA","ARG","ASM","AUT","AUS","ABW","AZE","BIH","BRB",
608  "BGD","BEL","BFA","BGR","BHR","BDI","BEN","BMU","BRN","BOL",
609  "BRA","BHS","BTN","BVT","BWA","BLR","BLZ","CAN","CCK","COD",
610  "CAF","COG","CHE","CIV","COK","CHL","CMR","CHN","COL","CRI",
611  "CUB","CPV","CXR","CYP","CZE","DEU","DJI","DNK","DMA","DOM",
612  "DZA","ECU","EST","EGY","ESH","ERI","ESP","ETH","FIN","FJI",
613  "FLK","FSM","FRO","FRA","SXM","GAB","GBR","GRD","GEO","GUF",
614  "GHA","GIB","GRL","GMB","GIN","GLP","GNQ","GRC","SGS","GTM",
615  "GUM","GNB","GUY","HKG","HMD","HND","HRV","HTI","HUN","IDN",
616  "IRL","ISR","IND","IOT","IRQ","IRN","ISL","ITA","JAM","JOR",
617  "JPN","KEN","KGZ","KHM","KIR","COM","KNA","PRK","KOR","KWT",
618  "CYM","KAZ","LAO","LBN","LCA","LIE","LKA","LBR","LSO","LTU",
619  "LUX","LVA","LBY","MAR","MCO","MDA","MDG","MHL","MKD","MLI",
620  "MMR","MNG","MAC","MNP","MTQ","MRT","MSR","MLT","MUS","MDV",
621  "MWI","MEX","MYS","MOZ","NAM","NCL","NER","NFK","NGA","NIC",
622  "NLD","NOR","NPL","NRU","NIU","NZL","OMN","PAN","PER","PYF",
623  "PNG","PHL","PAK","POL","SPM","PCN","PRI","PSE","PRT","PLW",
624  "PRY","QAT","REU","ROU","RUS","RWA","SAU","SLB","SYC","SDN",
625  "SWE","SGP","SHN","SVN","SJM","SVK","SLE","SMR","SEN","SOM",
626  "SUR","STP","SLV","SYR","SWZ","TCA","TCD","ATF","TGO","THA",
627  "TJK","TKL","TKM","TUN","TON","TLS","TUR","TTO","TUV","TWN",
628  "TZA","UKR","UGA","UMI","USA","URY","UZB","VAT","VCT","VEN",
629  "VGB","VIR","VNM","VUT","WLF","WSM","YEM","MYT","SRB","ZAF",
630  "ZMB","MNE","ZWE","A1","A2","O1","ALA","GGY","IMN","JEY",
631  "BLM","MAF", "BES", "SSD",
632  /* see above about AN */
633  "ANT",
634 };
635 
637 const char *corsaro_geo_maxmind_country_name[] = {
638  "N/A","Asia/Pacific Region","Europe","Andorra","United Arab Emirates",
639  "Afghanistan","Antigua and Barbuda","Anguilla","Albania","Armenia",
640  "Cura" "\xe7" "ao","Angola","Antarctica","Argentina","American Samoa",
641  "Austria","Australia","Aruba","Azerbaijan","Bosnia and Herzegovina",
642  "Barbados","Bangladesh","Belgium","Burkina Faso","Bulgaria","Bahrain",
643  "Burundi","Benin","Bermuda","Brunei Darussalam","Bolivia","Brazil",
644  "Bahamas","Bhutan","Bouvet Island","Botswana","Belarus","Belize",
645  "Canada","Cocos (Keeling) Islands","Congo, The Democratic Republic of the",
646  "Central African Republic","Congo","Switzerland","Cote D'Ivoire",
647  "Cook Islands","Chile","Cameroon","China","Colombia","Costa Rica","Cuba",
648  "Cape Verde","Christmas Island","Cyprus","Czech Republic","Germany",
649  "Djibouti","Denmark","Dominica","Dominican Republic","Algeria","Ecuador",
650  "Estonia","Egypt","Western Sahara","Eritrea","Spain","Ethiopia","Finland",
651  "Fiji","Falkland Islands (Malvinas)","Micronesia, Federated States of",
652  "Faroe Islands","France","Sint Maarten (Dutch part)","Gabon",
653  "United Kingdom","Grenada","Georgia","French Guiana","Ghana","Gibraltar",
654  "Greenland","Gambia","Guinea","Guadeloupe","Equatorial Guinea","Greece",
655  "South Georgia and the South Sandwich Islands","Guatemala","Guam",
656  "Guinea-Bissau","Guyana","Hong Kong","Heard Island and McDonald Islands",
657  "Honduras","Croatia","Haiti","Hungary","Indonesia","Ireland","Israel",
658  "India","British Indian Ocean Territory","Iraq","Iran, Islamic Republic of",
659  "Iceland","Italy","Jamaica","Jordan","Japan","Kenya","Kyrgyzstan","Cambodia",
660  "Kiribati","Comoros","Saint Kitts and Nevis",
661  "Korea, Democratic People's Republic of","Korea, Republic of","Kuwait",
662  "Cayman Islands","Kazakhstan","Lao People's Democratic Republic","Lebanon",
663  "Saint Lucia","Liechtenstein","Sri Lanka","Liberia","Lesotho","Lithuania",
664  "Luxembourg","Latvia","Libyan Arab Jamahiriya","Morocco","Monaco",
665  "Moldova, Republic of","Madagascar","Marshall Islands","Macedonia","Mali",
666  "Myanmar","Mongolia","Macau","Northern Mariana Islands","Martinique",
667  "Mauritania","Montserrat","Malta","Mauritius","Maldives","Malawi","Mexico",
668  "Malaysia","Mozambique","Namibia","New Caledonia","Niger","Norfolk Island",
669  "Nigeria","Nicaragua","Netherlands","Norway","Nepal","Nauru","Niue",
670  "New Zealand","Oman","Panama","Peru","French Polynesia","Papua New Guinea",
671  "Philippines","Pakistan","Poland","Saint Pierre and Miquelon",
672  "Pitcairn Islands","Puerto Rico","Palestinian Territory","Portugal","Palau",
673  "Paraguay","Qatar","Reunion","Romania","Russian Federation","Rwanda",
674  "Saudi Arabia","Solomon Islands","Seychelles","Sudan","Sweden","Singapore",
675  "Saint Helena","Slovenia","Svalbard and Jan Mayen","Slovakia","Sierra Leone",
676  "San Marino","Senegal","Somalia","Suriname","Sao Tome and Principe",
677  "El Salvador","Syrian Arab Republic","Swaziland","Turks and Caicos Islands",
678  "Chad","French Southern Territories","Togo","Thailand","Tajikistan",
679  "Tokelau","Turkmenistan","Tunisia","Tonga","Timor-Leste","Turkey",
680  "Trinidad and Tobago","Tuvalu","Taiwan","Tanzania, United Republic of",
681  "Ukraine","Uganda","United States Minor Outlying Islands","United States",
682  "Uruguay","Uzbekistan","Holy See (Vatican City State)",
683  "Saint Vincent and the Grenadines","Venezuela","Virgin Islands, British",
684  "Virgin Islands, U.S.","Vietnam","Vanuatu","Wallis and Futuna","Samoa",
685  "Yemen","Mayotte","Serbia","South Africa","Zambia","Montenegro","Zimbabwe",
686  "Anonymous Proxy","Satellite Provider","Other","Aland Islands","Guernsey",
687  "Isle of Man","Jersey","Saint Barthelemy","Saint Martin",
688  "Bonaire, Saint Eustatius and Saba", "South Sudan",
689  /* again, see above about AN */
690  "Netherlands Antilles",
691 };
692 
693 const char *corsaro_geo_maxmind_country_continent[] = {
694  "--", "AS","EU","EU","AS","AS","NA","NA","EU","AS","NA",
695  "AF","AN","SA","OC","EU","OC","NA","AS","EU","NA",
696  "AS","EU","AF","EU","AS","AF","AF","NA","AS","SA",
697  "SA","NA","AS","AN","AF","EU","NA","NA","AS","AF",
698  "AF","AF","EU","AF","OC","SA","AF","AS","SA","NA",
699  "NA","AF","AS","AS","EU","EU","AF","EU","NA","NA",
700  "AF","SA","EU","AF","AF","AF","EU","AF","EU","OC",
701  "SA","OC","EU","EU","NA","AF","EU","NA","AS","SA",
702  "AF","EU","NA","AF","AF","NA","AF","EU","AN","NA",
703  "OC","AF","SA","AS","AN","NA","EU","NA","EU","AS",
704  "EU","AS","AS","AS","AS","AS","EU","EU","NA","AS",
705  "AS","AF","AS","AS","OC","AF","NA","AS","AS","AS",
706  "NA","AS","AS","AS","NA","EU","AS","AF","AF","EU",
707  "EU","EU","AF","AF","EU","EU","AF","OC","EU","AF",
708  "AS","AS","AS","OC","NA","AF","NA","EU","AF","AS",
709  "AF","NA","AS","AF","AF","OC","AF","OC","AF","NA",
710  "EU","EU","AS","OC","OC","OC","AS","NA","SA","OC",
711  "OC","AS","AS","EU","NA","OC","NA","AS","EU","OC",
712  "SA","AS","AF","EU","EU","AF","AS","OC","AF","AF",
713  "EU","AS","AF","EU","EU","EU","AF","EU","AF","AF",
714  "SA","AF","NA","AS","AF","NA","AF","AN","AF","AS",
715  "AS","OC","AS","AF","OC","AS","EU","NA","OC","AS",
716  "AF","EU","AF","OC","NA","SA","AS","EU","NA","SA",
717  "NA","NA","AS","OC","OC","OC","AS","AF","EU","AF",
718  "AF","EU","AF","--","--","--","EU","EU","EU","EU",
719  "NA","NA","NA","AF",
720  /* see above about AN */
721  "NA",
722 };
723 
724 #define COUNTRY_CNT ((unsigned)( \
725  sizeof(corsaro_geo_maxmind_country_code_iso2) / \
726  sizeof(corsaro_geo_maxmind_country_code_iso2[0])))
727 
728 const char *corsaro_geo_get_maxmind_iso2(int country_id)
729 {
730  assert(country_id < COUNTRY_CNT);
731  return corsaro_geo_maxmind_country_code_iso2[country_id];
732 }
733 
734 int corsaro_geo_get_maxmind_iso2_list(const char ***countries)
735 {
736  *countries = corsaro_geo_maxmind_country_code_iso2;
737  return COUNTRY_CNT;
738 }
739 
740 const char *corsaro_geo_get_maxmind_iso3(int country_id)
741 {
742  assert(country_id < COUNTRY_CNT);
743  return corsaro_geo_maxmind_country_code_iso3[country_id];
744 }
745 
746 int corsaro_geo_get_maxmind_iso3_list(const char ***countries)
747 {
748  *countries = corsaro_geo_maxmind_country_code_iso3;
749  return COUNTRY_CNT;
750 }
751 
752 const char *corsaro_geo_get_maxmind_country_name(int country_id)
753 {
754  assert(country_id < COUNTRY_CNT);
755  return corsaro_geo_maxmind_country_name[country_id];
756 }
757 
758 int corsaro_geo_get_maxmind_country_name_list(const char ***countries)
759 {
760  *countries = corsaro_geo_maxmind_country_name;
761  return COUNTRY_CNT;
762 }
763 
764 const char *corsaro_geo_get_maxmind_continent(int country_id)
765 {
766  assert(country_id < COUNTRY_CNT);
767  return corsaro_geo_maxmind_country_continent[country_id];
768 }
769 
771 {
772  *continents = corsaro_geo_maxmind_country_continent;
773  return COUNTRY_CNT;
774 }
uint32_t id
A unique ID for this record (used to join the Blocks and Locations Files)
Definition: corsaro_geo.h:52
void * state
Pointer to a instance-specific state object.
Definition: corsaro_geo.h:201
Structure which represents a geolocation datastructure.
Definition: corsaro_geo.h:175
char * conn_speed
Connection Speed/Type.
Definition: corsaro_geo.h:85
const char * corsaro_geo_get_maxmind_iso2(int country_id)
Get the ISO-3166-1 2 character country code for the given maxmind country id.
Definition: corsaro_geo.c:728
Header file dealing with the corsaro logging sub-system.
int corsaro_geo_get_maxmind_iso3_list(const char ***countries)
Get a list of all possible ISO-3166-1 3 character country codes that maxmind uses.
Definition: corsaro_geo.c:746
void corsaro_geo_free_provider(corsaro_t *corsaro, corsaro_geo_provider_t *provider)
Free the given geolocation provider object.
Definition: corsaro_geo.c:299
int corsaro_geo_get_maxmind_country_name_list(const char ***countries)
Get a list of all possible country names that maxmind uses.
Definition: corsaro_geo.c:758
int corsaro_geo_get_maxmind_iso2_list(const char ***countries)
Get a list of all possible ISO-3166-1 2 character country codes that maxmind uses.
Definition: corsaro_geo.c:734
corsaro_geo_provider_t * corsaro_geo_get_by_id(corsaro_t *corsaro, corsaro_geo_provider_id_t id)
Retrieve the provider object for the given provider ID.
Definition: corsaro_geo.c:495
const char * corsaro_geo_get_provider_name(corsaro_geo_provider_id_t id)
Get the provider name for the given ID.
Definition: corsaro_geo.c:203
#define STATE(corsaro)
Extends the generic plugin state convenience macro in corsaro_plugin.h.
Definition: corsaro_anon.c:105
This provider should be the default geolocation result.
Definition: corsaro_geo.h:110
void corsaro_geo_provider_add_record(corsaro_geo_provider_t *provider, corsaro_geo_record_t *record)
Add the given geolocation record to the head of the given geolocation provider object.
Definition: corsaro_geo.c:465
const char * corsaro_geo_get_maxmind_continent(int country_id)
Get the continent code for the given maxmind country id.
Definition: corsaro_geo.c:764
corsaro_packet_t * packet
A pointer to the wrapper packet passed to the plugins.
Definition: corsaro_int.h:269
Structure which represents a geolocation provider.
Definition: corsaro_geo.h:137
corsaro_geo_record_t * corsaro_geo_provider_lookup_record(corsaro_t *corsaro, corsaro_geo_provider_t *provider, uint32_t addr)
Look up the given address in the provider's datastructure.
Definition: corsaro_geo.c:437
char country_code[3]
2 character string which holds the ISO2 country code
Definition: corsaro_geo.h:55
Highest numbered geolocation provider ID.
Definition: corsaro_geo.h:132
void corsaro_geo_dump_record(corsaro_geo_record_t *record)
Dump the given geolocation record to stdout (for debugging)
Definition: corsaro_geo.c:536
corsaro_geo_record_t * records
The list of records which contain the results of geolocation using this provider. ...
Definition: corsaro_geo.h:153
Header file for common utility functions.
const char * name
The name of the provider.
Definition: corsaro_geo.h:143
struct corsaro_geo_datastructure * ds
The datastructure that will be used to perform pfx => record lookups.
Definition: corsaro_geo.h:149
int corsaro_geo_get_maxmind_country_continent_list(const char ***continents)
Get a mapping of continent codes that maxmind uses.
Definition: corsaro_geo.c:770
int asn_cnt
Number of ASNs in the asn array.
Definition: corsaro_geo.h:91
int corsaro_geo_provider_clear(corsaro_geo_provider_t *provider)
Remove all the existing records from the given geolocation provider.
Definition: corsaro_geo.c:447
corsaro_geo_record_t * corsaro_geo_next_record(corsaro_geo_provider_t *provider, corsaro_geo_record_t *record)
Retrieve the next geolocation provider record in the list.
Definition: corsaro_geo.c:521
enum corsaro_geo_provider_default corsaro_geo_provider_default_t
Should this provider be set to be the default geolocation result provider.
void * malloc_zero(const size_t size)
Allocate memory and set it to zero.
Definition: utils.c:78
static corsaro_in_record_t * record
A pointer to a corsaro record.
Definition: corsaro_main.c:76
double latitude
Latitude of the city.
Definition: corsaro_geo.h:73
double longitude
Longitude of the city.
Definition: corsaro_geo.h:76
corsaro_geo_record_t * corsaro_geo_get_record(corsaro_geo_provider_t *provider, uint32_t id)
Get the geolocation record for the given id.
Definition: corsaro_geo.c:372
corsaro_geo_provider_t * corsaro_geo_get_default(corsaro_t *corsaro)
Retrieve the provider object for the default geolocation provider.
Definition: corsaro_geo.c:489
corsaro_geo_provider_t * geo_provider_default
Default geolocation provider object associated with this packet.
Definition: corsaro_int.h:220
corsaro_geo_provider_t * corsaro_geo_init_provider(corsaro_t *corsaro, corsaro_geo_provider_id_t provider_id, corsaro_geo_datastructure_id_t ds_id, corsaro_geo_provider_default_t set_default)
Allocate a geolocation provider object in the packet state.
Definition: corsaro_geo.c:222
char region[3]
2 character string which represents the region the city is in
Definition: corsaro_geo.h:61
void(* free)(struct corsaro_geo_datastructure *ds)
Pointer to free function.
Definition: corsaro_geo.h:187
uint32_t area_code
Area code.
Definition: corsaro_geo.h:82
corsaro_geo_provider_id_t id
The ID of the provider.
Definition: corsaro_geo.h:140
char * post_code
String which contains the postal code.
Definition: corsaro_geo.h:70
int corsaro_geo_provider_associate_record(corsaro_t *corsaro, corsaro_geo_provider_t *provider, uint32_t addr, uint8_t mask, corsaro_geo_record_t *record)
Register a new prefix to record mapping for the given provider.
Definition: corsaro_geo.c:425
corsaro_geo_provider_t * geo_providers[CORSARO_GEO_PROVIDER_MAX]
Array of geolocation provider objects associated with this packet.
Definition: corsaro_int.h:217
Structure which contains a geolocation record.
Definition: corsaro_geo.h:45
corsaro_geo_record_t *(* lookup_record)(corsaro_t *corsaro, struct corsaro_geo_datastructure *ds, uint32_t addr)
Pointer to lookup record function.
Definition: corsaro_geo.h:196
uint32_t * asn
Array of Autonomous System Numbers.
Definition: corsaro_geo.h:88
struct corsaro_geo_record * next
The next record in the list.
Definition: corsaro_geo.h:99
uint32_t metro_code
Metro code.
Definition: corsaro_geo.h:79
int continent_code
Continent Code.
Definition: corsaro_geo.h:58
const char * corsaro_geo_get_maxmind_country_name(int country_id)
Get the country name for the given maxmind country id.
Definition: corsaro_geo.c:752
corsaro_geo_provider_t * corsaro_geo_get_by_name(corsaro_t *corsaro, const char *name)
Retrieve the provider object for the given provider name.
Definition: corsaro_geo.c:503
int corsaro_geo_get_all_records(corsaro_geo_provider_t *provider, corsaro_geo_record_t ***records)
Get an array of all the geolocation records registered with the given provider.
Definition: corsaro_geo.c:386
Corsaro output state.
Definition: corsaro_int.h:230
#define ARR_CNT(a)
Count the number of elements in an arbitrary array.
Definition: utils.h:60
enum corsaro_geo_datastructure_id corsaro_geo_datastructure_id_t
A unique identifier for each geolocation datastructure that corsaro supports.
void corsaro_log(const char *func, corsaro_t *corsaro, const char *format,...)
Write a formatted string to the logfile associated with an corsaro object.
Definition: corsaro_log.c:113
int(* add_prefix)(corsaro_t *corsaro, struct corsaro_geo_datastructure *ds, uint32_t addr, uint8_t mask, corsaro_geo_record_t *record)
Pointer to add prefix function.
Definition: corsaro_geo.h:190
char * city
String which contains the city name.
Definition: corsaro_geo.h:64
enum corsaro_geo_provider_id corsaro_geo_provider_id_t
A unique identifier for each geolocation provider that corsaro supports.
int(* init)(corsaro_t *corsaro, struct corsaro_geo_datastructure *ds)
Pointer to init function.
Definition: corsaro_geo.h:184
const char * corsaro_geo_get_maxmind_iso3(int country_id)
Get the ISO-3166-1 3 character country code for the given maxmind country id.
Definition: corsaro_geo.c:740
Header file dealing with the corsaro geolocation subsystem.
corsaro_geo_record_t * corsaro_geo_init_record(corsaro_geo_provider_t *provider, uint32_t id)
Allocate an empty geolocation record for the given id.
Definition: corsaro_geo.c:346
const char ** corsaro_geo_get_provider_names()
Get an array of provider names.
Definition: corsaro_geo.c:215
Header file dealing with the internal corsaro functions.