1 /*
2 ** Copyright (C) 2004-2020 by Carnegie Mellon University.
3 **
4 ** @OPENSOURCE_LICENSE_START@
5 ** See license information in ../../LICENSE.txt
6 ** @OPENSOURCE_LICENSE_END@
7 */
8 
9 /*
10 **  skcountry.h
11 **
12 **    Functions for getting the two letter country code value for an
13 **    IP address.
14 **
15 **    Based on ccfilter_priv.h by Katherine Prevost, December 2004
16 **
17 **    Mark Thomas
18 **
19 */
20 #ifndef _SKCOUNTRY_H
21 #define _SKCOUNTRY_H
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25 
26 #include <silk/silk.h>
27 
28 RCSIDENTVAR(rcsID_SKCOUNTRY_H, "$SiLK: skcountry.h ef14e54179be 2020-04-14 21:57:45Z mthomas $");
29 
30 #include <silk/silk_types.h>
31 #include <silk/skplugin.h>
32 #include <silk/skprefixmap.h>
33 
34 /**
35  *  @file
36  *
37  *    Functions for processing a specially designed binary prefix map
38  *    file whose entries have a two-later country code as their value.
39  *
40  *    This file is part of libsilk.
41  */
42 
43 
44 #define SK_COUNTRYCODE_INVALID      ((sk_countrycode_t)32383)
45 
46 /**
47  *    This contains the name of an environment variable.  If that
48  *    variable is set, it should name the country code file to use.
49  */
50 #define SK_COUNTRY_MAP_ENVAR        "SILK_COUNTRY_CODES"
51 
52 /**
53  *    If a country code data file name is not provided (neither in the
54  *    environment nor via command line switches where
55  *    supported/required) this is the name of mapping file.
56  */
57 #define SK_COUNTRY_DEFAULT_MAP      "country_codes.pmap"
58 
59 
60 /**
61  *    Abstract type for country code values
62  */
63 typedef uint16_t sk_countrycode_t;
64 
65 
66 /**
67  *    Return the maximum possible country code value.
68  */
69 sk_countrycode_t
70 skCountryGetMaxCode(
71     void);
72 
73 
74 /**
75  *    Given a two letter Country Code in 'name', return the numerical
76  *    value.  Returns SK_COUNTRYCODE_INVALID if 'name' is too long to
77  *    be Country Code or contains illegal characters.  Returns
78  *    SK_COUNTRYCODE_INVALID unless 'name' is ASCII and contains two
79  *    letters, a letter followed by a number, or the string "--".  The
80  *    'name' is not compared with the country code mapping file, so
81  *    returned value may not reflect a known Country Code.
82  */
83 sk_countrycode_t
84 skCountryNameToCode(
85     const char         *name);
86 
87 
88 /**
89  *    Given a numeric Country Code in 'code', fill 'name' with the two
90  *    letter representation of the code, where 'name_len' is the
91  *    number of characters in 'name'.
92  *
93  *    Return NULL if 'name' is NULL or 'name_len' is zero.  If 'code'
94  *    is not a possible Country Code, writes "??" to name.  The 'code'
95  *    is not compared with the country code mapping file, so the
96  *    returned name may not reflect a known country.
97  */
98 char *
99 skCountryCodeToName(
100     sk_countrycode_t    code,
101     char               *name,
102     size_t              name_len);
103 
104 
105 /**
106  *    Return a handle to the prefix map supporting the Country Codes.
107  */
108 const skPrefixMap_t *
109 skCountryGetPrefixMap(
110     void);
111 
112 
113 /**
114  *    Return 1 if the Country Code map contains IPv6 addresses.
115  *    Return 0 if the Country Code map contains only IPv4 addresses.
116  *    Return -1 if the Country Code map is not available.
117  */
118 int
119 skCountryIsV6(
120     void);
121 
122 
123 /**
124  *    Find the Country Code for the IP address 'ipaddr' in the prefix
125  *    map file and return the numerical value.  The caller must invoke
126  *    skCountrySetup() prior to calling this function.
127  *
128  *    Return SK_INVALID_COUNTRY_CODE if the Country Code map has not
129  *    been loaded or if the Country Code map contains only IPv4
130  *    addresses and 'ipaddr' is IPv6.
131  *
132  *    See also skCountryLookupName(), skCountryLookupCodeAndRange().
133  */
134 sk_countrycode_t
135 skCountryLookupCode(
136     const skipaddr_t   *ipaddr);
137 
138 
139 /**
140  *    Find the Country Code for the IP address 'ipaddr' in the prefix
141  *    map file and return the numerical value.  The caller must invoke
142  *    skCountrySetup() prior to calling this function.
143  *
144  *    In addition, set the referents of 'start_range' and 'end_range'
145  *    to the starting and ending IP addresses of the CIDR block in the
146  *    Country Code mapping file that contains 'ipaddr'.
147  *
148  *    Return SK_INVALID_COUNTRY_CODE and leave 'start_range' and
149  *    'end_range' unchanged if the Country Code map has not been
150  *    loaded or if the Country Code map contains only IPv4 addresses
151  *    and 'ipaddr' is IPv6.
152  *
153  *    See also skCountryLookupCode(), skCountryLookupName().
154  */
155 sk_countrycode_t
156 skCountryLookupCodeAndRange(
157     const skipaddr_t   *ipaddr,
158     skipaddr_t         *start_range,
159     skipaddr_t         *end_range);
160 
161 
162 /**
163  *    Find the Country Code for the IP address 'ipaddr' in the prefix
164  *    map file and fill the buffer 'name' with the two letter Country
165  *    Code.  The caller must invoke skCountrySetup() prior to calling
166  *    this function.
167  *
168  *    Return NULL if 'name' is NULL or 'name_len' is zero.  If the
169  *    Country Code map contains only IPv4 addresses and 'ipaddr' is
170  *    IPv6 or if the address cannot be mapped for any other reason,
171  *    write "??" to name.
172  *
173  *    See also skCountryLookupCode(), skCountryLookupCodeAndRange().
174  */
175 char *
176 skCountryLookupName(
177     const skipaddr_t   *ipaddr,
178     char               *name,
179     size_t              name_len);
180 
181 
182 /**
183  *    Load the Country Code map for use by the skCountryLookupCode()
184  *    and skCountryLookupName() functions.
185  *
186  *    Use the Country Code map name in 'map_name' if that value is
187  *    provided.  If not, the environment variable named by
188  *    SK_COUNTRY_ENVAR is used.  If that is empty, the
189  *    SK_COUNTRY_DEFAULT_MAP is used.
190  *
191  *    Return 0 on success or non-zero if the map cannot be found or
192  *    there is a problem reading the file.  On error, a messages will
193  *    be printed using 'errfn' if non-NULL.
194  *
195  *    If the Country Code map was previously initialized, this
196  *    function returns 0.  To load a different map, first destroy the
197  *    current mapping by calling skCountryTeardown().
198  */
199 int
200 skCountrySetup(
201     const char         *map_name,
202     sk_msg_fn_t         errfn);
203 
204 
205 /**
206  *    Remove the Country Code mapping file from memory.
207  */
208 void
209 skCountryTeardown(
210     void);
211 
212 
213 /**
214  *    Add support for the --scc and --dcc switches in rwfilter, and
215  *    the 'scc' and 'dcc' fields in rwcut, rwgroup, rwsort, rwuniq,
216  *    and rwstats.
217  */
218 skplugin_err_t
219 skCountryAddFields(
220     uint16_t            major_version,
221     uint16_t            minor_version,
222     void        UNUSED(*pi_data));
223 
224 
225 #ifdef __cplusplus
226 }
227 #endif
228 #endif /* _SKCOUNTRY_H */
229 
230 /*
231 ** Local Variables:
232 ** mode:c
233 ** indent-tabs-mode:nil
234 ** c-basic-offset:4
235 ** End:
236 */
237