|
19 | 19 | * along with PacketQ. If not, see <http://www.gnu.org/licenses/>.
|
20 | 20 | */
|
21 | 21 |
|
| 22 | +#include "config.h" |
| 23 | + |
22 | 24 | #include "sql.h"
|
23 | 25 | #include "output.h"
|
24 | 26 | #include "packet_handler.h"
|
|
31 | 33 | #ifdef WIN32
|
32 | 34 | #include <windows.h>
|
33 | 35 | #endif
|
| 36 | +#ifdef HAVE_LIBMAXMINDDB |
| 37 | +#include <maxminddb.h> |
| 38 | +#include <sys/types.h> |
| 39 | +#include <sys/stat.h> |
| 40 | +#include <unistd.h> |
| 41 | +static MMDB_s* __cc_mmdb = 0; |
| 42 | +static MMDB_s* __asn_mmdb = 0; |
| 43 | +#endif |
34 | 44 |
|
35 | 45 | namespace packetq {
|
36 | 46 |
|
@@ -1884,14 +1894,12 @@ OP* OP::compile(const std::vector<Table*>& tables, const std::vector<int>& searc
|
1884 | 1894 | } else if (cmpi(get_token(), "netmask")) {
|
1885 | 1895 | m_t = Coltype::_text;
|
1886 | 1896 | ret = new Netmask_func(*this);
|
1887 |
| -#ifdef MAXMINDDB |
1888 | 1897 | } else if (cmpi(get_token(), "cc")) {
|
1889 | 1898 | m_t = Coltype::_text;
|
1890 | 1899 | ret = new Cc_func(*this);
|
1891 | 1900 | } else if (cmpi(get_token(), "asn")) {
|
1892 | 1901 | m_t = Coltype::_int;
|
1893 | 1902 | ret = new Asn_func(*this);
|
1894 |
| -#endif /* MAXMIND */ |
1895 | 1903 | } else if (cmpi(get_token(), "count")) {
|
1896 | 1904 | m_t = Coltype::_int;
|
1897 | 1905 | ret = new Count_func(*this, dest_table);
|
@@ -2511,6 +2519,185 @@ void Trim_func::evaluate(Row** rows, Variant& v)
|
2511 | 2519 | }
|
2512 | 2520 | }
|
2513 | 2521 |
|
| 2522 | +Cc_func::Cc_func(const OP& op) |
| 2523 | + : OP(op) |
| 2524 | +{ |
| 2525 | +#ifdef HAVE_LIBMAXMINDDB |
| 2526 | + if (__cc_mmdb) { |
| 2527 | + return; |
| 2528 | + } |
| 2529 | + |
| 2530 | + std::string db; |
| 2531 | + char* env = getenv("PACKETQ_MAXMIND_CC_DB"); |
| 2532 | + if (env) { |
| 2533 | + db = env; |
| 2534 | + } |
| 2535 | + |
| 2536 | + if (db.empty()) { |
| 2537 | + std::list<std::string> paths = { |
| 2538 | + "/var/lib/GeoIP", "/usr/share/GeoIP", "/usr/local/share/GeoIP" |
| 2539 | + }; |
| 2540 | + |
| 2541 | + if ((env = getenv("PACKETQ_MAXMIND_PATH"))) { |
| 2542 | + paths.push_front(std::string(env)); |
| 2543 | + } |
| 2544 | + |
| 2545 | + std::list<std::string>::iterator i = paths.begin(); |
| 2546 | + for (; i != paths.end(); i++) { |
| 2547 | + db = (*i) + "/GeoLite2-Country.mmdb"; |
| 2548 | + struct stat s; |
| 2549 | + if (!stat(db.c_str(), &s)) { |
| 2550 | + break; |
| 2551 | + } |
| 2552 | + } |
| 2553 | + if (i == paths.end()) { |
| 2554 | + return; |
| 2555 | + } |
| 2556 | + } |
| 2557 | + |
| 2558 | + MMDB_s* mmdb = new MMDB_s; |
| 2559 | + if (!mmdb) { |
| 2560 | + return; |
| 2561 | + } |
| 2562 | + |
| 2563 | + int ret = MMDB_open(db.c_str(), 0, mmdb); |
| 2564 | + if (ret != MMDB_SUCCESS) { |
| 2565 | + fprintf(stderr, "Warning: cannot open MaxMind CC database \"%s\": %s\n", db.c_str(), MMDB_strerror(ret)); |
| 2566 | + free(mmdb); |
| 2567 | + return; |
| 2568 | + } |
| 2569 | + |
| 2570 | + __cc_mmdb = mmdb; |
| 2571 | +#endif |
| 2572 | +} |
| 2573 | + |
| 2574 | +void Cc_func::evaluate(Row** rows, Variant& v) |
| 2575 | +{ |
| 2576 | +#ifdef HAVE_LIBMAXMINDDB |
| 2577 | + if (!__cc_mmdb) { |
| 2578 | + RefCountStringHandle res(RefCountString::construct("")); |
| 2579 | + v = *res; |
| 2580 | + return; |
| 2581 | + } |
| 2582 | + |
| 2583 | + Variant str; |
| 2584 | + m_param[0]->evaluate(rows, str); |
| 2585 | + RefCountStringHandle str_handle(str.get_text()); |
| 2586 | + |
| 2587 | + int gai_error, ret; |
| 2588 | + |
| 2589 | + MMDB_lookup_result_s mmdb_result = MMDB_lookup_string(__cc_mmdb, (*str_handle)->data, &gai_error, &ret); |
| 2590 | + |
| 2591 | + if (gai_error || ret != MMDB_SUCCESS || !mmdb_result.found_entry) { |
| 2592 | + RefCountStringHandle res(RefCountString::construct("")); |
| 2593 | + v = *res; |
| 2594 | + return; |
| 2595 | + } |
| 2596 | + |
| 2597 | + MMDB_entry_data_s entry_data; |
| 2598 | + ret = MMDB_get_value(&mmdb_result.entry, &entry_data, "country", "iso_code", NULL); |
| 2599 | + |
| 2600 | + if (ret != MMDB_SUCCESS || !entry_data.has_data || entry_data.type != MMDB_DATA_TYPE_UTF8_STRING) { |
| 2601 | + RefCountStringHandle res(RefCountString::construct("")); |
| 2602 | + v = *res; |
| 2603 | + return; |
| 2604 | + } |
| 2605 | + |
| 2606 | + RefCountStringHandle res(RefCountString::construct(entry_data.utf8_string, 0, entry_data.data_size)); |
| 2607 | + v = *res; |
| 2608 | +#else |
| 2609 | + RefCountStringHandle res(RefCountString::construct("")); |
| 2610 | + v = *res; |
| 2611 | +#endif |
| 2612 | +} |
| 2613 | + |
| 2614 | +Asn_func::Asn_func(const OP& op) |
| 2615 | + : OP(op) |
| 2616 | +{ |
| 2617 | +#ifdef HAVE_LIBMAXMINDDB |
| 2618 | + if (__asn_mmdb) { |
| 2619 | + return; |
| 2620 | + } |
| 2621 | + |
| 2622 | + std::string db; |
| 2623 | + char* env = getenv("PACKETQ_MAXMIND_ASN_DB"); |
| 2624 | + if (env) { |
| 2625 | + db = env; |
| 2626 | + } |
| 2627 | + |
| 2628 | + if (db.empty()) { |
| 2629 | + std::list<std::string> paths = { |
| 2630 | + "/var/lib/GeoIP", "/usr/share/GeoIP", "/usr/local/share/GeoIP" |
| 2631 | + }; |
| 2632 | + |
| 2633 | + if ((env = getenv("PACKETQ_MAXMIND_PATH"))) { |
| 2634 | + paths.push_front(std::string(env)); |
| 2635 | + } |
| 2636 | + |
| 2637 | + std::list<std::string>::iterator i = paths.begin(); |
| 2638 | + for (; i != paths.end(); i++) { |
| 2639 | + db = (*i) + "/GeoLite2-ASN.mmdb"; |
| 2640 | + struct stat s; |
| 2641 | + if (!stat(db.c_str(), &s)) { |
| 2642 | + break; |
| 2643 | + } |
| 2644 | + } |
| 2645 | + if (i == paths.end()) { |
| 2646 | + return; |
| 2647 | + } |
| 2648 | + } |
| 2649 | + |
| 2650 | + MMDB_s* mmdb = new MMDB_s; |
| 2651 | + if (!mmdb) { |
| 2652 | + return; |
| 2653 | + } |
| 2654 | + |
| 2655 | + int ret = MMDB_open(db.c_str(), 0, mmdb); |
| 2656 | + if (ret != MMDB_SUCCESS) { |
| 2657 | + fprintf(stderr, "Warning: cannot open MaxMind ASN database \"%s\": %s\n", db.c_str(), MMDB_strerror(ret)); |
| 2658 | + free(mmdb); |
| 2659 | + return; |
| 2660 | + } |
| 2661 | + |
| 2662 | + __asn_mmdb = mmdb; |
| 2663 | +#endif |
| 2664 | +} |
| 2665 | + |
| 2666 | +void Asn_func::evaluate(Row** rows, Variant& v) |
| 2667 | +{ |
| 2668 | +#ifdef HAVE_LIBMAXMINDDB |
| 2669 | + if (!__asn_mmdb) { |
| 2670 | + v = -1; |
| 2671 | + return; |
| 2672 | + } |
| 2673 | + |
| 2674 | + Variant str; |
| 2675 | + m_param[0]->evaluate(rows, str); |
| 2676 | + RefCountStringHandle str_handle(str.get_text()); |
| 2677 | + |
| 2678 | + int gai_error, ret; |
| 2679 | + |
| 2680 | + MMDB_lookup_result_s mmdb_result = MMDB_lookup_string(__asn_mmdb, (*str_handle)->data, &gai_error, &ret); |
| 2681 | + |
| 2682 | + if (gai_error || ret != MMDB_SUCCESS || !mmdb_result.found_entry) { |
| 2683 | + v = -1; |
| 2684 | + return; |
| 2685 | + } |
| 2686 | + |
| 2687 | + MMDB_entry_data_s entry_data; |
| 2688 | + ret = MMDB_get_value(&mmdb_result.entry, &entry_data, "autonomous_system_number", NULL); |
| 2689 | + |
| 2690 | + if (ret != MMDB_SUCCESS || !entry_data.has_data || entry_data.type != MMDB_DATA_TYPE_UINT32) { |
| 2691 | + v = -1; |
| 2692 | + return; |
| 2693 | + } |
| 2694 | + |
| 2695 | + v = (int_column)entry_data.uint32; |
| 2696 | +#else |
| 2697 | + v = -1; |
| 2698 | +#endif |
| 2699 | +} |
| 2700 | + |
2514 | 2701 | DB g_db;
|
2515 | 2702 |
|
2516 | 2703 | Coldef Column::m_coldefs[COLTYPE_MAX];
|
|
0 commit comments