Index: conf_lex.l diff -u conf_lex.l.orig conf_lex.l --- conf_lex.l.orig 2015-10-05 13:18:33.000000000 +0900 +++ conf_lex.l 2016-11-22 17:23:19.376504000 +0900 @@ -115,6 +115,7 @@ body [Bb][Oo][Dd][Yy] maxpeek [Mm][Aa][Xx][Pp][Ee][Ee][Kk] geoipdb [Gg][Ee][Oo][Ii][Pp][Dd][Bb] +geoipv6db [Gg][Ee][Oo][Ii][Pp][Vv]6[Dd][Bb] geoip [Gg][Ee][Oo][Ii][Pp] ldapconf [Ll][Dd][Aa][Pp][Cc][Oo][Nn][Ff] ldapcheck [Ll][Dd][Aa][Pp][Cc][Hh][Ee][Cc][Kk] @@ -308,6 +309,7 @@ {body} { BEGIN(S_REGEX); return BODY; } {maxpeek} { return MAXPEEK; } {geoipdb} { return GEOIPDB; } +{geoipv6db} { return GEOIPV6DB; } {geoip} { return GEOIP; } {ldapconf} { return LDAPCONF; } {ldapcheck} { return LDAPCHECK; } Index: conf_yacc.y diff -u conf_yacc.y.orig conf_yacc.y --- conf_yacc.y.orig 2015-10-05 13:18:33.000000000 +0900 +++ conf_yacc.y 2016-11-22 17:23:19.378293000 +0900 @@ -8,7 +8,7 @@ %token OPENLIST CLOSELIST BLACKLIST FLUSHADDR CODE ECODE MSG SM_MACRO %token UNSET URLCHECK RACL DACL GLHEADER BODY MAXPEEK STAT POSTMSG FORK %token GETPROP CLEAR PROP AUTH TLS SPF MSGSIZE RCPTCOUNT OP NO SLASH MINUS -%token COMMA TIME GEOIPDB GEOIP PASS FAIL SOFTFAIL NEUTRAL UNKNWON ERROR +%token COMMA TIME GEOIPDB GEOIPV6DB GEOIP PASS FAIL SOFTFAIL NEUTRAL UNKNWON ERROR %token SELF SPF_STATUS LDAPCONF LDAPCHECK LOGFAC LOGFAC_KERN LOGFAC_USER %token LOGFAC_MAIL LOGFAC_DAEMON LOGFAC_AUTH LOGFAC_SYSLOG LOGFAC_LPR %token LOGFAC_NEWS LOGFAC_UUCP LOGFAC_CRON LOGFAC_AUTHPRIV LOGFAC_FTP @@ -147,6 +147,7 @@ | lines socket '\n' | lines user '\n' | lines geoipdb '\n' + | lines geoipv6db '\n' | lines nodetach '\n' | lines lazyaw '\n' | lines report '\n' @@ -759,6 +760,19 @@ #endif } ; +geoipv6db: GEOIPV6DB QSTRING { +#ifdef USE_GEOIP + char path[QSTRLEN + 1]; + + geoip_set_db_v6(quotepath(path, $2, QSTRLEN)); +#else + mg_log(LOG_INFO, + "GeoIP support not compiled in, " + "ignore line %d", + conf_line); +#endif + } + ; report: REPORT NONE { conf.c_report = C_GLNONE; } | REPORT DELAYS { conf.c_report = C_DELAYS; } | REPORT NODELAYS { conf.c_report = C_NODELAYS; } Index: geoip.c diff -u -p geoip.c.orig geoip.c --- geoip.c.orig 2013-03-23 10:43:01.000000000 +0900 +++ geoip.c 2016-11-22 18:01:36.012937000 +0900 @@ -59,7 +59,9 @@ __RCSID("$Id"); #endif static GeoIP *geoip_handle = NULL; +static GeoIP *geoip_handle_v6 = NULL; static char geoip_database[MAXPATHLEN + 1]; +static char geoip_database_v6[MAXPATHLEN + 1]; static pthread_rwlock_t geoip_lock; void @@ -97,6 +99,27 @@ geoip_set_db(name) } } +void +geoip_set_db_v6(name) + char *name; +{ + if (geoip_handle_v6 != NULL) { + GeoIP_delete(geoip_handle_v6); + geoip_handle_v6 = NULL; + } + + strncpy(geoip_database_v6, name, MAXPATHLEN); + geoip_database_v6[MAXPATHLEN] = '\0'; + + geoip_handle_v6 = GeoIP_open(geoip_database_v6, GEOIP_STANDARD); + if (geoip_handle_v6 == NULL) { + mg_log(LOG_WARNING, + "GeoIPv6 databade \"%s\" cannot be used", + geoip_database_v6); + return; + } +} + int geoip_filter(ad, stage, ap, priv) acl_data_t *ad; @@ -119,9 +142,27 @@ void geoip_set_ccode(priv) struct mlfi_priv *priv; { + GEOIP_API const char *(*country_code_by_addr)(GeoIP *, const char *); + GeoIP *handle; char ipstr[IPADDRSTRLEN]; - if (geoip_handle == NULL) { + switch (SA(&priv->priv_addr)->sa_family) { + case AF_INET: + country_code_by_addr = GeoIP_country_code_by_addr; + handle = geoip_handle; + break; +#ifdef AF_INET6 + case AF_INET6: + country_code_by_addr = GeoIP_country_code_by_addr_v6; + handle = geoip_handle_v6; + break; +#endif + default: + mg_log(LOG_DEBUG, "GeoIP not supported address family"); + priv->priv_ccode = NULL; + return; + } + if (handle == NULL) { mg_log(LOG_WARNING, "GeoIP is not available"); priv->priv_ccode = NULL; return; @@ -135,7 +176,7 @@ geoip_set_ccode(priv) } WRLOCK(geoip_lock); - priv->priv_ccode = GeoIP_country_code_by_addr(geoip_handle, ipstr); + priv->priv_ccode = country_code_by_addr(handle, ipstr); UNLOCK(geoip_lock); if (priv->priv_ccode == NULL) Index: geoip.h diff -u geoip.h.orig geoip.h --- geoip.h.orig 2010-02-16 01:38:03.000000000 +0900 +++ geoip.h 2016-11-22 17:23:19.379532000 +0900 @@ -37,6 +37,7 @@ void geoip_init(void); void geoip_set_db(char *); +void geoip_set_db_v6(char *); void geoip_set_ccode(struct mlfi_priv *); int geoip_filter(acl_data_t *, acl_stage_t, struct acl_param *, struct mlfi_priv *); Index: greylist.conf.5 diff -u greylist.conf.5.orig greylist.conf.5 --- greylist.conf.5.orig 2016-01-03 14:06:32.000000000 +0900 +++ greylist.conf.5 2016-11-22 17:23:19.381060000 +0900 @@ -185,6 +185,8 @@ addresses, for instance). The .I geoipdb statement can be used to specify the location of GeoIP database. +.I geoipv6db +statement can be used to specify the location of GeoIPv6 database. .TP .I p0f This is used to match against the remote system OS fingerprint genre and