/*
 * 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 "vrf.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, NULL, 0, VRF_DEFAULT, RT_TABLE_MAIN,
		      0, 0, SAFI_UNICAST);
}

void
route_read (struct zebra_vrf *zvrf)
{
	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 (zvrf->vrf_id != VRF_DEFAULT) {
		return;
	}

	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 &&
			(size_t)msgdata.len >= sizeof (struct T_optmgmt_ack) &&
			TLIack->PRIM_type == T_OPTMGMT_ACK &&
			TLIack->MGMT_flags == T_SUCCESS &&
			MIB2hdr->len == 0)
			break;

		if ((size_t)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 ||
			(size_t)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);
}
