1/* $NetBSD: dns_rr_filter.c,v 1.2 2017/02/14 01:16:44 christos Exp $ */ 2 3/*++ 4/* NAME 5/* dns_rr_filter 3 6/* SUMMARY 7/* DNS resource record filter 8/* SYNOPSIS 9/* #include <dns.h> 10/* 11/* void dns_rr_filter_compile(title, map_names) 12/* const char *title; 13/* const char *map_names; 14/* INTERNAL INTERFACES 15/* int dns_rr_filter_execute(rrlist) 16/* DNS_RR **rrlist; 17/* 18/* MAPS *dns_rr_filter_maps; 19/* DESCRIPTION 20/* This module implements a simple filter for dns_lookup*() 21/* results. 22/* 23/* dns_rr_filter_compile() initializes a result filter. The 24/* title and map_names arguments are as with maps_create(). 25/* This function may be invoked more than once; only the last 26/* filter takes effect. 27/* 28/* dns_rr_filter_execute() converts each resource record in the 29/* specified list with dns_strrecord to ASCII form and matches 30/* that against the specified maps. If a match is found it 31/* executes the corresponding action. Currently, only the 32/* "ignore" action is implemented. This removes the matched 33/* record from the list. The result is 0 in case of success, 34/* -1 in case of error. 35/* 36/* dns_rr_filter_maps is updated by dns_rr_filter_compile(). 37/* LICENSE 38/* .ad 39/* .fi 40/* The Secure Mailer license must be distributed with this software. 41/* AUTHOR(S) 42/* Wietse Venema 43/* IBM T.J. Watson Research 44/* P.O. Box 704 45/* Yorktown Heights, NY 10598, USA 46/*--*/ 47 48 /* 49 * System library. 50 */ 51#include <sys_defs.h> 52#include <ctype.h> 53 54#ifdef STRCASECMP_IN_STRINGS_H 55#include <strings.h> 56#endif 57 58 /* 59 * Utility library. 60 */ 61#include <msg.h> 62#include <vstring.h> 63#include <myaddrinfo.h> 64 65 /* 66 * Global library. 67 */ 68#include <maps.h> 69 70 /* 71 * DNS library. 72 */ 73#define LIBDNS_INTERNAL 74#include <dns.h> 75 76 /* 77 * Application-specific. 78 */ 79MAPS *dns_rr_filter_maps; 80 81static DNS_RR dns_rr_filter_error[1]; 82 83#define STR vstring_str 84 85/* dns_rr_filter_compile - compile dns result filter */ 86 87void dns_rr_filter_compile(const char *title, const char *map_names) 88{ 89 if (dns_rr_filter_maps != 0) 90 maps_free(dns_rr_filter_maps); 91 dns_rr_filter_maps = maps_create(title, map_names, 92 DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX); 93} 94 95/* dns_rr_action - execute action from filter map */ 96 97static DNS_RR *dns_rr_action(const char *cmd, DNS_RR *rr, const char *rr_text) 98{ 99 const char *cmd_args = cmd + strcspn(cmd, " \t"); 100 int cmd_len = cmd_args - cmd; 101 102 while (*cmd_args && ISSPACE(*cmd_args)) 103 cmd_args++; 104 105#define STREQUAL(x,y,l) (strncasecmp((x), (y), (l)) == 0 && (y)[l] == 0) 106 107 if (STREQUAL(cmd, "IGNORE", cmd_len)) { 108 msg_info("ignoring DNS RR: %s", rr_text); 109 return (0); 110 } else { 111 msg_warn("%s: unknown DNS filter action: \"%s\"", 112 dns_rr_filter_maps->title, cmd); 113 return (dns_rr_filter_error); 114 } 115 return (rr); 116} 117 118/* dns_rr_filter_execute - filter DNS lookup result */ 119 120int dns_rr_filter_execute(DNS_RR **rrlist) 121{ 122 static VSTRING *buf = 0; 123 DNS_RR **rrp; 124 DNS_RR *rr; 125 const char *map_res; 126 DNS_RR *act_res; 127 128 /* 129 * Convert the resource record to string form, then search the maps for a 130 * matching action. 131 */ 132 if (buf == 0) 133 buf = vstring_alloc(100); 134 for (rrp = rrlist; (rr = *rrp) != 0; /* see below */ ) { 135 map_res = maps_find(dns_rr_filter_maps, dns_strrecord(buf, rr), 136 DICT_FLAG_NONE); 137 if (map_res != 0) { 138 if ((act_res = dns_rr_action(map_res, rr, STR(buf))) == 0) { 139 *rrp = rr->next; /* do not advance in the list */ 140 rr->next = 0; 141 dns_rr_free(rr); 142 continue; 143 } else if (act_res == dns_rr_filter_error) { 144 return (-1); 145 } 146 } else if (dns_rr_filter_maps->error) { 147 return (-1); 148 } 149 rrp = &(rr->next); /* do advance in the list */ 150 } 151 return (0); 152} 153