⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 check.c

📁 此dns服务器是在mydns基础上改写
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (LASTCHAR(name) != '.')		rrproblem(_("soa.origin is not a FQDN (no trailing dot)"));	if (soa->refresh < 300) rrproblem(_("soa.refresh is less than 300 seconds"));	if (soa->retry < 300) rrproblem(_("soa.retry is less than 300 seconds"));	if (soa->expire < 300) rrproblem(_("soa.expire is less than 300 seconds"));	if (soa->minimum < 300) rrproblem(_("soa.minimum is less than 300 seconds"));	if (soa->ttl < 300) rrproblem(_("soa.ttl is less than 300 seconds"));	if (soa->minimum < 300) rrproblem(_("soa.minimum is less than 300 seconds"));	return (soa);}/*--- check_soa() -------------------------------------------------------------------------------*//**************************************************************************************************	CHECK_RR_CNAME	Expanded check for CNAME resource record.**************************************************************************************************/static voidcheck_rr_cname(void){	unsigned char *xname;	int found = 0;	EXPAND_DATA(data);	check_name(data, "rr.data", 1);	/* A CNAME record can't have any other type of RR data for the same name */	if (!(xname = calloc(strlen(name) * 2 + 1, sizeof(unsigned char))))		Err(_("out of memory"));	sql_escstr(sql, xname, (unsigned char *)name, strlen(name));	found = sql_count(sql, "SELECT COUNT(*) FROM %s WHERE zone=%u AND name='%s' AND type != 'CNAME'",								  mydns_rr_table_name, rr->zone, xname);	/* If not found that way, check short name */	if (!found)	{		Free(xname);		shortname(name, 1);		if (!(xname = calloc(strlen(name) * 2 + 1, sizeof(unsigned char))))			Err(_("out of memory"));		sql_escstr(sql, xname, (unsigned char *)name, strlen(name));		found = sql_count(sql, "SELECT COUNT(*) FROM %s WHERE zone=%u AND name='%s' AND type != 'CNAME'",									  mydns_rr_table_name, rr->zone, xname);		EXPAND_DATA(name);	}	if (found)		rrproblem(_("non-CNAME record(s) present alongside CNAME"));	Free(xname);}/*--- check_rr_cname() --------------------------------------------------------------------------*//**************************************************************************************************	CHECK_RR_HINFO	Expanded check for HINFO resource record.**************************************************************************************************/static voidcheck_rr_hinfo(void){	char	os[DNS_MAXNAMELEN + 1] = "", cpu[DNS_MAXNAMELEN + 1] = "";	if (hinfo_parse(rr->data, cpu, os, DNS_MAXNAMELEN) < 0)		rrproblem(_("data too long in HINFO record"));}/*--- check_rr_hinfo() --------------------------------------------------------------------------*//**************************************************************************************************	CHECK_RR_NAPTR	Expanded check for NAPTR resource record.**************************************************************************************************/static voidcheck_rr_naptr(void){	char tmp[DNS_MAXNAMELEN * 2 + 2], data_copy[DNS_MAXNAMELEN * 2 + 2], *p;	strncpy(data_copy, rr->data, sizeof(data_copy) - 1);	p = data_copy;	if (!strsep_quotes(&p, tmp, sizeof(tmp)))		return rrproblem(_("'order' field missing from NAPTR record"));	if (!strsep_quotes(&p, tmp, sizeof(tmp)))		return rrproblem(_("'preference' field missing from NAPTR record"));	if (!strsep_quotes(&p, tmp, sizeof(tmp)))		return rrproblem(_("'flags' field missing from NAPTR record"));	if (!strsep_quotes(&p, tmp, sizeof(tmp)))		return rrproblem(_("'service' field missing from NAPTR record"));	if (!strsep_quotes(&p, tmp, sizeof(tmp)))		return rrproblem(_("'regexp' field missing from NAPTR record"));	if (!strsep_quotes(&p, tmp, sizeof(tmp)))		return rrproblem(_("'replacement' field missing from NAPTR record"));	/* For now, don't check 'replacement'.. the example in the RFC even contains illegal chars */	/* EXPAND_DATA(tmp); */	/* check_name(tmp, "replacement", 1); */}/*--- check_rr_naptr() --------------------------------------------------------------------------*//**************************************************************************************************	CHECK_RR	Check an individual resource record.**************************************************************************************************/static voidcheck_rr(void){	/* Expand RR's name into `name' */	strncpy(name, rr->name, sizeof(name)-1);	strncpy(data, rr->data, sizeof(data)-1);	EXPAND_DATA(name);	check_name(name, "rr.name", 1);	if (!ignore_minimum && (rr->ttl < soa->minimum))		rrproblem(_("TTL below zone minimum"));	switch (rr->type)	{		case DNS_QTYPE_A:											/* Data: IPv4 address */			{				struct in_addr addr;#if ALIAS_ENABLED				if (rr->alias == 1)					check_rr_cname();				else				{#endif /* ALIAS_ENABLED */					if (inet_pton(AF_INET, data, (void *)&addr) <= 0)						rrproblem(_("IPv4 address in `data' is invalid"));#if ALIAS_ENABLED				}#endif /* ALIAS_ENABLED */			}			break;		case DNS_QTYPE_AAAA:										/* Data: IPv6 address */			{				uint8_t addr[16];				if (inet_pton(AF_INET6, data, (void *)&addr) <= 0)					rrproblem(_("IPv6 address in `data' is invalid"));			}			break;		case DNS_QTYPE_CNAME:									/* Data: Name */			check_rr_cname();			break;		case DNS_QTYPE_HINFO:									/* Data: Host info */			check_rr_hinfo();			break;		case DNS_QTYPE_MX:										/* Data: Name */			EXPAND_DATA(data);			check_name(data, "rr.data", 1);			break;		case DNS_QTYPE_NAPTR:									/* Data: Multiple fields */			check_rr_naptr();			break;		case DNS_QTYPE_NS:										/* Data: Name */			EXPAND_DATA(data);			check_name(data, "rr.data", 1);			break;		case DNS_QTYPE_PTR:										/* Data: PTR */			/* TODO */			break;		case DNS_QTYPE_RP:										/* Data: Responsible person */			{				char	txt[DNS_MAXNAMELEN*2];				strncpy(txt, rr->rp_txt, sizeof(txt)-1);				EXPAND_DATA(txt);				check_name(data, "rr.data (mbox)", 1);				check_name(txt, "rr.data (txt)", 1);			}			break;		case DNS_QTYPE_SRV:										/* Data: Server location */			/* TODO */			break;		case DNS_QTYPE_TXT:										/* Data: Undefined text string */			/* Can be anything, so consider it always OK */			break;		default:			rrproblem(_("Unknown/unsupported resource record type"));			break;	}}/*--- check_rr() --------------------------------------------------------------------------------*/                                                                                                                               /**************************************************************************************************	CHECK_ZONE	Checks each RR in the current zone through check_rr.**************************************************************************************************/static voidcheck_zone(void){	char query[BUFSIZ];	size_t querylen;	unsigned int rrct = 0;	SQL_RES *res;	SQL_ROW row;	querylen = snprintf(query, sizeof(query), "SELECT "MYDNS_RR_FIELDS" FROM %s WHERE zone=%u",		mydns_rr_table_name, soa->id);	if (!(res = sql_query(sql, query, querylen)))		return;	while ((row = sql_getrow(res)))	{		if (!(rr = mydns_rr_parse(row, soa->origin)))			continue;		check_rr();		mydns_rr_free(rr);		rrct++;   }	sql_free(res);	if (err_verbose)	{		meter(0, 0);		Verbose("%s: %u %s", soa->origin, rrct, rrct == 1 ? _("resource record") : _("resource records"));	}}/*--- check_zone() ------------------------------------------------------------------------------*//**************************************************************************************************	CONSISTENCY_RR_ZONE	Makes sure rr.zone matches a soa.id.**************************************************************************************************/static voidconsistency_rr_zone(void){	char query[BUFSIZ];	size_t querylen;	SQL_RES *res;	SQL_ROW row;	querylen = snprintf(query, sizeof(query),      "SELECT %s.id,%s.zone FROM %s LEFT JOIN %s ON %s.zone=%s.id WHERE %s.id IS NULL",		mydns_rr_table_name, mydns_rr_table_name, mydns_rr_table_name, mydns_soa_table_name,		mydns_rr_table_name, mydns_soa_table_name, mydns_soa_table_name);	if (!(res = sql_query(sql, query, querylen)))		return;	while ((row = sql_getrow(res)))	{		char msg[80];		meter(0,0);		snprintf(msg, sizeof(msg),					_("%s id %s references invalid %s id %s"),					mydns_rr_table_name, row[0], mydns_soa_table_name, row[1]);		printf("%s\t-\t%s\t-\t-\t-\t-\t-\n", msg, row[0]);		fflush(stdout);		consistency_errors++;	}	sql_free(res);}/*--- consistency_rr_zone() ---------------------------------------------------------------------*//**************************************************************************************************	CONSISTENCY_CHECK	Does a general database consistency check - makes sure all keys are kosher.**************************************************************************************************/static voidconsistency_check(void){	consistency_rr_zone();}/*--- consistency_check() -----------------------------------------------------------------------*//**************************************************************************************************	MAIN**************************************************************************************************/intmain(int argc, char **argv){	setlocale(LC_ALL, "");										/* Internationalization */	bindtextdomain(PACKAGE, LOCALEDIR);	textdomain(PACKAGE);	cmdline(argc, argv);	load_config();	ignore_minimum = GETBOOL(conf_get(&Conf, "ignore-minimum", NULL));	db_connect();	if (!opt_consistency_only)	{		if (optind >= argc)											/* Check all zones */		{			char query[BUFSIZ];			size_t querylen;			SQL_RES *res;			SQL_ROW row;			unsigned long current = 0, total;			querylen = snprintf(query, sizeof(query), "SELECT origin FROM %s", mydns_soa_table_name);			if ((res = sql_query(sql, query, querylen)))			{				total = sql_num_rows(res);				while ((row = sql_getrow(res)))				{					meter(current++, total);					if ((soa = check_soa(row[0])))					{						check_zone();						mydns_soa_free(soa);					}				}				sql_free(res);			}		}		else while (optind < argc)									/* Check zones provided as args */		{			char zone[DNS_MAXNAMELEN+2];			strncpy(zone, argv[optind++], sizeof(zone)-2);			if (LASTCHAR(zone) != '.')				strcat(zone, ".");			if ((soa = check_soa(zone)))			{				check_zone();				mydns_soa_free(soa);			}		}	}	if (opt_consistency)		consistency_check();											/* Do consistency check if requested */	meter(0, 0);	if (!syntax_errors && !consistency_errors)		Verbose(_("No errors"));	else	{		if (opt_consistency_only)			Verbose("%s: %d", _("Consistency errors"), consistency_errors);		else if (opt_consistency)			Verbose("%s: %d  %s: %d",					 _("Syntax errors"), syntax_errors, _("Consistency errors"), consistency_errors);		else			Verbose("%s: %d", _("Syntax errors"), syntax_errors);	}	return (0);}/*--- main() ------------------------------------------------------------------------------------*//* vi:set ts=3: *//* NEED_PO */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -