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

📄 server6_parse.y

📁 DHCPv6协议在Linux操作系统下的一个客户端实现。
💻 Y
📖 第 1 页 / 共 2 页
字号:
/*	$Id: server6_parse.y,v 1.9 2004/02/05 00:10:31 shemminger Exp $	*//* * Copyright (C) International Business Machines  Corp., 2003 * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. Neither the name of the project nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. *//* Author: Shirley Ma, xma@us.ibm.com */%{#include <stdio.h>#include <string.h>#include <syslog.h>#include <errno.h>#include <sys/socket.h>#include <net/if.h>#include <linux/ipv6.h>#include "queue.h"#include "dhcp6.h"#include "config.h"#include "common.h"#include "server6_conf.h"#include "hash.h"#include "lease.h"extern int num_lines;extern char *sfyytext;extern int sock;static struct interface *ifnetworklist = NULL;static struct link_decl *linklist = NULL;static struct host_decl *hostlist = NULL;static struct pool_decl *poollist = NULL;static struct interface *ifnetwork = NULL;static struct link_decl *link = NULL;static struct host_decl *host = NULL;static struct pool_decl *pool = NULL;static struct scopelist *currentscope = NULL;static struct scopelist *currentgroup = NULL;static int allow = 0;static void cleanup(void);void sfyyerror(char *msg);#define ABORT	do { cleanup(); YYABORT; } while (0)extern int sfyylex __P((void));%}%token	<str>	INTERFACE IFNAME%token	<str>	PREFIX%token	<str>	LINK	%token	<str>	RELAY%token	<str>	STRING%token	<num>	NUMBER%token	<snum>	SIGNEDNUMBER%token	<dec>	DECIMAL%token	<bool>	BOOLEAN%token	<addr>	IPV6ADDR%token 	<str>	INFINITY%token	<str>	HOST%token	<str>	POOL%token	<str>	RANGE%token	<str>	GROUP%token	<str>	LINKLOCAL%token	<str>	OPTION ALLOW SEND%token	<str>	PREFERENCE%token	<str>	RENEWTIME%token	<str>	REBINDTIME%token	<str>	RAPIDCOMMIT%token	<str>	ADDRESS%token	<str>	VALIDLIFETIME%token	<str>	PREFERLIFETIME%token	<str>	UNICAST%token	<str>	TEMPIPV6ADDR%token	<str>	DNS_SERVERS%token	<str>	DUID DUID_ID%token	<str>	IAID IAIDINFO%token  <str>	INFO_ONLY%token	<str>	TO%token	<str>	BAD_TOKEN%type	<str>	name%type   <num>	number_or_infinity%type	<dhcp6addr>	hostaddr6 hostprefix6 addr6para v6address%union {	unsigned int	num;	int 	snum;	char	*str;	int 	dec;	int	bool;	struct in6_addr	addr;	struct dhcp6_addr *dhcp6addr;}%%statements		: 	| statements networkdef 	;networkdef		: ifdef	| groupdef	| confdecl	| linkdef	;ifdef			: ifhead '{' ifbody  '}' ';'	{		if (linklist) {			ifnetwork->linklist = linklist;			linklist = NULL;		}		if (hostlist) {			ifnetwork->hostlist = hostlist;			hostlist = NULL;		}		if (currentgroup) 			ifnetwork->group = currentgroup->scope;		dprintf(LOG_DEBUG, "interface definition for %s is ok", ifnetwork->name);		ifnetwork->next = ifnetworklist;		ifnetworklist = ifnetwork;		ifnetwork = NULL;		globalgroup->iflist = ifnetworklist;		/* leave interface scope we know the current scope is not point to NULL*/		currentscope = pop_double_list(currentscope);	} 		;ifhead			: INTERFACE IFNAME 	{		struct interface *temp_if = ifnetworklist;		while (temp_if)		{			if (!strcmp(temp_if->name, $2))			{				dprintf(LOG_ERR, "duplicate interface definition for %s",					temp_if->name);				ABORT;			}			temp_if = temp_if->next;		}		ifnetwork = (struct interface *)malloc(sizeof(*ifnetwork));		if (ifnetwork == NULL) {			dprintf(LOG_ERR, "failed to allocate memory");			ABORT;		}		memset(ifnetwork, 0, sizeof(*ifnetwork));		TAILQ_INIT(&ifnetwork->ifscope.dnslist.addrlist);		strncpy(ifnetwork->name, $2, strlen($2)); 		if (get_linklocal(ifnetwork->name, &ifnetwork->linklocal) < 0) {			dprintf(LOG_ERR, "get device %s linklocal failed", ifnetwork->name);		}				/* check device, if the device is not available,		 * it is OK, it might be added later		 * so keep this in the configuration file.		 */		if (if_nametoindex(ifnetwork->name) == 0) {			dprintf(LOG_ERR, "this device %s doesn't exist.", $2);		}		/* set up hw_addr, link local, primary ipv6addr */		/* enter interface scope */		currentscope = push_double_list(currentscope, &ifnetwork->ifscope);		if (currentscope == NULL)			ABORT;	}	;ifbody	:	| ifbody ifparams	;ifparams	: linkdef	| hostdef	| groupdef	| confdecl	;	linkdef		: linkhead '{' linkbody '}' ';'	{		if (poollist) {			link->poollist = poollist;			poollist = NULL;		}		if (currentgroup) 			link->group = currentgroup->scope;		link->next = linklist;		linklist = link;		link = NULL;		/* leave iink scope we know the current scope is not point to NULL*/		currentscope = pop_double_list(currentscope);	}	;linkhead		: LINK name	{		struct link_decl *temp_sub = linklist;		/* memory allocation for link */		link = (struct link_decl *)malloc(sizeof(*link));		if (link == NULL) {			dprintf(LOG_ERR, "failed to allocate memory");			ABORT;		}		memset(link, 0, sizeof(*link));		TAILQ_INIT(&link->linkscope.dnslist.addrlist);		while (temp_sub) {			if (!strcmp(temp_sub->name, $2))			{				dprintf(LOG_ERR, "duplicate link definition for %s", $2);				ABORT;			}			temp_sub = temp_sub->next;		}					/* link set */		strncpy(link->name, $2, strlen($2));		if (ifnetwork)			link->network = ifnetwork;		else {			/* create a ifnetwork for this interface */		}		link->relaylist = NULL;		link->seglist = NULL;		/* enter link scope */		currentscope = push_double_list(currentscope, &link->linkscope);		if (currentscope == NULL)			ABORT;	}	;	linkbody		:  	| linkbody linkparams	| relaylist 	;linkparams		: pooldef	| rangedef	| prefixdef	| hostdef	| groupdef	| confdecl	;relaylist		: relaylist relaypara	| relaypara	;relaypara		: RELAY IPV6ADDR '/' NUMBER ';'	{		struct v6addrlist *temprelay;		if (!link) {			dprintf(LOG_ERR, "relay must be defined under link");			ABORT;		}		temprelay = (struct v6addrlist *)malloc(sizeof(*temprelay));		if (temprelay == NULL) {			dprintf(LOG_ERR, "failed to allocate memory");			ABORT;		}		memset(temprelay, 0, sizeof(*temprelay));		memcpy(&temprelay->v6addr.addr, &$2, sizeof(temprelay->v6addr.addr));		temprelay->v6addr.plen = $4;		temprelay->next = link->relaylist;		link->relaylist = temprelay;		temprelay = NULL;	}	;pooldef			: poolhead '{' poolbody '}' ';'	{		if (currentgroup) 			pool->group = currentgroup->scope;		pool->next = poollist;		poollist = pool;		pool = NULL;		/* leave pool scope we know the current scope is not point to NULL*/		currentscope = pop_double_list(currentscope);	}	;poolhead		: POOL	{		if (!link) {			dprintf(LOG_ERR, "pooldef must be defined under link");			ABORT;		}		pool = (struct pool_decl *)malloc(sizeof(*pool));		if (pool == NULL) {			dprintf(LOG_ERR, "fail to allocate memory");			ABORT;		}		memset(pool, 0, sizeof(*pool));		TAILQ_INIT(&pool->poolscope.dnslist.addrlist);		if (link)			pool->link = link;					/* enter pool scope */		currentscope = push_double_list(currentscope, &pool->poolscope);		if (currentscope == NULL)			ABORT;	}	;poolbody		: 	| poolbody poolparas 	;poolparas		: hostdef	| groupdef	| rangedef	| prefixdef	| confdecl	;prefixdef	: PREFIX IPV6ADDR '/' NUMBER ';'	{		struct v6prefix *v6prefix, *v6prefix0;		struct v6addr *prefix;		if (!link) {			dprintf(LOG_ERR, "prefix must be defined under link");			ABORT;		}		v6prefix = (struct v6prefix *)malloc(sizeof(*v6prefix));		if (v6prefix == NULL) {			dprintf(LOG_ERR, "failed to allocate memory");			ABORT;		}		memset(v6prefix, 0, sizeof(*v6prefix));		v6prefix->link = link;		if (pool)			v6prefix->pool = pool;		/* make sure the range ipv6 address within the prefixaddr */		if ($4 > 128 || $4 < 0) {			dprintf(LOG_ERR, "invalid prefix length in line %d", num_lines);			ABORT;		}		prefix = getprefix(&$2, $4);		for (v6prefix0 = link->prefixlist; v6prefix0; v6prefix0 = v6prefix0->next) {			if (IN6_ARE_ADDR_EQUAL(prefix, &v6prefix0->prefix.addr) && 					$4 == v6prefix0->prefix.plen)  {				dprintf(LOG_ERR, "duplicated prefix defined within same link");				ABORT;			}		}		/* check the assigned prefix is not reserved pv6 addresses */		if (IN6_IS_ADDR_RESERVED(prefix)) {			dprintf(LOG_ERR, "config reserved prefix");			ABORT;		}		memcpy(&v6prefix->prefix, prefix, sizeof(v6prefix->prefix));		v6prefix->next = link->prefixlist;		link->prefixlist = v6prefix;		free(prefix);	}	;rangedef	: RANGE IPV6ADDR TO IPV6ADDR '/' NUMBER ';'	{		struct v6addrseg *seg, *temp_seg;		struct v6addr *prefix1, *prefix2;		if (!link) {			dprintf(LOG_ERR, "range must be defined under link");			ABORT;		}		seg = (struct v6addrseg *)malloc(sizeof(*seg));		if (seg == NULL) {			dprintf(LOG_ERR, "failed to allocate memory");			ABORT;		}		memset(seg, 0, sizeof(*seg));		temp_seg = link->seglist;		seg->link = link;		if (pool)			seg->pool = pool;		/* make sure the range ipv6 address within the prefixaddr */		if ($6 > 128 || $6 < 0) {			dprintf(LOG_ERR, "invalid prefix length in line %d", num_lines);			ABORT;		}		prefix1 = getprefix(&$2, $6);		prefix2 = getprefix(&$4, $6);		if (!prefix1 || !prefix2) {			dprintf(LOG_ERR, "address range defined error");			ABORT;		}		if (ipv6addrcmp(&prefix1->addr, &prefix2->addr)) {			dprintf(LOG_ERR, 				"address range defined doesn't in the same prefix range");			ABORT;		}		if (ipv6addrcmp(&$2, &$4) < 0) {			memcpy(&seg->min, &$2, sizeof(seg->min));			memcpy(&seg->max, &$4, sizeof(seg->max));		} else {			memcpy(&seg->max, &$2, sizeof(seg->max));			memcpy(&seg->min, &$4, sizeof(seg->min));		}		/* check the assigned addresses are not reserved ipv6 addresses */		if (IN6_IS_ADDR_RESERVED(&seg->max) || IN6_IS_ADDR_RESERVED(&seg->max)) {			dprintf(LOG_ERR, "config reserved ipv6address");			ABORT;		}		memcpy(&seg->prefix, prefix1, sizeof(seg->prefix));		memcpy(&seg->free, &seg->min, sizeof(seg->free));		if (pool)			seg->pool = pool;		/* make sure there is no overlap in the rangelist */		/* the segaddr is sorted by prefix len, thus most specific		   ipv6 address is going to be assigned.		 */		if (!temp_seg) {			seg->next = NULL;			seg->prev = NULL;			link->seglist = seg;		} else {			for (; temp_seg; temp_seg = temp_seg->next) { 				if ( prefix1->plen < temp_seg->prefix.plen) {					if (temp_seg->next == NULL) {						temp_seg->next = seg;						seg->prev = temp_seg;						seg->next = NULL;						break;					}					continue;

⌨️ 快捷键说明

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