/*
 * Kernel routing table readup by getmsg(2)
 * Copyright (C) 1999 Michael Handler
 *
 * This file is part of GNU Zebra.
 *
 * GNU Zebra 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, or (at your option) any
 * later version.
 *
 * GNU Zebra 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 GNU Zebra; see the file COPYING.  If not, write to the Free
 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 * 02111-1307, USA.  
 */

#include <zebra.h>

#include "prefix.h"
#include "log.h"
#include "if.h"

#include "zebra/rib.h"
#include "zebra/zserv.h"

#include <sys/stream.h>
#include <sys/tihdr.h>

/* Solaris defines these in both <netinet/in.h> and <inet/in.h>, sigh */
#ifdef SUNOS_5
#include <sys/tiuser.h>
#ifndef T_CURRENT
#define T_CURRENT       MI_T_CURRENT
#endif /* T_CURRENT */
#ifndef IRE_CACHE
#define IRE_CACHE               0x0020  /* Cached Route entry */
#endif /* IRE_CACHE */
#ifndef IRE_HOST_REDIRECT
#define IRE_HOST_REDIRECT       0x0200  /* Host route entry from redirects */
#endif /* IRE_HOST_REDIRECT */
#ifndef IRE_CACHETABLE
#define IRE_CACHETABLE          (IRE_CACHE | IRE_BROADCAST | IRE_LOCAL | \
                                 IRE_LOOPBACK)
#endif /* IRE_CACHETABLE */
#undef IPOPT_EOL
#undef IPOPT_NOP
#undef IPOPT_LSRR
#undef IPOPT_RR
#undef IPOPT_SSRR
#endif /* SUNOS_5 */

#include <inet/common.h>
#include <inet/ip.h>
#include <inet/mib2.h>

/* device to read IP routing table from */
#ifndef _PATH_GETMSG_ROUTE
#define _PATH_GETMSG_ROUTE	"/dev/ip"
#endif /* _PATH_GETMSG_ROUTE */

#define RT_BUFSIZ		8192

static void 
handle_route_entry (mib2_ipRouteEntry_t *routeEntry)
{
	struct prefix_ipv4	prefix;
 	struct in_addr		tmpaddr, gateway;
	u_char			zebra_flags = 0;

	if (routeEntry->ipRouteInfo.re_ire_type & IRE_CACHETABLE)
		return;

	if (routeEntry->ipRouteInfo.re_ire_type & IRE_HOST_REDIRECT)
		zebra_flags |= ZEBRA_FLAG_SELFROUTE;

	prefix.family = AF_INET;

	tmpaddr.s_addr = routeEntry->ipRouteDest;
	prefix.prefix = tmpaddr;

	tmpaddr.s_addr = routeEntry->ipRouteMask;
	prefix.prefixlen = ip_masklen (tmpaddr);

	gateway.s_addr = routeEntry->ipRouteNextHop;

	rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &prefix,
		      &gateway, 0, 0, 0, 0);
}

void
route_read (void)
{
	char 			storage[RT_BUFSIZ];

	struct T_optmgmt_req	*TLIreq = (struct T_optmgmt_req *) storage;
	struct T_optmgmt_ack	*TLIack = (struct T_optmgmt_ack *) storage;
	struct T_error_ack	*TLIerr = (struct T_error_ack *) storage;

	struct opthdr		*MIB2hdr;

	mib2_ipRouteEntry_t	*routeEntry, *lastRouteEntry;

	struct strbuf		msgdata;
	int			flags, dev, retval, process;

	if ((dev = open (_PATH_GETMSG_ROUTE, O_RDWR)) == -1) {
		zlog_warn ("can't open %s: %s", _PATH_GETMSG_ROUTE,
			safe_strerror (errno));
		return;
	}

	TLIreq->PRIM_type = T_OPTMGMT_REQ;
	TLIreq->OPT_offset = sizeof (struct T_optmgmt_req);
	TLIreq->OPT_length = sizeof (struct opthdr);
	TLIreq->MGMT_flags = T_CURRENT;

	MIB2hdr = (struct opthdr *) &TLIreq[1];

	MIB2hdr->level = MIB2_IP;
	MIB2hdr->name = 0;
	MIB2hdr->len = 0;
	
	msgdata.buf = storage;
	msgdata.len = sizeof (struct T_optmgmt_req) + sizeof (struct opthdr);

	flags = 0;

	if (putmsg (dev, &msgdata, NULL, flags) == -1) {
		zlog_warn ("putmsg failed: %s", safe_strerror (errno));
		goto exit;
	}

	MIB2hdr = (struct opthdr *) &TLIack[1];
	msgdata.maxlen = sizeof (storage);

	while (1) {
		flags = 0;
		retval = getmsg (dev, &msgdata, NULL, &flags);

		if (retval == -1) {
			zlog_warn ("getmsg(ctl) failed: %s", safe_strerror (errno));
			goto exit;
		}

		/* This is normal loop termination */
		if (retval == 0 &&
			msgdata.len >= sizeof (struct T_optmgmt_ack) &&
			TLIack->PRIM_type == T_OPTMGMT_ACK &&
			TLIack->MGMT_flags == T_SUCCESS &&
			MIB2hdr->len == 0)
			break;

		if (msgdata.len >= sizeof (struct T_error_ack) &&
			TLIerr->PRIM_type == T_ERROR_ACK) {
			zlog_warn ("getmsg(ctl) returned T_ERROR_ACK: %s",
				safe_strerror ((TLIerr->TLI_error == TSYSERR)
				? TLIerr->UNIX_error : EPROTO));
			break;
		}

		/* should dump more debugging info to the log statement,
		   like what GateD does in this instance, but not
		   critical yet. */
		if (retval != MOREDATA ||
			msgdata.len < sizeof (struct T_optmgmt_ack) ||
			TLIack->PRIM_type != T_OPTMGMT_ACK ||
			TLIack->MGMT_flags != T_SUCCESS) {
			errno = ENOMSG;
			zlog_warn ("getmsg(ctl) returned bizarreness");
			break;
		}

		/* MIB2_IP_21 is the the pseudo-MIB2 ipRouteTable
		   entry, see <inet/mib2.h>. "This isn't the MIB data
		   you're looking for." */
		process = (MIB2hdr->level == MIB2_IP &&
			MIB2hdr->name == MIB2_IP_21) ? 1 : 0;

		/* getmsg writes the data buffer out completely, not
		   to the closest smaller multiple. Unless reassembling
		   data structures across buffer boundaries is your idea
		   of a good time, set maxlen to the closest smaller
		   multiple of the size of the datastructure you're
		   retrieving. */
		msgdata.maxlen = sizeof (storage) - (sizeof (storage)
			% sizeof (mib2_ipRouteEntry_t));

		msgdata.len = 0;
		flags = 0;

		do {
			retval = getmsg (dev, NULL, &msgdata, &flags);

			if (retval == -1) {
				zlog_warn ("getmsg(data) failed: %s",
					safe_strerror (errno));
				goto exit;
			}

			if (!(retval == 0 || retval == MOREDATA)) {
				zlog_warn ("getmsg(data) returned %d", retval);
				goto exit;
			}

			if (process) {
				if (msgdata.len %
					sizeof (mib2_ipRouteEntry_t) != 0) {
					zlog_warn ("getmsg(data) returned "
"msgdata.len = %d (%% sizeof (mib2_ipRouteEntry_t) != 0)", msgdata.len);
					goto exit;
				}

				routeEntry = (mib2_ipRouteEntry_t *)
					msgdata.buf;
				lastRouteEntry = (mib2_ipRouteEntry_t *)
					(msgdata.buf + msgdata.len);
				do {
					handle_route_entry (routeEntry);
				} while (++routeEntry < lastRouteEntry);
			}
		} while (retval == MOREDATA);
	}

exit:
	close (dev);
}
