1/*	$Id: ra_token.l,v 1.1.1.1 2006-12-04 00:45:31 pmoutarl Exp $	*/
2
3/*
4 * Copyright (C) International Business Machines  Corp., 2003
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 *    may be used to endorse or promote products derived from this software
17 *    without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 */
30
31/* Author Shirley Ma xma@us.ibm.com */
32
33%option noyywrap
34
35%{
36#include <stdio.h>
37#include <string.h>
38#include <sys/types.h>
39
40#include <netinet/in.h>
41#include <arpa/inet.h>
42
43#include <errno.h>
44#include <syslog.h>
45#include <string.h>
46
47#include "queue.h"
48#include "dhcp6.h"
49#include "config.h"
50#include "common.h"
51
52#define YYABORT(msg) dprintf(LOG_ERR, msg " %s lineno %d.", \
53	rayytext, num_lines)
54
55#define ABORT   do {    \
56	YYABORT("/proc/net/ra6 file parse error");   \
57	exit(1);        \
58} while (0)
59
60#define PROC_RA_FILE "/proc/net/ra6"
61
62const char *raproc_file = "/proc/net/ra6";
63extern struct dhcp6_if *dhcp6_if;
64
65static struct ra_info *rainfo;
66static int num_lines = 1;
67
68%}
69
70digit           [0-9]
71number          ({digit})+
72hexdigit        ([a-f]|[A-F]|[0-9])
73hexdigits	({hexdigit}{1,32})
74whitespace      ([ \t])+
75ifname          [a-zA-Z]+[0-9]+
76flags		[a-zA-Z\-]+
77nl              \n
78
79
80%s S_CNF S_INDEX S_PLEN S_FLAGS S_PREFIX S_RLINK
81
82%%
83
84%{
85	BEGIN S_CNF;
86%}
87
88<S_CNF>{ifname} {if (strcmp(rayytext, dhcp6_if->ifname))
89			BEGIN S_CNF;
90		else {
91			rainfo = (struct ra_info *)malloc(sizeof(*rainfo));
92			if (rainfo == NULL)
93				ABORT;
94			BEGIN S_INDEX;}
95		}
96<S_INDEX>{number} {if (atoi(rayytext) != dhcp6_if->ifid)
97			ABORT;
98		BEGIN S_PLEN;}
99<S_PLEN>{number} {rainfo->plen = atoi(rayytext);
100		BEGIN S_FLAGS;}
101<S_FLAGS>{flags} {if (strchr(rayytext, 'M') != NULL)
102			rainfo->flags |= IF_RA_MANAGED;
103		else
104			rainfo->flags |= IF_RA_OTHERCONF;
105		BEGIN S_PREFIX;}
106<S_PREFIX>{hexdigits} {struct in6_addr addr;
107		struct ra_info *ri, *ri_prev;
108		char buff[128];
109		int i, len = 0;
110		for (i = 0; i < rainfo->plen/4; i ++) {
111			strncpy(buff+len, &rayytext[i*4], 4);
112			len += 4;
113			if (i < 7) {
114				strcpy(buff+len, ":");
115				len += 1;
116			}
117		}
118		if (rainfo->plen < 128) {
119			strcat(buff, ":0");
120			len += 2;
121		}
122		strcat(buff, "\0");
123		if (inet_pton(AF_INET6, buff, &addr) < 1)
124			ABORT;
125		memcpy(&rainfo->prefix, &addr, sizeof(rainfo->prefix));
126		if (dhcp6_if->ralist == NULL) {
127			dhcp6_if->ralist = rainfo;
128			rainfo->next = NULL;
129		} else {
130			ri_prev = dhcp6_if->ralist;
131			for (ri = dhcp6_if->ralist; ri; ri = ri->next) {
132				if (rainfo->plen >= ri->plen) {
133					if (ri_prev == ri) {
134						dhcp6_if->ralist = rainfo;
135						rainfo->next = ri;
136					} else {
137						ri_prev->next = rainfo;
138						rainfo->next = ri;
139					}
140					break;
141				} else {
142					if (ri->next == NULL) {
143						ri->next = rainfo;
144						rainfo->next = NULL;
145						break;
146					} else {
147						ri_prev = ri;
148						continue;
149					}
150				}
151			}
152		}
153		BEGIN S_RLINK;}
154<S_RLINK>{hexdigits} { BEGIN S_CNF;}
155
156{nl}            {num_lines++;}
157{whitespace}    {;}
158
159. {ABORT;}
160
161%%
162
163int
164ra_parse(const char *raname)
165{
166	if ((rayyin = fopen(raname, "r")) == NULL) {
167		if (errno == ENOENT) {
168			return (1);
169		}
170		dprintf(LOG_ERR, "ra_parse: fopen(%s): %s",
171			raname, strerror(errno));
172		return (-1);
173	}
174	yylex();
175	return 0;
176}
177