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

📄 import-tinydns.c

📁 此dns服务器是在mydns基础上改写
💻 C
📖 第 1 页 / 共 2 页
字号:
/**************************************************************************************************	$Id: import-tinydns.c,v 1.14 2005/04/20 16:49:12 bboy Exp $	import-tinydns.c: Import DNS data from a tinydns-data format data file.	Copyright (C) 2002-2005  Don Moore <bboy@bboy.net>	This program is free software; you can redistribute it and/or modify	it under the terms of the GNU General Public License as published by	the Free Software Foundation; either version 2 of the License, or	(at Your option) any later version.	This program is distributed in the hope that it will be useful,	but WITHOUT ANY WARRANTY; without even the implied warranty of	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the	GNU General Public License for more details.	You should have received a copy of the GNU General Public License	along with this program; if not, write to the Free Software	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA**************************************************************************************************/#include "util.h"#ifdef TINYDNS_IMPORT#define MAX_FIELDS	20											/* Max fields per line */#define TINYDNS_DEF_REFRESH	16384#define TINYDNS_DEF_RETRY		2048#define TINYDNS_DEF_EXPIRE		1048576#define TINYDNS_DEF_MINIMUM	2560#define TINYDNS_DEF_TTL			2560typedef struct _zone{	uint32_t id;	char		*origin, *ns, *mbox;	uint32_t	serial, refresh, retry, expire, minimum, ttl;} ZONE;static ZONE	**Zones = NULL;									/* List of zones found */static int	numZones = 0;										/* Number of zones found */static uint32_t		default_serial;						/* Default serial */static unsigned int	lineno;									/* Current line number */static char				*filename;								/* Input file name */static char				*field[MAX_FIELDS];					/* Fields parsed from line */static char				tinydns_zone[DNS_MAXNAMELEN+1];	/* Zone to import (only this zone) */extern uint32_t		import_zone_id;						/* ID of current zone */extern uint32_t import_soa(const char *origin, const char *ns, const char *mbox,  unsigned serial, unsigned refresh, unsigned retry, unsigned expire,  unsigned minimum, unsigned ttl);extern void import_rr(char *name, char *type, char *data, unsigned aux, unsigned ttl);/**************************************************************************************************	TWARN	Convenience function; outputs error message for current file/line.**************************************************************************************************/static voidtwarn(const char *fmt, ...){	va_list	ap;	char		buf[1024];	va_start(ap, fmt);	vsnprintf(buf, sizeof(buf)-1, fmt, ap);	va_end(ap);	Warnx("%s: line %u: %s", filename, lineno, buf);	return;}/*--- twarn() -----------------------------------------------------------------------------------*//**************************************************************************************************	ZONE_OK	Given an fqdn, is this a zone we want to process?**************************************************************************************************/static inline intzone_ok(const char *fqdn){	if (!tinydns_zone[0])										/* Processing all zones */		return 1;	if (!strcasecmp(fqdn, tinydns_zone))					/* Exact match on zone */		return 1;	/* Does FQDN at least end with the zone? */	if (strlen(fqdn) > strlen(tinydns_zone)		 && !strcasecmp(fqdn + strlen(fqdn) - strlen(tinydns_zone), tinydns_zone))		return 1;	return 0;}/*--- zone_ok() ---------------------------------------------------------------------------------*//**************************************************************************************************	ZONECMP	Comparison function for sorting zones.**************************************************************************************************/static intzonecmp(const void *p1, const void *p2){	ZONE *z1 = *(ZONE **)p1, *z2 = *(ZONE **)p2;	return strcasecmp(z1->origin, z2->origin);}/*--- zonecmp() ---------------------------------------------------------------------------------*//**************************************************************************************************	FIND_ZONE	Looks for the specified zone.  Returns it if found, else NULL.**************************************************************************************************/static inline ZONE *find_zone(const char *origin){	register int n;	for (n = 0; n < numZones; n++)		if (!strcasecmp(Zones[n]->origin, origin))			return Zones[n];	return NULL;}/*--- find_zone() -------------------------------------------------------------------------------*//**************************************************************************************************	FIND_HOST_ZONE	Looks for the zone matching the provided FQDN.  Returns it if found, else NULL.  Also sets	the hostname part of 'fqdn' in 'hostname'.**************************************************************************************************/static inline ZONE *find_host_zone(char *fqdn, char *hostname){	register char *c;	ZONE *z;	hostname[0] = '\0';	if ((z = find_zone(fqdn)))									/* See if 'fqdn' is a plain zone origin */		return (z);	for (c = fqdn; *c; c++)		if (*c == '.')			if ((z = find_zone(c + 1)))			{				memcpy(hostname, fqdn, c - fqdn);				hostname[c - fqdn] = '\0';				return (z);			}	return NULL;}/*--- find_host_zone() --------------------------------------------------------------------------*//**************************************************************************************************	FIND_ARPA_ZONE	Given an IP address in numbers-and-dots format, returns the relevant in-addr.arpa zone, or	NULL if not found.**************************************************************************************************/static inline ZONE *find_arpa_zone(const char *ip, char *hostname){	char zone[DNS_MAXNAMELEN + 1], buf[DNS_MAXNAMELEN + 1], *p, *a, *b, *c, *d;	ZONE *z;	hostname[0] = '\0';	strncpy(buf, ip, sizeof(buf)-1);	p = buf;	if (!(a = strsep(&p, ".")) || !(b = strsep(&p, "."))		 || !(c = strsep(&p, ".")) || !(d = strsep(&p, ".")))		return NULL;	snprintf(zone, sizeof(zone), "%s.in-addr.arpa", a);	if ((z = find_zone(zone)))	{		snprintf(hostname, DNS_MAXNAMELEN, "%s.%s.%s", d, c, b);		return z;	}	snprintf(zone, sizeof(zone), "%s.%s.in-addr.arpa", b, a);	if ((z = find_zone(zone)))	{		snprintf(hostname, DNS_MAXNAMELEN, "%s.%s", d, c);		return z;	}	snprintf(zone, sizeof(zone), "%s.%s.%s.in-addr.arpa", c, b, a);	if ((z = find_zone(zone)))	{		strncpy(hostname, d, DNS_MAXNAMELEN);		return z;	}	return NULL;}/*--- find_arpa_zone() --------------------------------------------------------------------------*//**************************************************************************************************	NEW_ZONE	Adds a new zone.  Returns the zone.**************************************************************************************************/static ZONE *new_zone(const char *originp){	ZONE *z;	char origin[DNS_MAXNAMELEN+1];	/* If this is an 'in-addr.arpa' zone, knock off the first quad if present */	if (strlen(originp) > 12 && !strcasecmp(originp + strlen(originp) - 13, ".in-addr.arpa"))	{		char buf[DNS_MAXNAMELEN+1], *p, *a, *b, *c, *d;		strncpy(buf, originp, sizeof(buf)-1);		p = buf;		if ((d = strsep(&p, ".")) && (c = strsep(&p, "."))			 && (b = strsep(&p, ".")) && (a = strsep(&p, ".")))			snprintf(origin, sizeof(origin), "%s.%s.%s.in-addr.arpa", c, b, a);		else			strncpy(origin, originp, sizeof(origin)-1);	}	else		strncpy(origin, originp, sizeof(origin)-1);	if ((z = find_zone(origin)))		return z;	if (!(z = malloc(sizeof(ZONE))))		Err("malloc");	z->id = 0;	if (!(z->origin = strdup(origin)))		Err("strdup");	z->ns = NULL;	z->mbox = NULL;	z->serial = default_serial;	z->refresh = TINYDNS_DEF_REFRESH;	z->retry = TINYDNS_DEF_RETRY;	z->expire = TINYDNS_DEF_EXPIRE;	z->minimum = TINYDNS_DEF_MINIMUM;	z->ttl = TINYDNS_DEF_TTL;	if (!Zones)	{		if (!(Zones = malloc((numZones + 1) * sizeof(ZONE))))			Err("malloc");	}	else	{		if (!(Zones = realloc(Zones, (numZones + 1) * sizeof(ZONE))))			Err("realloc");	}	Zones[numZones++] = z;	return z;}/*--- new_zone() --------------------------------------------------------------------------------*//**************************************************************************************************	TINYDNS_ADD_SOA	Adds a zone to 'Zones' due to a '.' or 'Z' line.**************************************************************************************************/voidtinydns_add_soa(char *line){	char	*l = line + 1;	ZONE	*z;	if (line[0] == '.')											/* '.' (NS) line */	{		char *fqdn = NULL, *ip = NULL, *x = NULL, *ttl = NULL, *timestamp = NULL, *lo = NULL;		if (!(fqdn = strsep(&l, ":")) || !strlen(fqdn))			return twarn("'.' line has no fqdn");		if (!zone_ok(fqdn))			return;		if (!(ip = strsep(&l, ":")))			return twarn("'.' line has no ip");		if ((x = strsep(&l, ":")) && (ttl = strsep(&l, ":")) && (timestamp = strsep(&l, ":"))			 && (lo = strsep(&l, ":")))			/* DONOTHING */;		z = new_zone(fqdn);		/* Assign 'ns' */		if (!z->ns)		{			if (!x || !strlen(x))				sdprintf(&z->ns, "ns.%s", fqdn);			else if (strchr(x, '.'))			{				if (!(z->ns = strdup(x)))					Err("strdup");			}			else				sdprintf(&z->ns, "%s.ns.%s", x, fqdn);		}		/* Assign 'mbox' */		if (!z->mbox)			sdprintf(&z->mbox, "hostmaster.%s", fqdn);	}	else if (line[0] == 'Z')									/* 'Z' (SOA) line */	{		char *fqdn = NULL, *ns = NULL, *mbox = NULL, *serial = NULL, *refresh = NULL,			  *retry = NULL, *expire = NULL, *minimum = NULL, *ttl = NULL, *timestamp = NULL,			  *lo = NULL;		if (!(fqdn = strsep(&l, ":")) || !strlen(fqdn))			return twarn("'Z' line has no fqdn");		if (!zone_ok(fqdn))			return;		if (!(ns = strsep(&l, ":")) || !strlen(ns))			return twarn("'Z' line has no ns");		if (!(mbox = strsep(&l, ":")) || !strlen(mbox))			return twarn("'Z' line has no mbox");		if ((serial = strsep(&l, ":")) && (refresh = strsep(&l, ":")) && (retry = strsep(&l, ":"))			 && (expire = strsep(&l, ":")) && (minimum = strsep(&l, ":")) && (ttl = strsep(&l, ":"))			 && (timestamp = strsep(&l, ":")) && (lo = strsep(&l, ":")))			/* DONOTHING */;		z = new_zone(fqdn);		if (!z->ns)		{			if (!(z->ns = strdup(ns)))				Err("strdup");		}		if (!z->mbox)		{			if (!(z->mbox = strdup(mbox)))				Err("strdup");		}		if (serial) z->serial = atol(serial);		if (refresh) z->refresh = atol(refresh);		if (retry) z->retry = atol(retry);		if (expire) z->expire = atol(expire);		if (minimum) z->minimum = atol(minimum);		if (ttl) z->ttl = atol(ttl);	}}/*--- tinydns_add_soa() -------------------------------------------------------------------------*//**************************************************************************************************	CREATE_ZONE	Loads or creates the actual SOA record and loads the ID.**************************************************************************************************/static voidcreate_zone(ZONE *z){	char origin[DNS_MAXNAMELEN + 3], ns[DNS_MAXNAMELEN + 3], mbox[DNS_MAXNAMELEN + 3];	if (!z->ns)		sdprintf(&z->ns, "ns.%s", z->origin);	if (!z->mbox)		sdprintf(&z->mbox, "hostmaster.%s", z->origin);	snprintf(origin, sizeof(origin), "%s.", z->origin);	snprintf(ns, sizeof(ns), "%s.", z->ns);	snprintf(mbox, sizeof(mbox), "%s.", z->mbox);	z->id = import_soa(origin, ns, mbox,							 z->serial, z->refresh, z->retry, z->expire, z->minimum, z->ttl);}/*--- create_zone() -----------------------------------------------------------------------------*//**************************************************************************************************	TINYDNS_PLUS	+fqdn:ip:ttl:timestamp:lo	Alias fqdn with IP address ip. This is just like =fqdn:ip:ttl except that tinydns-data	does not create the PTR record.**************************************************************************************************/static voidtinydns_plus(void){	ZONE	*z;	char	*fqdn = field[0], *ip = field[1], *ttl = field[2];	char	hostname[DNS_MAXNAMELEN + 1] = "";	if (!fqdn || !strlen(fqdn))		return (void)Warnx("%s:%u: %s", filename, lineno, _("fqdn field empty"));	if (!zone_ok(fqdn))		return;	if (!(z = find_host_zone(fqdn, hostname)))		return (void)Warnx("%s:%u: %s: %s", filename, lineno, fqdn, _("fqdn does not match any zones"));	/* Set import_zone_id and import the record */	if (ip && strlen(ip))	{		import_zone_id = z->id;		import_rr(hostname, "A", ip, 0, ttl ? atol(ttl) : z->ttl);	}}/*--- tinydns_plus() ----------------------------------------------------------------------------*//**************************************************************************************************	TINYDNS_DOT	.fqdn:ip:x:ttl:timestamp:lo	1. Create an NS record showing x.ns.fqdn as a name server for fqdn	2. Create an A record showing ip as the IP address of x.ns.fqdn**************************************************************************************************/static voidtinydns_dot(void){	ZONE	*z;	char	*fqdn = field[0], *ip = field[1], *x = field[2], *ttl = field[3];	char	hostname[DNS_MAXNAMELEN + 1] = "", buf[DNS_MAXNAMELEN + 1];	if (!fqdn || !strlen(fqdn))		return (void)Warnx("%s:%u: %s", filename, lineno, _("fqdn field empty"));	if (!zone_ok(fqdn))		return;	if (!(z = find_host_zone(fqdn, hostname)))		return (void)Warnx("%s:%u: %s: %s", filename, lineno, fqdn, _("fqdn does not match any zones"));	import_zone_id = z->id;	/* Create NS record */	if (x && strlen(x))	{		if (strchr(x, '.'))			strncpy(buf, x, sizeof(buf)-1);		else			snprintf(buf, sizeof(buf), "%s.ns", x);		if (LASTCHAR(buf) != '.')			strcat(buf, ".");		import_rr(hostname, "NS", buf, 0, ttl ? atol(ttl) : z->ttl);	}	else	{		strncpy(buf, "ns", sizeof(buf)-1);		import_rr(hostname, "NS", buf, 0, ttl ? atol(ttl) : z->ttl);	}	/* Create A record if 'ip' is present */	if (ip && strlen(ip))		import_rr(buf, "A", ip, 0, ttl ? atol(ttl) : z->ttl);}/*--- tinydns_dot() -----------------------------------------------------------------------------*//**************************************************************************************************	TINYDNS_AMP	&fqdn:ip:x:ttl:timestamp:lo

⌨️ 快捷键说明

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