/*
 * route_info.c
 *
 * See the file COPYING for Copyright conditions.
 * This file is under the GPL.
 * Mostly from route.c and netstat.c from FvK and Fred Baumgarten (and more).
 *
 * created Bernd Eckenfels 1995-10-20
 */

#include <string.h>
#include <linux/route.h>
#include <stdio.h>
#include "support.h"
#include "pathnames.h"
#include "version.h"
#include "config.h"
#include "net-locale.h"

#define E_READ -1

int
route_info(int flag_not,int opt_e)
{
  char buff[4096], iface[16], flags[16];
  char gate_addr[128], net_addr[128];
  char mask_addr[128];
  struct sockaddr snet, sgate, smask;
  struct aftype *ap;
  int num, iflags, metric, refcnt, use, mss, window, irtt;
  FILE *fp;

  printf(NLS_CATGETS(catfd, netstatSet, netstat_table, "Kernel routing table\n"));
  if (opt_e == 1)
	printf(NLS_CATGETS(catfd, netstatSet, netstat_header1,
		"Destination     Gateway         Genmask         "
		"Flags Metric Ref    Use Iface\n"));
  if (opt_e == 2)
	printf(NLS_CATGETS(catfd, netstatSet, netstat_header2,
		"Destination     Gateway         Genmask         "
		"Flags   MSS Window  irtt Iface\n"));
  if (opt_e == 3)
	printf(NLS_CATGETS(catfd, netstatSet, netstat_header3,
		"Destination     Gateway         Genmask         "
		"Flags Metric Ref    Use Iface      "
		"MSS Window irtt\n"));

  if ((fp = fopen(_PATH_PROCNET_ROUTE, "r")) == NULL) {
	perror(_PATH_PROCNET_ROUTE);
	return(E_READ);
  }

  while (fgets(buff, 1023, fp))
  {
	num = sscanf(buff, "%s %s %s %X %d %d %d %s %d %d %d\n",
		iface, net_addr, gate_addr,
		&iflags, &refcnt, &use, &metric, mask_addr,
 		&mss,&window,&irtt);
	if (num != 11) continue;

	/* Fetch and resolve the target address. */
	(void) getsock(net_addr, &snet);
	if ((ap = get_afntype(snet.sa_family)) == NULL) {
		fprintf(stderr, NLS_CATGETS(catfd, netstatSet, netstat_route,
					    "route: unsupported address family %d !\n"),
			snet.sa_family);
		continue;
	}
	strcpy(net_addr, ap->sprint(&snet, (flag_not | 0x8000)));
	net_addr[15] = '\0';
    
	/* Fetch and resolve the gateway address. */
	(void) getsock(gate_addr, &sgate);
	strcpy(gate_addr, ap->sprint(&sgate, flag_not));
	gate_addr[15] = '\0';

	/* Fetch and resolve the genmask. */
	(void) getsock(mask_addr, &smask);
	strcpy(mask_addr, ap->sprint(&smask, 1));
	mask_addr[15] = '\0';

	/* Decode the flags. */
	flags[0] = '\0';
	if (iflags & RTF_UP) strcat(flags, "U");
	if (iflags & RTF_GATEWAY) strcat(flags, "G");
	if (iflags & RTF_REJECT) strcpy(flags,"!");
	if (iflags & RTF_HOST) strcat(flags, "H");
	if (iflags & RTF_REINSTATE) strcat(flags, "R");
	if (iflags & RTF_DYNAMIC) strcat(flags, "D");
	if (iflags & RTF_MODIFIED) strcat(flags, "M");
	/* Print the info. */
	if (opt_e == 1) {
		if (iflags & RTF_REJECT)
			printf("%-15s %-15s %-15s %-5s -      -   %6d -\n",
				net_addr, gate_addr, mask_addr, flags, use);
		else
			printf("%-15s %-15s %-15s %-5s %-6d %-3d %6d %s\n",
			net_addr, gate_addr, mask_addr, flags,
			metric, refcnt, use, iface);
	}
	if (opt_e == 2) {
		if (iflags & RTF_REJECT)
			printf("%-15s %-15s %-15s %-5s     - -          - -\n",
				net_addr, gate_addr, mask_addr, flags);
		else
			printf("%-15s %-15s %-15s %-5s %5d %-5d %6d %s\n",
				net_addr, gate_addr, mask_addr, flags,
				mss, window, irtt, iface);
	}
	if (opt_e == 3) {
		if (iflags & RTF_REJECT)
			printf("%-15s %-15s %-15s %-5s -      -   %6d -            - -      -\n",
				net_addr, gate_addr, mask_addr, flags, use);
		else
			printf("%-15s %-15s %-15s %-5s %-6d %-3d %6d %-6s   %5d %-6d %d\n",
			net_addr, gate_addr, mask_addr, flags,
			metric, refcnt, use, iface, mss, window, irtt);
	}
  }

  (void) fclose(fp);
  return(0);
}
