dslinux/user/net-tools/lib Makefile activate.c af.c arcnet.c ash.c ax25.c ax25_gr.c ddp.c ddp_gr.c ec_hw.c econet.c ether.c fddi.c frame.c getargs.c getroute.c hdlclapb.c hippi.c hw.c inet.c inet6.c inet6_gr.c inet6_sr.c inet_gr.c inet_sr.c interface.c ipx.c ipx_gr.c ipx_sr.c irda.c loopback.c masq_info.c net-features.h net-support.h netrom.c netrom_gr.c netrom_sr.c nstrcmp.c pathnames.h ppp.c ppp_ac.c proc.c proc.h rose.c rose_gr.c setroute.c sit.c slip.c slip_ac.c sockets.c strip.c tr.c tunnel.c unix.c util-ank.c util.c util.h x25.c x25_gr.c x25_sr.c

amadeus dslinux_amadeus at user.in-berlin.de
Thu Aug 31 11:32:21 CEST 2006


Update of /cvsroot/dslinux/dslinux/user/net-tools/lib
In directory antilope:/tmp/cvs-serv14346/user/net-tools/lib

Added Files:
	Makefile activate.c af.c arcnet.c ash.c ax25.c ax25_gr.c ddp.c 
	ddp_gr.c ec_hw.c econet.c ether.c fddi.c frame.c getargs.c 
	getroute.c hdlclapb.c hippi.c hw.c inet.c inet6.c inet6_gr.c 
	inet6_sr.c inet_gr.c inet_sr.c interface.c ipx.c ipx_gr.c 
	ipx_sr.c irda.c loopback.c masq_info.c net-features.h 
	net-support.h netrom.c netrom_gr.c netrom_sr.c nstrcmp.c 
	pathnames.h ppp.c ppp_ac.c proc.c proc.h rose.c rose_gr.c 
	setroute.c sit.c slip.c slip_ac.c sockets.c strip.c tr.c 
	tunnel.c unix.c util-ank.c util.c util.h x25.c x25_gr.c 
	x25_sr.c 
Log Message:
Add some more applications

--- NEW FILE: loopback.c ---
/*
 * lib/loopback.c     This file contains the general hardware types.
 *
 * Version:     $Id: loopback.c,v 1.2 2006-08-31 09:32:18 dslinux_amadeus Exp $
 *
 * Author:      Fred N. van Kempen, <waltje at uwalt.nl.mugnet.org>
 *              Copyright 1993 MicroWalt Corporation
 *
 * Modifications:
 * 1998-07-01 - Arnaldo Carvalho de Melo - GNU gettext instead of catgets
 *
 *              This program 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 of the License, or  (at
 *              your option) any later version.
 */
#include "config.h"

#include <sys/types.h>
#include <sys/socket.h>
#include <net/if_arp.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"
#include "util.h"

/* Display an UNSPEC address. */
static char *pr_unspec(unsigned char *ptr)
{
    static char buff[64];
    char *pos;
    unsigned int i;

    pos = buff;
    for (i = 0; i < sizeof(struct sockaddr); i++) {
	pos += sprintf(pos, "%02X-", (*ptr++ & 0377));
    }
    buff[strlen(buff) - 1] = '\0';
    return (buff);
}

struct hwtype unspec_hwtype =
{
    "unspec", NULL, /*"UNSPEC", */ -1, 0,
    pr_unspec, NULL, NULL
};

struct hwtype loop_hwtype =
{
    "loop", NULL, /*"Local Loopback", */ ARPHRD_LOOPBACK, 0,
    NULL, NULL, NULL
};

--- NEW FILE: ax25_gr.c ---
/*
 * lib/ax25_gr.c      This file contains an implementation of the "AX.25"
 *                      route print support functions.
 *
 * Version:     $Id: ax25_gr.c,v 1.2 2006-08-31 09:32:17 dslinux_amadeus Exp $
 *
 * Author:      Bernd Eckenfels, <ecki at lina.inka.de>
 *              Copyright 1999 Bernd Eckenfels, Germany
 *              base on Code from Jonathan Naylor <jsn at Cs.Nott.AC.UK>
 *
 *              This program 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 of the License, or  (at
 *              your option) any later version.
 */
#include "config.h"

#if HAVE_AFAX25
#if 0
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <linux/ax25.h>
#include <linux/if_arp.h>	/* ARPHRD_AX25 */
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"

int AX25_rprint(int options)
{
    FILE *f = fopen(_PATH_PROCNET_AX25_ROUTE, "r");
    char buffer[256];
    int use;

    if (f == NULL) {
        perror(_PATH_PROCNET_AX25_ROUTE);
	printf(_("AX.25 not configured in this system.\n"));	/* xxx */
	return 1;
    }
    printf(_("Kernel AX.25 routing table\n"));	/* xxx */
    printf(_("Destination  Iface    Use\n"));	/* xxx */
    fgets(buffer, 256, f);
    while (fgets(buffer, 256, f)) {
	buffer[9] = 0;
	buffer[14] = 0;
	use = atoi(buffer + 15);
	printf("%-9s    %-5s  %5d\n",
	       buffer, buffer + 10, use);
    }
    fclose(f);
    return 0;
}

#endif				/* HAVE_AFAX25 */

--- NEW FILE: net-support.h ---
/*
 * lib/support.h      This file contains the definitions of what is in the
 *                      support library.  Most of all, it defines structures
 *                      for accessing support modules, and the function proto-
 *                      types.
 *
 * NET-LIB      A collection of functions used from the base set of the
 *              NET-3 Networking Distribution for the LINUX operating
 *              system. (net-tools, net-drivers)
 *
 * Version:     lib/net-support.h 1.35 (1996-01-01)
 *
 * Maintainer:  Bernd 'eckes' Eckenfels, <net-tools at lina.inka.de>
 *
 * Author:      Fred N. van Kempen, <waltje at uwalt.nl.mugnet.org>
 *              Copyright 1993 MicroWalt Corporation
 *
 * Modifications:
 *960125 {1.20} Bernd Eckenfels:        reformated, layout
 *960202 {1.30} Bernd Eckenfels:        rprint in aftype
 *960206 {1.31} Bernd Eckenfels:        route_init
 *960219 {1.32} Bernd Eckenfels:        type for ap->input()
 *960322 {1.33} Bernd Eckenfels:        activate_ld and const in get_hwtype
 *960413 {1.34} Bernd Eckenfels:        new RTACTION suport
 *990101 {1.35} Bernd Eckenfels:	print_(hw|af)list support, added kerneldefines
 *
 *              This program 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 of the License, or  (at
 *              your option) any later version.
 */
#include <sys/socket.h>

/* This structure defines protocol families and their handlers. */
struct aftype {
    char *name;
    char *title;
    int af;
    int alen;
    char *(*print) (unsigned char *);
    char *(*sprint) (struct sockaddr *, int numeric);
    int (*input) (int type, char *bufp, struct sockaddr *);
    void (*herror) (char *text);
    int (*rprint) (int options);
    int (*rinput) (int typ, int ext, char **argv);

    /* may modify src */
    int (*getmask) (char *src, struct sockaddr * mask, char *name);

    int fd;
    char *flag_file;
};

extern struct aftype *aftypes[];

/* This structure defines hardware protocols and their handlers. */
struct hwtype {
    char *name;
    char *title;
    int type;
    int alen;
    char *(*print) (unsigned char *);
    int (*input) (char *, struct sockaddr *);
    int (*activate) (int fd);
    int suppress_null_addr;
};


extern struct hwtype *get_hwtype(const char *name);
extern struct hwtype *get_hwntype(int type);
extern void          print_hwlist(int type);
extern struct aftype *get_aftype(const char *name);
extern struct aftype *get_afntype(int type);
extern void          print_aflist(int type);
extern int           hw_null_address(struct hwtype *hw, void *addr);

extern int getargs(char *string, char *arguments[]);

extern int get_socket_for_af(int af);

extern void getroute_init(void);
extern void setroute_init(void);
extern void activate_init(void);
extern int route_info(const char *afname, int flags);
extern int route_edit(int action, const char *afname, int flags, char **argv);
extern int activate_ld(const char *hwname, int fd);

#define RTACTION_ADD   1
#define RTACTION_DEL   2
#define RTACTION_HELP  3
#define RTACTION_FLUSH 4
#define RTACTION_SHOW  5

#define FLAG_EXT       3		/* AND-Mask */
#define FLAG_NUM_HOST  4
#define FLAG_NUM_PORT  8
#define FLAG_NUM_USER 16
#define FLAG_NUM     (FLAG_NUM_HOST|FLAG_NUM_PORT|FLAG_NUM_USER)
#define FLAG_SYM      32
#define FLAG_CACHE    64
#define FLAG_FIB     128
#define FLAG_VERBOSE 256

extern int ip_masq_info(int numeric_host, int numeric_port, int ext);

extern int INET_rprint(int options);
extern int INET6_rprint(int options);
extern int DDP_rprint(int options);
extern int IPX_rprint(int options);
extern int NETROM_rprint(int options);
extern int AX25_rprint(int options);
extern int X25_rprint(int options);

extern int INET_rinput(int action, int flags, char **argv);
extern int INET6_rinput(int action, int flags, char **argv);
extern int DDP_rinput(int action, int flags, char **argv);
extern int IPX_rinput(int action, int flags, char **argv);
extern int NETROM_rinput(int action, int flags, char **argv);
extern int AX25_rinput(int action, int flags, char **argv);
extern int X25_rinput(int action, int flags, char **argv);

extern int aftrans_opt(const char *arg);
extern void aftrans_def(char *tool, char *argv0, char *dflt);

extern char *get_sname(int socknumber, char *proto, int numeric);

extern int flag_unx;
extern int flag_ipx;
extern int flag_ax25;
extern int flag_ddp;
extern int flag_netrom;
extern int flag_x25;
extern int flag_inet;
extern int flag_inet6;

extern char afname[];

#define AFTRANS_OPTS \
	{"ax25",	0,	0,	1}, \
       {"x25",         0,      0,      1}, \
	{"ip",		0,	0,	1}, \
	{"ipx",         0,	0,	1}, \
	{"appletalk",	0,	0,	1}, \
	{"netrom",	0,	0,	1}, \
	{"inet",	0,	0,	1}, \
	{"inet6",	0,	0,	1}, \
	{"ddp",		0,	0,	1}, \
	{"unix",	0,	0,	1}, \
	{"tcpip",	0,	0,	1}
#define AFTRANS_CNT 11

#define EINTERN(file, text) fprintf(stderr, \
	_("%s: Internal Error `%s'.\n"),file,text);

#define ENOSUPP(A,B)	fprintf(stderr,\
                                _("%s: feature `%s' not supported.\n" \
				  "Please recompile `net-tools' with "\
				  "newer kernel source or full configuration.\n"),A,B)

#define ESYSNOT(A,B)	fprintf(stderr, _("%s: no support for `%s' on this system.\n"),A,B)

#define E_NOTFOUND	8
#define E_SOCK		7
#define E_LOOKUP	6
#define E_VERSION	5
#define E_USAGE		4
#define E_OPTERR	3
#define E_INTERN	2
#define E_NOSUPP	1


/* ========== Kernel Defines =============
 * Since it is not a good idea to depend on special kernel sources for the headers
 * and since the libc6 Headers are not always up to date, we keep a copy of the
 * most often used Flags in this file. We realy need a way to keep them up-to-date.
 * Perhaps anybody knows how the glibc2 folk is doing it? -ecki
 */

/* Keep this ins sync with /usr/src/linux/include/linux/rtnetlink.h */
#define RTNH_F_DEAD            1       /* Nexthop is dead (used by multipath)  */
#define RTNH_F_PERVASIVE       2       /* Do recursive gateway lookup  */
#define RTNH_F_ONLINK          4       /* Gateway is forced on link    */

/* Keep this in sync with /usr/src/linux/include/linux/in_route.h */
#define RTCF_DEAD       RTNH_F_DEAD
#define RTCF_ONLINK     RTNH_F_ONLINK
/* #define RTCF_NOPMTUDISC RTM_F_NOPMTUDISC */
#define RTCF_NOTIFY     0x00010000
#define RTCF_DIRECTDST  0x00020000
#define RTCF_REDIRECTED 0x00040000
#define RTCF_TPROXY     0x00080000
#define RTCF_FAST       0x00200000
#define RTCF_MASQ       0x00400000
#define RTCF_SNAT       0x00800000
#define RTCF_DOREDIRECT 0x01000000
#define RTCF_DIRECTSRC  0x04000000
#define RTCF_DNAT       0x08000000
#define RTCF_BROADCAST  0x10000000
#define RTCF_MULTICAST  0x20000000
#define RTCF_REJECT     0x40000000
#define RTCF_LOCAL      0x80000000

/* Keep this in sync with /usr/src/linux/include/linux/ipv6_route.h */
#ifndef RTF_DEFAULT
#define RTF_DEFAULT     0x00010000      /* default - learned via ND     */
#endif
#define RTF_ALLONLINK   0x00020000      /* fallback, no routers on link */
#ifndef RTF_ADDRCONF
#define RTF_ADDRCONF    0x00040000      /* addrconf route - RA          */
#endif
#define RTF_NONEXTHOP   0x00200000      /* route with no nexthop        */
#define RTF_EXPIRES     0x00400000
#define RTF_CACHE       0x01000000      /* cache entry                  */
#define RTF_FLOW        0x02000000      /* flow significant route       */
#define RTF_POLICY      0x04000000      /* policy route                 */
#define RTF_LOCAL       0x80000000

/* Keep this in sync with /usr/src/linux/include/linux/route.h */
#define RTF_UP          0x0001          /* route usable                 */
#define RTF_GATEWAY     0x0002          /* destination is a gateway     */
#define RTF_HOST        0x0004          /* host entry (net otherwise)   */
#define RTF_REINSTATE   0x0008          /* reinstate route after tmout  */
#define RTF_DYNAMIC     0x0010          /* created dyn. (by redirect)   */
#define RTF_MODIFIED    0x0020          /* modified dyn. (by redirect)  */
#define RTF_MTU         0x0040          /* specific MTU for this route  */
#ifndef RTF_MSS
#define RTF_MSS         RTF_MTU         /* Compatibility :-(            */
#endif
#define RTF_WINDOW      0x0080          /* per route window clamping    */
#define RTF_IRTT        0x0100          /* Initial round trip time      */
#define RTF_REJECT      0x0200          /* Reject route                 */

/* this is a 2.0.36 flag from /usr/src/linux/include/linux/route.h */
#define RTF_NOTCACHED   0x0400          /* this route isn't cached        */

#ifdef HAVE_AFECONET
#ifndef AF_ECONET
#define AF_ECONET       19      /* Acorn Econet */
#endif
#endif

/* End of lib/support.h */


--- NEW FILE: x25_sr.c ---
/*
 * lib/x25_sr.c	This file contains an implementation of the "X.25"
 *		route change support functions.
 *
 * Version:	@(#)x25_sr.c	1.00	08/15/98
 *
 * Author:	Stephane Fillod, <sfillod at charybde.gyptis.frmug.org>
 *		based on inet_sr.c
 *
 *		This program 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 of the License, or  (at
 *		your option) any later version.
 */
#include "config.h"

#if HAVE_AFX25
#include <asm/types.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/x25.h>
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <resolv.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include "version.h"
#include "net-support.h"
#include "pathnames.h"
#define  EXTERN
#if 0
#include "net-locale.h"
#endif
#include "intl.h"

#include "net-features.h"

extern     struct aftype   x25_aftype;

static int skfd = -1;


static int usage(void)
{
  fprintf(stderr,"Usage: x25_route [-v] del Target[/mask] [dev] If\n");
  fprintf(stderr,"       x25_route [-v] add Target[/mask] [dev] If\n");
  return(E_USAGE);
}


static int X25_setroute(int action, int options, char **args)
{
  struct x25_route_struct rt;
  struct sockaddr_x25 sx25;
  char target[128];
  signed int sigdigits;

  if (*args == NULL)
	return(usage());

  strcpy(target, *args++);

  /* Clean out the x25_route_struct structure. */
  memset((char *) &rt, 0, sizeof(struct x25_route_struct));


  if ((sigdigits = x25_aftype.input(0, target, (struct sockaddr *)&sx25)) < 0) {
	x25_aftype.herror(target);
	return (1);
  }
  rt.sigdigits=sigdigits;

  /* x25_route_struct.address isn't type struct sockaddr_x25, Why? */
  memcpy(&rt.address, &sx25.sx25_addr, sizeof(x25_address));

  while (*args) {
	if (!strcmp(*args,"device") || !strcmp(*args,"dev")) {
		args++;
		if (!*args)
			return(usage());
	} else
		if (args[1])
			return(usage());
	if (rt.device[0])
		return(usage());
	strcpy(rt.device, *args);
	args++;
  }
  if (rt.device[0]=='\0')
	return(usage());

  /* sanity checks.. */
	if (rt.sigdigits > 15) {
		fprintf(stderr, _("route: bogus netmask %d\n"), rt.sigdigits);
		return(E_OPTERR);
	}

	if (rt.sigdigits > strlen(rt.address.x25_addr)) {
		fprintf(stderr, _("route: netmask doesn't match route address\n"));
		return(E_OPTERR);
	}

  /* Create a socket to the X25 kernel. */
  if ((skfd = socket(AF_X25, SOCK_SEQPACKET, 0)) < 0) {
	perror("socket");
	return(E_SOCK);
  }
  
  /* Tell the kernel to accept this route. */
  if (action==RTACTION_DEL) {
	if (ioctl(skfd, SIOCDELRT, &rt) < 0) {
		perror("SIOCDELRT");
		close(skfd);
		return(E_SOCK);
	}
  } else {
	if (ioctl(skfd, SIOCADDRT, &rt) < 0) {
		perror("SIOCADDRT");
		close(skfd);
		return(E_SOCK);
	}
  }

  /* Close the socket. */
  (void) close(skfd);
  return(0);
}

int X25_rinput(int action, int options, char **args)
{
  if (action == RTACTION_FLUSH) {
  	fprintf(stderr,"Flushing `x25' routing table not supported\n");
  	return(usage());
  }	
  if (options & FLAG_CACHE) {
  	fprintf(stderr,"Modifying `x25' routing cache not supported\n");
  	return(usage());
  }	
  if ((*args == NULL) || (action == RTACTION_HELP))
	return(usage());
  
  return(X25_setroute(action, options, args));
}
#endif	/* HAVE_AFX25 */

--- NEW FILE: ether.c ---
/*
 * lib/ether.c        This file contains an implementation of the "Ethernet"
 *              support functions.
 *
 * Version:     $Id: ether.c,v 1.2 2006-08-31 09:32:17 dslinux_amadeus Exp $
 *
 * Author:      Fred N. van Kempen, <waltje at uwalt.nl.mugnet.org>
 *              Copyright 1993 MicroWalt Corporation
 *
 *              This program 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 of the License, or  (at
 *              your option) any later version.
 */
#include "config.h"

#if HAVE_HWETHER
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if_arp.h>
#include <linux/if_ether.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"
#include "util.h"

extern struct hwtype ether_hwtype;


/* Display an Ethernet address in readable format. */
static char *pr_ether(unsigned char *ptr)
{
    static char buff[64];

    snprintf(buff, sizeof(buff), "%02X:%02X:%02X:%02X:%02X:%02X",
	     (ptr[0] & 0377), (ptr[1] & 0377), (ptr[2] & 0377),
	     (ptr[3] & 0377), (ptr[4] & 0377), (ptr[5] & 0377)
	);
    return (buff);
}


/* Input an Ethernet address and convert to binary. */
static int in_ether(char *bufp, struct sockaddr *sap)
{
    unsigned char *ptr;
    char c, *orig;
    int i;
    unsigned val;

    sap->sa_family = ether_hwtype.type;
    ptr = sap->sa_data;

    i = 0;
    orig = bufp;
    while ((*bufp != '\0') && (i < ETH_ALEN)) {
	val = 0;
	c = *bufp++;
	if (isdigit(c))
	    val = c - '0';
	else if (c >= 'a' && c <= 'f')
	    val = c - 'a' + 10;
	else if (c >= 'A' && c <= 'F')
	    val = c - 'A' + 10;
	else {
#ifdef DEBUG
	    fprintf(stderr, _("in_ether(%s): invalid ether address!\n"), orig);
#endif
	    errno = EINVAL;
	    return (-1);
	}
	val <<= 4;
	c = *bufp;
	if (isdigit(c))
	    val |= c - '0';
	else if (c >= 'a' && c <= 'f')
	    val |= c - 'a' + 10;
	else if (c >= 'A' && c <= 'F')
	    val |= c - 'A' + 10;
	else if (c == ':' || c == 0)
	    val >>= 4;
	else {
#ifdef DEBUG
	    fprintf(stderr, _("in_ether(%s): invalid ether address!\n"), orig);
#endif
	    errno = EINVAL;
	    return (-1);
	}
	if (c != 0)
	    bufp++;
	*ptr++ = (unsigned char) (val & 0377);
	i++;

	/* We might get a semicolon here - not required. */
	if (*bufp == ':') {
	    if (i == ETH_ALEN) {
#ifdef DEBUG
		fprintf(stderr, _("in_ether(%s): trailing : ignored!\n"),
			orig)
#endif
		    ;		/* nothing */
	    }
	    bufp++;
	}
    }

    /* That's it.  Any trailing junk? */
    if ((i == ETH_ALEN) && (*bufp != '\0')) {
#ifdef DEBUG
	fprintf(stderr, _("in_ether(%s): trailing junk!\n"), orig);
	errno = EINVAL;
	return (-1);
#endif
    }
#ifdef DEBUG
    fprintf(stderr, "in_ether(%s): %s\n", orig, pr_ether(sap->sa_data));
#endif

    return (0);
}


struct hwtype ether_hwtype =
{
    "ether", NULL, /*"10Mbps Ethernet", */ ARPHRD_ETHER, ETH_ALEN,
    pr_ether, in_ether, NULL
};


#endif				/* HAVE_HWETHER */

--- NEW FILE: inet_gr.c ---
/*
   $Id: inet_gr.c,v 1.2 2006-08-31 09:32:18 dslinux_amadeus Exp $

   Modifications:
   1998-07-01 - Arnaldo Carvalho de Melo - GNU gettext instead of catgets
   1999-01-01 - Bernd Eckenfels          - fixed the routing cache printouts
   1999-10-07 - Kurt Garloff <garloff at suse.de> - do host (instead of network) name
						lookup for gws and hosts
 */

#include "config.h"

#if HAVE_AFINET
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
/* #include <net/route.h> realy broken */
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <resolv.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include "version.h"
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"
#include "net-features.h"
#include "proc.h"
extern struct aftype inet_aftype;

extern char *INET_sprintmask(struct sockaddr *sap, int numeric, 
			     unsigned int netmask);

int rprint_fib(int ext, int numeric)
{
    char buff[1024], iface[16], flags[64];
    char gate_addr[128], net_addr[128];
    char mask_addr[128];
    int num, iflags, metric, refcnt, use, mss, window, irtt;
    FILE *fp = fopen(_PATH_PROCNET_ROUTE, "r");
    char *fmt;

    if (!fp) {
        perror(_PATH_PROCNET_ROUTE);
        printf(_("INET (IPv4) not configured in this system.\n"));
	return 1;
    }
    printf(_("Kernel IP routing table\n"));

    if (ext == 1)
	printf(_("Destination     Gateway         Genmask         "
		 "Flags Metric Ref    Use Iface\n"));
    if (ext == 2)
	printf(_("Destination     Gateway         Genmask         "
		 "Flags   MSS Window  irtt Iface\n"));
    if (ext >= 3)
	printf(_("Destination     Gateway         Genmask         "
		 "Flags Metric Ref    Use Iface    "
		 "MSS   Window irtt\n"));

    irtt = 0;
    window = 0;
    mss = 0;

    fmt = proc_gen_fmt(_PATH_PROCNET_ROUTE, 0, fp,
		       "Iface", "%16s",
		       "Destination", "%128s",
		       "Gateway", "%128s",
		       "Flags", "%X",
		       "RefCnt", "%d",
		       "Use", "%d",
		       "Metric", "%d",
		       "Mask", "%128s",
		       "MTU", "%d",
		       "Window", "%d",
		       "IRTT", "%d",
		       NULL);
    /* "%16s %128s %128s %X %d %d %d %128s %d %d %d\n" */

    if (!fmt)
	return 1;

    while (fgets(buff, 1023, fp)) {
        struct sockaddr snet_target, snet_gateway, snet_mask;
	struct sockaddr_in *sin_netmask;

	num = sscanf(buff, fmt,
		     iface, net_addr, gate_addr,
		     &iflags, &refcnt, &use, &metric, mask_addr,
		     &mss, &window, &irtt);
	if (num < 10 || !(iflags & RTF_UP))
	    continue;

	/* Fetch and resolve the target address. */
	(void) inet_aftype.input(1, net_addr, &snet_target);

	/* Fetch and resolve the gateway address. */
	(void) inet_aftype.input(1, gate_addr, &snet_gateway);

	/* Fetch and resolve the genmask. */
	(void) inet_aftype.input(1, mask_addr, &snet_mask);
	
	sin_netmask = (struct sockaddr_in *)&snet_mask;
	strcpy(net_addr, INET_sprintmask(&snet_target, 
					 (numeric | 0x8000 | (iflags & RTF_HOST? 0x4000: 0)),
					 sin_netmask->sin_addr.s_addr));
	net_addr[15] = '\0';

	strcpy(gate_addr, inet_aftype.sprint(&snet_gateway, numeric | 0x4000));
	gate_addr[15] = '\0';

	strcpy(mask_addr, inet_aftype.sprint(&snet_mask, 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 HAVE_RTF_REJECT
	if (iflags & RTF_REJECT)
	    strcpy(flags, "!");
#endif
	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");
	if (iflags & RTF_DEFAULT)
	    strcat(flags, "d");
	if (iflags & RTF_ALLONLINK)
	    strcat(flags, "a");
	if (iflags & RTF_ADDRCONF)
	    strcat(flags, "c");
	if (iflags & RTF_NONEXTHOP)
	    strcat(flags, "o");
	if (iflags & RTF_EXPIRES)
	    strcat(flags, "e");
	if (iflags & RTF_CACHE)
	    strcat(flags, "c");
	if (iflags & RTF_FLOW)
	    strcat(flags, "f");
	if (iflags & RTF_POLICY)
	    strcat(flags, "p");
	if (iflags & RTF_LOCAL)
	    strcat(flags, "l");
	if (iflags & RTF_MTU)
	    strcat(flags, "u");
	if (iflags & RTF_WINDOW)
	    strcat(flags, "w");
	if (iflags & RTF_IRTT)
	    strcat(flags, "i");
	if (iflags & RTF_NOTCACHED) /* 2.0.36 */
	    strcat(flags, "n");

	/* Print the info. */
	if (ext == 1) {
#if HAVE_RTF_REJECT
	    if (iflags & RTF_REJECT)
		printf("%-15s -               %-15s %-5s %-6d -  %7d -\n",
		       net_addr, mask_addr, flags, metric, use);
	    else
#endif
		printf("%-15s %-15s %-15s %-5s %-6d %-2d %7d %s\n",
		       net_addr, gate_addr, mask_addr, flags,
		       metric, refcnt, use, iface);
	}
	if (ext == 2) {
#if HAVE_RTF_REJECT
	    if (iflags & RTF_REJECT)
		printf("%-15s -               %-15s %-5s     - -          - -\n",
		       net_addr, mask_addr, flags);
	    else
#endif
		printf("%-15s %-15s %-15s %-5s %5d %-5d %6d %s\n",
		       net_addr, gate_addr, mask_addr, flags,
		       mss, window, irtt, iface);
	}
	if (ext >= 3) {
#if HAVE_RTF_REJECT
	    if (iflags & RTF_REJECT)
		printf("%-15s -               %-15s %-5s %-6d -  %7d -        -     -      -\n",
		       net_addr, mask_addr, flags, metric, use);
	    else
#endif
		printf("%-15s %-15s %-15s %-5s %-6d %-3d %6d %-6.6s   %-5d %-6d %d\n",
		       net_addr, gate_addr, mask_addr, flags,
		       metric, refcnt, use, iface, mss, window, irtt);
	}
    }

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

int rprint_cache(int ext, int numeric)
{
    char buff[1024], iface[16], flags[64];
    char gate_addr[128], dest_addr[128], specdst[128];
    char src_addr[128];
    struct sockaddr snet;
    unsigned int iflags;
    int num, format, metric, refcnt, use, mss, window, irtt, hh, hhref, hhuptod, arp, tos;
    char *fmt = NULL;

    FILE *fp = fopen(_PATH_PROCNET_RTCACHE, "r");

    if (!fp) {
        perror(_PATH_PROCNET_RTCACHE);
        printf(_("INET (IPv4) not configured in this system.\n"));
	return 1;
    }

   /* Okay, first thing we need to know is the format of the rt_cache. 
    * I am aware of two possible layouts:
    * 2.2.0
    * "Iface\tDestination\tGateway \tFlags\t\tRefCnt\tUse\tMetric\tSource\t\tMTU\tWindow\tIRTT\tTOS\tHHRef\tHHUptod\tSpecDst"
    * "%s\t%08lX\t%08lX\t%8X\t%d\t%u\t%d\t%08lX\t%d\t%u\t%u\t%02X\t%d\t%1d\t%08X" 
    *
    * 2.0.36
    * "Iface\tDestination\tGateway \tFlags\tRefCnt\tUse\tMetric\tSource\t\tMTU\tWindow\tIRTT\tHH\tARP"
    * "%s\t%08lX\t%08lX\t%02X\t%d\t%u\t%d\t%08lX\t%d\t%lu\t%u\t%d\t%1d"
    */
    
    format = proc_guess_fmt(_PATH_PROCNET_RTCACHE, fp, "IRTT",1,"TOS",2,"HHRef",4,"HHUptod",8,"SpecDst",16,"HH",32,"ARP",64,NULL);

    printf(_("Kernel IP routing cache\n"));

    switch(format) {
    	case -1: /* I/O Error */
	  perror(_PATH_PROCNET_RTCACHE);
	  exit(-1);
    	  break;
    	case 63: /* 2.2.0 Format */
	  format = 2;
    	  break;
    	case 97: /* 2.0.36 Format */
    	  format = 1;
    	  break;
    	default:
    	  printf("ERROR: proc_guess_fmt(%s,... returned: %d\n",_PATH_PROCNET_RTCACHE, format);
	  break;
    }
    
    rewind(fp);

    if (ext == 1)
      printf(_("Source          Destination     Gateway         "
               "Flags Metric Ref    Use Iface\n"));
    if (ext == 2)
      printf(_("Source          Destination     Gateway         "
               "Flags   MSS Window  irtt Iface\n"));

    if (format == 1) {
      if (ext >= 3)
	printf(_("Source          Destination     Gateway         "
		 "Flags Metric Ref    Use Iface    "
		 "MSS   Window irtt  HH  Arp\n"));

      fmt = proc_gen_fmt(_PATH_PROCNET_RTCACHE, 0, fp,
		       "Iface", "%16s",
		       "Destination", "%128s",
		       "Gateway", "%128s",
		       "Flags", "%X",
		       "RefCnt", "%d",
		       "Use", "%d",
		       "Metric", "%d",
		       "Source", "%128s",
		       "MTU", "%d",
		       "Window", "%d",
		       "IRTT", "%d",
		       "HH", "%d",
		       "ARP", "%d",
		       NULL);
      /* "%16s %128s %128s %X %d %d %d %128s %d %d %d %d %d\n" */
    }

    if (format == 2) {
      if (ext >= 3)
	printf(_("Source          Destination     Gateway         "
		 "Flags Metric Ref    Use Iface    "
		 "MSS   Window irtt  TOS HHRef HHUptod     SpecDst\n"));
        fmt = proc_gen_fmt(_PATH_PROCNET_RTCACHE, 0, fp,
		       "Iface", "%16s",
		       "Destination", "%128s",
		       "Gateway", "%128s",
		       "Flags", "%X",
		       "RefCnt", "%d",
		       "Use", "%d",
		       "Metric", "%d",
		       "Source", "%128s",
		       "MTU", "%d",
		       "Window", "%d",
		       "IRTT", "%d",
		       "TOS", "%d",
		       "HHRef", "%d",
		       "HHUptod", "%d",
		       "SpecDst", "%128s",
		       NULL);
      /* "%16s %128s %128s %X %d %d %d %128s %d %d %d %d %d %128s\n" */
    }


    irtt = 0;
    window = 0;
    mss = 0;
    hh = 0; hhref = 0; hhuptod = 0;
    arp = 0; tos = 0;
    while (fgets(buff, 1023, fp)) {
        if (format == 1) {
  	  num = sscanf(buff, fmt,
		     iface, dest_addr, gate_addr,
		     &iflags, &refcnt, &use, &metric, src_addr,
		     &mss, &window, &irtt, &hh, &arp);
	  if (num < 12)
	    continue;
	}
        if (format == 2) {
  	  num = sscanf(buff, fmt,
		     iface, dest_addr, gate_addr,
		     &iflags, &refcnt, &use, &metric, src_addr,
		     &mss, &window, &irtt, &tos, &hhref, &hhuptod, &specdst);
	  if (num < 12)
	    continue;
	}
	

	/* Fetch and resolve the target address. */
	(void) inet_aftype.input(1, dest_addr, &snet);
	strcpy(dest_addr, inet_aftype.sprint(&snet, numeric));
	dest_addr[15] = '\0';

	/* Fetch and resolve the gateway address. */
	(void) inet_aftype.input(1, gate_addr, &snet);
	strcpy(gate_addr, inet_aftype.sprint(&snet, numeric));
	gate_addr[15] = '\0';

	/* Fetch and resolve the source. */
	(void) inet_aftype.input(1, src_addr, &snet);
	strcpy(src_addr, inet_aftype.sprint(&snet, numeric));
	src_addr[15] = '\0';

	/* Fetch and resolve the SpecDst addrerss. */
	(void) inet_aftype.input(1, specdst, &snet);
	strcpy(specdst, inet_aftype.sprint(&snet, numeric));
	specdst[15] = '\0';

	/* Decode the flags. */
	flags[0] = '\0';
if (format == 1) {
	if (iflags & RTF_UP)
	    strcat(flags, "U");
	if (iflags & RTF_HOST)
	    strcat(flags, "H");
}
	if (iflags & RTF_GATEWAY)
	    strcat(flags, "G");
#if HAVE_RTF_REJECT
	if (iflags & RTF_REJECT)
	    strcpy(flags, "!");
#endif
	if (iflags & RTF_REINSTATE)
	    strcat(flags, "R");
	if (iflags & RTF_DYNAMIC)
	    strcat(flags, "D");
	if (iflags & RTF_MODIFIED)
	    strcat(flags, "M");

/* possible collision with 2.0 flags U and H */
if (format == 2) {
	if (iflags & RTCF_DEAD)
	    strcat(flags, "-");
	if (iflags & RTCF_ONLINK)
	    strcat(flags, "o");
}
	if (iflags & RTCF_NOTIFY)
	    strcat(flags, "n");
	if (iflags & RTCF_DIRECTDST)
	    strcat(flags, "d");
	if (iflags & RTCF_TPROXY)
	    strcat(flags, "t");
	if (iflags & RTCF_FAST)
	    strcat(flags, "f");
	if (iflags & RTCF_MASQ)
	    strcat(flags, "q");
	if (iflags & RTCF_SNAT)
	    strcat(flags, "Ns");
	if (iflags & RTCF_DOREDIRECT)
	    strcat(flags, "r");
	if (iflags & RTCF_DIRECTSRC)
	    strcat(flags, "i");
	if (iflags & RTCF_DNAT)
	    strcat(flags, "Nd");
	if (iflags & RTCF_BROADCAST)
	    strcat(flags, "b");
	if (iflags & RTCF_MULTICAST)
	    strcat(flags, "m");
	if (iflags & RTCF_REJECT)
	    strcat(flags, "#");
	if (iflags & RTCF_LOCAL)
	    strcat(flags, "l");
	/* Print the info. */
	if (ext == 1) {
		printf("%-15s %-15s %-15s %-5s %-6d %-2d %7d %s\n",
		       src_addr, dest_addr, gate_addr, flags,
		       metric, refcnt, use, iface);
	}
	if (ext == 2) {
		printf("%-15s %-15s %-15s %-5s %5d %-5d %6d %s\n",
		       src_addr, dest_addr, gate_addr, flags,
		       mss, window, irtt, iface);
	}
	if (format == 1) {
	  if (ext >= 3) {
		printf("%-15s %-15s %-15s %-5s %-6d %-3d %6d %-6.6s   %-5d %-6d %-5d %-3d %d\n",
		       src_addr, dest_addr, gate_addr, flags,
		 metric, refcnt, use, iface, mss, window, irtt, hh, arp);
	  }
	}
	if (format == 2) {
	  if (ext >= 3) {
		printf("%-15s %-15s %-15s %-5s %-6d %-3d %6d %-6.6s   %-5d %-6d %-5d %-3d %-3d   %-3d %15s\n",
		       src_addr, dest_addr, gate_addr, flags,
		 metric, refcnt, use, iface, mss, window, irtt, tos, hhref, hhuptod, specdst);
	  }
	}
    }

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

int INET_rprint(int options)
{
    int ext = options & FLAG_EXT;
    int numeric = options & (FLAG_NUM_HOST | FLAG_SYM);
    int rc = E_INTERN;

    if (options & FLAG_FIB)
	if ((rc = rprint_fib(ext, numeric)))
	    return (rc);
    if (options & FLAG_CACHE)
	rc = rprint_cache(ext, numeric);

    return (rc);
}

#endif				/* HAVE_AFINET */

--- NEW FILE: netrom.c ---
/*
 * lib/netrom.c       This file contains an implementation of the "NET/ROM"
 *              support functions for the NET-2 base distribution.
 *
 * Version:     $Id: netrom.c,v 1.2 2006-08-31 09:32:18 dslinux_amadeus Exp $
 *
 * NOTE:        I will redo this module as soon as I got the libax25.a
 *              library sorted out.  This library contains some useful
 *              and often used address conversion functions, database
 *              lookup stuff, and more of the like.
 *
 * Author:      Fred N. van Kempen, <waltje at uwalt.nl.mugnet.org>
 *              Copyright 1993 MicroWalt Corporation
 * 
 * Changes:
 * 980701 {1.21} Arnaldo Carvalho de Melo - GNU gettext instead of catgets,
 *                                          strncpy instead of strcpy for
 *                                          i18n strings
 *
 *              This program 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 of the License, or  (at
 *              your option) any later version.
 */
#include "config.h"

#if HAVE_AFNETROM || HAVE_HWNETROM
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if_arp.h>
#if ((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1)) && !defined(__UCLIBC__)
#include <netax25/ax25.h>
#else
#include <linux/ax25.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"
#include "util.h"

static char netrom_errmsg[128];

extern struct aftype netrom_aftype;

static char *NETROM_print(unsigned char *ptr)
{
    static char buff[8];
    int i;

    for (i = 0; i < 6; i++) {
	buff[i] = ((ptr[i] & 0377) >> 1);
	if (buff[i] == ' ')
	    buff[i] = '\0';
    }
    buff[6] = '\0';
    i = ((ptr[6] & 0x1E) >> 1);
    if (i != 0)
	sprintf(&buff[strlen(buff)], "-%d", i);
    return (buff);
}


/* Display an AX.25 socket address. */
static char *NETROM_sprint(struct sockaddr *sap, int numeric)
{
    char buf[64];
    if (sap->sa_family == 0xFFFF || sap->sa_family == 0)
	return safe_strncpy(buf, _("[NONE SET]"), sizeof(buf));
    return (NETROM_print(((struct sockaddr_ax25 *) sap)->sax25_call.ax25_call));
}


static int NETROM_input(int type, char *bufp, struct sockaddr *sap)
{
    unsigned char *ptr;
    char *orig, c;
    unsigned int i;

    sap->sa_family = netrom_aftype.af;
    ptr = ((struct sockaddr_ax25 *) sap)->sax25_call.ax25_call;

    /* First, scan and convert the basic callsign. */
    orig = bufp;
    i = 0;
    while ((*bufp != '\0') && (*bufp != '-') && (i < 6)) {
	c = *bufp++;
	if (islower(c))
	    c = toupper(c);
	if (!(isupper(c) || isdigit(c))) {
	    safe_strncpy(netrom_errmsg, _("Invalid callsign"), sizeof(netrom_errmsg));
#ifdef DEBUG
	    fprintf(stderr, "netrom_input(%s): %s !\n", netrom_errmsg, orig);
#endif
	    errno = EINVAL;
	    return (-1);
	}
	*ptr++ = (unsigned char) ((c << 1) & 0xFE);
	i++;
    }

    /* Callsign too long? */
    if ((i == 6) && (*bufp != '-') && (*bufp != '\0')) {
	safe_strncpy(netrom_errmsg, _("Callsign too long"), sizeof(netrom_errmsg));
#ifdef DEBUG
	fprintf(stderr, "netrom_input(%s): %s !\n", netrom_errmsg, orig);
#endif
	errno = E2BIG;
	return (-1);
    }
    /* Nope, fill out the address bytes with blanks. */
    while (i++ < sizeof(ax25_address) - 1) {
	*ptr++ = (unsigned char) ((' ' << 1) & 0xFE);
    }

    /* See if we need to add an SSID field. */
    if (*bufp == '-') {
	i = atoi(++bufp);
	*ptr = (unsigned char) ((i << 1) & 0xFE);
    } else {
	*ptr = (unsigned char) '\0';
    }

    /* All done. */
#ifdef DEBUG
    fprintf(stderr, "netrom_input(%s): ", orig);
    for (i = 0; i < sizeof(ax25_address); i++)
	fprintf(stderr, "%02X ", sap->sa_data[i] & 0377);
    fprintf(stderr, "\n");
#endif

    return (0);
}


/* Display an error message. */
static void NETROM_herror(char *text)
{
    if (text == NULL)
	fprintf(stderr, "%s\n", netrom_errmsg);
    else
	fprintf(stderr, "%s: %s\n", text, netrom_errmsg);
}


static int NETROM_hinput(char *bufp, struct sockaddr *sap)
{
    if (NETROM_input(0, bufp, sap) < 0)
	return (-1);
    sap->sa_family = ARPHRD_NETROM;
    return (0);
}

#if 0
/* Set the line discipline of a terminal line. */
static int KISS_set_disc(int fd, int disc)
{
    if (ioctl(fd, TIOCSETD, &disc) < 0) {
	fprintf(stderr, "KISS_set_disc(%d): %s\n", disc, strerror(errno));
	return (-errno);
    }
    return (0);
}


/* Start the KISS encapsulation on the file descriptor. */
static int KISS_init(int fd)
{
    if (KISS_set_disc(fd, N_SLIP) < 0)
	return (-1);
    if (ioctl(fd, SIOCSIFENCAP, 4) < 0)
	return (-1);
    return (0);
}
#endif

struct hwtype netrom_hwtype =
{
    "netrom", NULL, /* "AMPR NET/ROM", */ ARPHRD_NETROM, 7,
    NETROM_print, NETROM_hinput, NULL, 0
};

struct aftype netrom_aftype =
{
    "netrom", NULL, /* "AMPR NET/ROM", */ AF_NETROM, 7,
    NETROM_print, NETROM_sprint, NETROM_input, NETROM_herror,
    NULL, NULL, NULL,
    -1,
    "/proc/net/nr"
};

#endif				/* HAVE_AFNETROM */

--- NEW FILE: tr.c ---
/*
 * lib/tr.c   This file contains an implementation of the "Tokenring"
 *              support functions.
 *
 * Version:     $Id: tr.c,v 1.2 2006-08-31 09:32:19 dslinux_amadeus Exp $
 *
 * Author:      Fred N. van Kempen, <waltje at uwalt.nl.mugnet.org>
 *              Copyright 1993 MicroWalt Corporation
 *
 *              This program 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 of the License, or  (at
 *              your option) any later version.
 */
#include "config.h"

#if HAVE_HWTR
#include <asm/types.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if_arp.h>
#include <linux/if_tr.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"

extern struct hwtype tr_hwtype;

static char *pr_tr(unsigned char *ptr)
{
    static char buff[64];

    snprintf(buff, sizeof(buff), "%02X:%02X:%02X:%02X:%02X:%02X",
	     (ptr[0] & 0377), (ptr[1] & 0377), (ptr[2] & 0377),
	     (ptr[3] & 0377), (ptr[4] & 0377), (ptr[5] & 0377)
	);
    return (buff);
}


static int in_tr(char *bufp, struct sockaddr *sap)
{
    unsigned char *ptr;
    char c, *orig;
    int i, val;

    sap->sa_family = tr_hwtype.type;
    ptr = sap->sa_data;

    i = 0;
    orig = bufp;
    while ((*bufp != '\0') && (i < TR_ALEN)) {
	val = 0;
	c = *bufp++;
	if (isdigit(c))
	    val = c - '0';
	else if (c >= 'a' && c <= 'f')
	    val = c - 'a' + 10;
	else if (c >= 'A' && c <= 'F')
	    val = c - 'A' + 10;
	else {
#ifdef DEBUG
	    fprintf(stderr, _("in_tr(%s): invalid token ring address!\n"), orig);
#endif
	    errno = EINVAL;
	    return (-1);
	}
	val <<= 4;
	c = *bufp++;
	if (isdigit(c))
	    val |= c - '0';
	else if (c >= 'a' && c <= 'f')
	    val |= c - 'a' + 10;
	else if (c >= 'A' && c <= 'F')
	    val |= c - 'A' + 10;
	else {
#ifdef DEBUG
	    fprintf(stderr, _("in_tr(%s): invalid token ring address!\n"), orig);
#endif
	    errno = EINVAL;
	    return (-1);
	}
	*ptr++ = (unsigned char) (val & 0377);
	i++;

	/* We might get a semicolon here - not required. */
	if (*bufp == ':') {
	    if (i == TR_ALEN) {
#ifdef DEBUG
		fprintf(stderr, _("in_tr(%s): trailing : ignored!\n"),
			orig)
#endif
		    ;		/* nothing */
	    }
	    bufp++;
	}
    }

    /* That's it.  Any trailing junk? */
    if ((i == TR_ALEN) && (*bufp != '\0')) {
#ifdef DEBUG
	fprintf(stderr, _("in_tr(%s): trailing junk!\n"), orig);
	errno = EINVAL;
	return (-1);
#endif
    }
#ifdef DEBUG
    fprintf(stderr, "in_tr(%s): %s\n", orig, pr_tr(sap->sa_data));
#endif

    return (0);
}


struct hwtype tr_hwtype =
{
    "tr", NULL /* "16/4 Mbps Token Ring" */, ARPHRD_IEEE802, TR_ALEN,
    pr_tr, in_tr, NULL
};
#ifdef ARPHRD_IEEE802_TR
struct hwtype tr_hwtype1 =
{
    "tr", NULL /* "16/4 Mbps Token Ring" */, ARPHRD_IEEE802_TR, TR_ALEN,
    pr_tr, in_tr, NULL
};
#endif


#endif				/* HAVE_HWTR */

--- NEW FILE: Makefile ---
#
# lib/Makefile	Makefile for the net-lib function collection
#
# NET-LIB	A collection of functions used from the base set of the
#		NET-2 Networking Distribution for the LINUX operating
#		system.  (net-tools, net-drivers)
#
# Author:	Fred N. van Kempen, <waltje at uwalt.nl.mugnet.org>
#		Copyright 1993 MicroWalt Corporation
#
#		This program 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 of the License, or  (at
#		your option) any later version.
#


HWOBJS	 = hw.o loopback.o slip.o ether.o ax25.o ppp.o arcnet.o tr.o tunnel.o frame.o sit.o rose.o ash.o fddi.o hippi.o hdlclapb.o strip.o irda.o ec_hw.o x25.o
AFOBJS	 = unix.o inet.o inet6.o ax25.o ipx.o ddp.o ipx.o netrom.o af.o rose.o econet.o x25.o
AFGROBJS = inet_gr.o inet6_gr.o ipx_gr.o ddp_gr.o netrom_gr.o ax25_gr.o rose_gr.o getroute.o x25_gr.o
AFSROBJS = inet_sr.o inet6_sr.o netrom_sr.o ipx_sr.o setroute.o x25_sr.o
ACTOBJS  = slip_ac.o ppp_ac.o activate.o
VARIA	 = getargs.o masq_info.o proc.o util.o nstrcmp.o interface.o sockets.o

# Default Name
NET_LIB_NAME = net-tools

ifeq ($(HAVE_IP_TOOLS),1)
VARIA	+= util-ank.o
endif

OBJS	= $(sort $(VARIA) $(AFOBJS) $(HWOBJS) \
		$(AFGROBJS) $(AFSROBJS) $(ACTOBJS))


# This can be overwritten by the TOPLEVEL Makefile
TOPDIR=..
CFLAGS += -I$(TOPDIR) -idirafter $(TOPDIR)/include # -fPIC
SONAME=libnet-tools.so.0

.SUFFIXES: .a .so

all:	lib$(NET_LIB_NAME).a # lib$(NET_LIB_NAME).so

lib$(NET_LIB_NAME).a:	Makefile $(TOPDIR)/config.h $(OBJS)
			@echo Building $@
			@rm -f $@
			@$(AR) rcs $@ $(OBJS)

.a.so:;
	$(CC) -o $@ -shared -Wl,--whole-archive -Wl,--soname -Wl,$(SONAME) -nostdlib -nostartfiles $<

clean:
		rm -f *.o *~ *.orig lib$(NET_LIB_NAME).a lib$(NET_LIB_NAME).so

clobber:	clean

# End of lib/Makefile.

--- NEW FILE: ddp_gr.c ---
#include "config.h"

#if HAVE_AFATALK
#include <asm/types.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/atalk.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"

int DDP_rprint(int options)
{
    fprintf(stderr, _("Routing table for `ddp' not yet supported.\n"));
    return (1);
}
#endif

--- NEW FILE: slip_ac.c ---
/*
 * lib/slip_ac.c      This file contains the activation for the
 *                      SLIP line disciplines, called from activate_ld().
 *
 * Version:     $Id: slip_ac.c,v 1.2 2006-08-31 09:32:19 dslinux_amadeus Exp $
 *
 * Author:      Bernd 'eckes' Eckenfels
 *              Fred N. van Kempen, <waltje at uwalt.nl.mugnet.org>
 *              Copyright 1993 MicroWalt Corporation
 *
 *              Modified by Alan Cox, May 94 to cover NET-3
 *
 *              This program 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 of the License, or  (at
 *              your option) any later version.
 */
#include "config.h"

#if HAVE_HWSLIP

#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if_arp.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include "net-support.h"
#include "pathnames.h"


/* Set the line discipline of a terminal line. */
static int SLIP_set_disc(int fd, int disc)
{
    if (ioctl(fd, TIOCSETD, &disc) < 0) {
	fprintf(stderr, "SLIP_set_disc(%d): %s\n", disc, strerror(errno));
	return (-errno);
    }
    return (0);
}


/* Set the encapsulation type of a terminal line. */
static int SLIP_set_encap(int fd, int encap)
{
    if (ioctl(fd, SIOCSIFENCAP, &encap) < 0) {
	fprintf(stderr, "SLIP_set_encap(%d): %s\n", encap, strerror(errno));
	return (-errno);
    }
    return (0);
}


/* Start the SLIP encapsulation on the file descriptor. */
int SLIP_activate(int fd)
{
    if (SLIP_set_disc(fd, N_SLIP) < 0)
	return (-1);
    if (SLIP_set_encap(fd, 0) < 0)
	return (-1);
    return (0);
}


/* Start the VJ-SLIP encapsulation on the file descriptor. */
int CSLIP_activate(int fd)
{
    if (SLIP_set_disc(fd, N_SLIP) < 0)
	return (-1);
    if (SLIP_set_encap(fd, 1) < 0)
	return (-1);
    return (0);
}


/* Start the SLIP-6 encapsulation on the file descriptor. */
int SLIP6_activate(int fd)
{
    if (SLIP_set_disc(fd, N_SLIP) < 0)
	return (-1);
    if (SLIP_set_encap(fd, 2) < 0)
	return (-1);
    return (0);
}


/* Start the VJ-SLIP-6 encapsulation on the file descriptor. */
int CSLIP6_activate(int fd)
{
    if (SLIP_set_disc(fd, N_SLIP) < 0)
	return (-1);
    if (SLIP_set_encap(fd, 3) < 0)
	return (-1);
    return (0);
}


/* Start adaptive encapsulation on the file descriptor. */
int ADAPTIVE_activate(int fd)
{
    if (SLIP_set_disc(fd, N_SLIP) < 0)
	return (-1);
    if (SLIP_set_encap(fd, 8) < 0)
	return (-1);
    return (0);
}
#endif				/* HAVE_HWSLIP */

--- NEW FILE: util.c ---
/* Copyright 1998 by Andi Kleen. Subject to the GPL. */ 
/* $Id: util.c,v 1.2 2006-08-31 09:32:19 dslinux_amadeus Exp $ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/utsname.h>

#include "util.h"


static void oom(void)
{
    fprintf(stderr, "out of virtual memory\n");
    exit(2);
}

void *xmalloc(size_t sz)
{
    void *p = calloc(sz, 1);
    if (!p)
	oom();
    return p;
}

void *xrealloc(void *oldp, size_t sz)
{
    void *p = realloc(oldp, sz);
    if (!p)
	oom();
    return p;
}

int kernel_version(void)
{
    struct utsname uts;
    int major, minor, patch;

    if (uname(&uts) < 0)
	return -1;
    if (sscanf(uts.release, "%d.%d.%d", &major, &minor, &patch) != 3)
	return -1;
    return KRELEASE(major, minor, patch);
}


/* Like strncpy but make sure the resulting string is always 0 terminated. */  
char *safe_strncpy(char *dst, const char *src, size_t size)
{   
    dst[size-1] = '\0';
    return strncpy(dst,src,size-1);   
}

--- NEW FILE: getroute.c ---
/*
 * lib/getroute.c     This file contains a small interface function to
 *                      use the AF specific print routine for the routing
 *                      table.
 *
 * NET-LIB      A collection of functions used from the base set of the
 *              NET-3 Networking Distribution for the LINUX operating
 *              system. (net-tools, net-drivers)
 *
 * Version:     $Id: getroute.c,v 1.2 2006-08-31 09:32:18 dslinux_amadeus Exp $
 *
 * Author:      Bernd 'eckes' Eckenfels <net-tools at lina.inka.de>
 *              Copyright 1999 Bernd Eckenfels, Germany
 *
 * Modifications:
 *
 *951020 {0.10} Bernd Eckenfels:        creation
 *960202 {0.90} Bernd Eckenfels:        rewrite to use getaftype.
 *960204 {0.91} Bernd Eckenfels:        takes constant list of AFs
 *960206 {1.01} Bernd Eckenfels:        route_init will enable routing
 *                                      support in the AF handlers
 *960221 {1.02} Bernd Eckenfels:        renamed from route_info to getroute.c
 *960413 {1.03} Bernd Eckenfels:        new RTACTION support
 *980701 {1.04} Arnaldo C. Melo:        GNU gettext instead of catgets
 *
 *              This program 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 of the License, or  (at
 *              your option) any later version.
 */
#include <stdio.h>
#include <string.h>
#include "net-support.h"
#include "pathnames.h"
#include "version.h"
#include "config.h"
#include "intl.h"
#include "util.h"

extern struct aftype unspec_aftype;
extern struct aftype unix_aftype;
extern struct aftype inet_aftype;
extern struct aftype inet6_aftype;
extern struct aftype ax25_aftype;
extern struct aftype netrom_aftype;
extern struct aftype ipx_aftype;
extern struct aftype ddp_aftype;
extern struct aftype x25_aftype;

void getroute_init(void)
{
#if HAVE_AFINET
    inet_aftype.rprint = INET_rprint;
#endif
#if HAVE_AFINET6
    inet6_aftype.rprint = INET6_rprint;
#endif
#if HAVE_AFNETROM
    netrom_aftype.rprint = NETROM_rprint;
#endif
#if HAVE_AFAX25
    ax25_aftype.rprint = AX25_rprint;
#endif
#if HAVE_AFIPX
    ipx_aftype.rprint = IPX_rprint;
#endif
#if HAVE_AFATALK
    ddp_aftype.rprint = DDP_rprint;
#endif
#if HAVE_AFX25
    x25_aftype.rprint = X25_rprint;
#endif
}

int route_info(const char *afname, int options)
{
    struct aftype *ap;
    char *tmp1, *tmp2;
    int found = E_NOTFOUND, rc;
    char buf[256];

    safe_strncpy(buf, afname, sizeof(buf));

    tmp1 = buf;

    while (tmp1) {

	ap = NULL;

	if ((tmp2 = index(tmp1, ',')))
	    *tmp2++ = '\0';

	if (!tmp1[0]) {
	    tmp1 = tmp2;
	    continue;
	}
	ap = get_aftype(tmp1);

	if (!ap) {
	    fprintf(stderr, _("Address family `%s' not supported.\n"), tmp1);
	    return (E_OPTERR);
	}
	tmp1 = tmp2;

	if (!ap->rprint) {
	    fprintf(stderr, _("No routing for address family `%s'.\n"), ap->name);
	    return (E_OPTERR);
	}
	found = 0;

	if ((rc = ap->rprint(options)))
	    return (rc);

    }
    return (found);
}

--- NEW FILE: econet.c ---
/*
 * lib/econet.c This file contains an implementation of the Econet
 *              support functions for the net-tools.
 *              (NET-3 base distribution).
 *
 * Version:     $Id: econet.c,v 1.2 2006-08-31 09:32:17 dslinux_amadeus Exp $
 *
 * Author:      Philip Blundell <philb at gnu.org>
 *
 * Modified:
 *
 *              This program 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 of the License, or  (at
 *              your option) any later version.
 */

#include "config.h"

#if HAVE_AFECONET

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <neteconet/ec.h>

#include "version.h"
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"


/* Display an Econet address */
static char *
ec_print(unsigned char *ptr)
{
    static char buff[64];
    struct ec_addr *ec = (struct ec_addr *) ptr;
    sprintf(buff, "%d.%d", ec->net, ec->station);
    return buff;
}


/* Display an Econet socket address */
static char *
ec_sprint(struct sockaddr *sap, int numeric)
{
    struct sockaddr_ec *sec = (struct sockaddr_ec *) sap;

    if (sap->sa_family != AF_ECONET)
	return _("[NONE SET]");

    return ec_print((unsigned char *) &sec->addr);
}

static int 
ec_input(int type, char *bufp, struct sockaddr *sap)
{
    struct sockaddr_ec *sec = (struct sockaddr_ec *) sap;
    int net, stn;
    switch (sscanf(bufp, "%d.%d", &net, &stn)) {
    case 2:
	sec->addr.station = stn;
	sec->addr.net = net;
	return 0;
    case 1:
	if (sscanf(bufp, "%d", &stn) == 1) {
	    sec->addr.net = 0;
	    sec->addr.station = stn;
	    return 0;
	}
    }
    return -1;
}

struct aftype ec_aftype =
{
    "ec", NULL, AF_ECONET, 0,
    ec_print, ec_sprint, ec_input, NULL,
    NULL, NULL, NULL,
    -1,
    "/proc/sys/net/econet"
};

#endif				/* HAVE_AFECONET */

--- NEW FILE: proc.c ---
/* Tolerant /proc file parser. Copyright 1998 Andi Kleen */
/* $Id: proc.c,v 1.2 2006-08-31 09:32:19 dslinux_amadeus Exp $ */ 
/* Fixme: cannot currently cope with removed fields */ 

#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <ctype.h>

/* Caller must free return string. */

char *proc_gen_fmt(char *name, int more, FILE * fh,...)
{
    char buf[512], format[512] = "";
    char *title, *head, *hdr;
    va_list ap;

    if (!fgets(buf, (sizeof buf) - 1, fh))
	return NULL;
    strcat(buf, " ");

    va_start(ap, fh);
    title = va_arg(ap, char *);
    for (hdr = buf; hdr;) {
	while (isspace(*hdr) || *hdr == '|')
	    hdr++;
	head = hdr;
	hdr = strpbrk(hdr, "| \t\n");
	if (hdr)
	    *hdr++ = 0;

	if (!strcmp(title, head)) {
	    strcat(format, va_arg(ap, char *));
	    title = va_arg(ap, char *);
	    if (!title || !head)
		break;
	} else {
	    strcat(format, "%*s");	/* XXX */
	}
	strcat(format, " ");
    }
    va_end(ap);

    if (!more && title) {
	fprintf(stderr, "warning: %s does not contain required field %s\n",
		name, title);
	return NULL;
    }
    return strdup(format);
}

/* 
 * this will generate a bitmask of present/missing fields in the header of
 * a /proc file.
 */
int proc_guess_fmt(char *name, FILE *fh, ...)
{
    char buf[512];
    char *tmp;
    int flag = 0;
    va_list ap;

    if (!fgets(buf, (sizeof buf) - 1, fh))
	return -1;
    strcat(buf, "\0");
    va_start(ap, fh);
    while((tmp = va_arg(ap, char *))) {
      int f = va_arg(ap, int);
      if (strstr(buf,tmp) != 0)
        flag |= f;
    }
    va_end(ap);
    return flag;
}

--- NEW FILE: util.h ---
#include <stddef.h>

void *xmalloc(size_t sz);
void *xrealloc(void *p, size_t sz);

#define new(p) ((p) = xmalloc(sizeof(*(p))))


int kernel_version(void);
#define KRELEASE(maj,min,patch) ((maj) * 10000 + (min)*1000 + (patch))


int nstrcmp(const char *, const char *);

char *safe_strncpy(char *dst, const char *src, size_t size); 


--- NEW FILE: af.c ---
/*
 * lib/af.c   This file contains the top-level part of the protocol
 *              support functions module for the NET-2 base distribution.
 *
 * Version:     $Id: af.c,v 1.2 2006-08-31 09:32:17 dslinux_amadeus Exp $
 *
 * Author:      Fred N. van Kempen, <waltje at uwalt.nl.mugnet.org>
 *              Copyright 1993 MicroWalt Corporation
 *
 *              This program 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 of the License, or  (at
 *              your option) any later version.
 */
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include "config.h"
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"
#include "util.h"

int flag_unx;
int flag_ipx;
int flag_ax25;
int flag_ddp;
int flag_netrom;
int flag_inet;
int flag_inet6;
int flag_econet;
int flag_x25 = 0;
int flag_ash;


struct aftrans_t {
    char *alias;
    char *name;
    int *flag;
} aftrans[] = {

    {
	"ax25", "ax25", &flag_ax25
    },
    {
	"ip", "inet", &flag_inet
    },
    {
	"ip6", "inet6", &flag_inet6
    },
    {
	"ipx", "ipx", &flag_ipx
    },
    {
	"appletalk", "ddp", &flag_ddp
    },
    {
	"netrom", "netrom", &flag_netrom
    },
    {
	"inet", "inet", &flag_inet
    },
    {
	"inet6", "inet6", &flag_inet6
    },
    {
	"ddp", "ddp", &flag_ddp
    },
    {
	"unix", "unix", &flag_unx
    },
    {
	"tcpip", "inet", &flag_inet
    },
    {
	"econet", "ec", &flag_econet
    },
    {
	"x25", "x25", &flag_x25
    },
    {
        "ash", "ash", &flag_ash
    },
    {
	0, 0, 0
    }
};

char afname[256] = "";

extern struct aftype unspec_aftype;
extern struct aftype unix_aftype;
extern struct aftype inet_aftype;
extern struct aftype inet6_aftype;
extern struct aftype ax25_aftype;
extern struct aftype netrom_aftype;
extern struct aftype ipx_aftype;
extern struct aftype ddp_aftype;
extern struct aftype ec_aftype;
extern struct aftype x25_aftype;
extern struct aftype rose_aftype;
extern struct aftype ash_aftype;

static short sVafinit = 0;

struct aftype *aftypes[] =
{
#if HAVE_AFUNIX
    &unix_aftype,
#endif
#if HAVE_AFINET
    &inet_aftype,
#endif
#if HAVE_AFINET6
    &inet6_aftype,
#endif
#if HAVE_AFAX25
    &ax25_aftype,
#endif
#if HAVE_AFNETROM
    &netrom_aftype,
#endif
#if HAVE_AFROSE
    &rose_aftype,
#endif
#if HAVE_AFIPX
    &ipx_aftype,
#endif
#if HAVE_AFATALK
    &ddp_aftype,
#endif
#if HAVE_AFECONET
    &ec_aftype,
#endif
#if HAVE_AFASH
    &ash_aftype,
#endif
#if HAVE_AFX25
    &x25_aftype,
#endif
    &unspec_aftype,
    NULL
};

void afinit()
{
    unspec_aftype.title = _("UNSPEC");
#if HAVE_AFUNIX
    unix_aftype.title = _("UNIX Domain");
#endif
#if HAVE_AFINET
    inet_aftype.title = _("DARPA Internet");
#endif
#if HAVE_AFINET6
    inet6_aftype.title = _("IPv6");
#endif
#if HAVE_AFAX25
    ax25_aftype.title = _("AMPR AX.25");
#endif
#if HAVE_AFNETROM
    netrom_aftype.title = _("AMPR NET/ROM");
#endif
#if HAVE_AFIPX
    ipx_aftype.title = _("Novell IPX");
#endif
#if HAVE_AFATALK
    ddp_aftype.title = _("Appletalk DDP");
#endif
#if HAVE_AFECONET
    ec_aftype.title = _("Econet");
#endif
#if HAVE_AFX25
    x25_aftype.title = _("CCITT X.25");
#endif
#if HAVE_AFROSE
    rose_aftype.title = _("AMPR ROSE");
#endif
#if HAVE_AFASH
    ash_aftype.title = _("Ash");
#endif
    sVafinit = 1;
}

/* set the default AF list from the program name or a constant value    */
void aftrans_def(char *tool, char *argv0, char *dflt)
{
    char *tmp;
    char *buf;

    strcpy(afname, dflt);

    if (!(tmp = strrchr(argv0, '/')))
	tmp = argv0;		/* no slash?! */
    else
	tmp++;

    if (!(buf = strdup(tmp)))
	return;

    if (strlen(tool) >= strlen(tmp)) {
	free(buf);
	return;
    }
    tmp = buf + (strlen(tmp) - strlen(tool));

    if (strcmp(tmp, tool) != 0) {
	free(buf);
	return;
    }
    *tmp = '\0';
    if ((tmp = strchr(buf, '_')))
	*tmp = '\0';

    afname[0] = '\0';
    if (aftrans_opt(buf))
	strcpy(afname, buf);

    free(buf);
}


/* Check our protocol family table for this family. */
struct aftype *get_aftype(const char *name)
{
    struct aftype **afp;

    if (!sVafinit)
	afinit();

    afp = aftypes;
    while (*afp != NULL) {
	if (!strcmp((*afp)->name, name))
	    return (*afp);
	afp++;
    }
    if (index(name, ','))
	fprintf(stderr, _("Please don't supply more than one address family.\n"));
    return (NULL);
}


/* Check our protocol family table for this family. */
struct aftype *get_afntype(int af)
{
    struct aftype **afp;

    if (!sVafinit)
	afinit();

    afp = aftypes;
    while (*afp != NULL) {
	if ((*afp)->af == af)
	    return (*afp);
	afp++;
    }
    return (NULL);
}

/* Check our protocol family table for this family and return its socket */
int get_socket_for_af(int af)
{
    struct aftype **afp;

    if (!sVafinit)
	afinit();

    afp = aftypes;
    while (*afp != NULL) {
	if ((*afp)->af == af)
	    return (*afp)->fd;
	afp++;
    }
    return -1;
}

int aftrans_opt(const char *arg)
{
    struct aftrans_t *paft;
    char *tmp1, *tmp2;
    char buf[256];

    safe_strncpy(buf, arg, sizeof(buf));

    tmp1 = buf;

    while (tmp1) {

	tmp2 = index(tmp1, ',');

	if (tmp2)
	    *(tmp2++) = '\0';

	paft = aftrans;
	for (paft = aftrans; paft->alias; paft++) {
	    if (strcmp(tmp1, paft->alias))
		continue;
	    if (strlen(paft->name) + strlen(afname) + 1 >= sizeof(afname)) {
		fprintf(stderr, _("Too much address family arguments.\n"));
		return (0);
	    }
	    if (paft->flag)
		(*paft->flag)++;
	    if (afname[0])
		strcat(afname, ",");
	    strcat(afname, paft->name);
	    break;
	}
	if (!paft->alias) {
	    fprintf(stderr, _("Unknown address family `%s'.\n"), tmp1);
	    return (1);
	}
	tmp1 = tmp2;
    }

    return (0);
}

/* type: 0=all, 1=getroute */
void print_aflist(int type) {
    int count = 0;
    char * txt;
    struct aftype **afp;

    if (!sVafinit)
	afinit();

    afp = aftypes;
    while (*afp != NULL) {
	if ((type == 1 && ((*afp)->rprint == NULL)) || ((*afp)->af == 0)) {
		afp++; continue;
	}
	if ((count % 3) == 0) fprintf(stderr,count?"\n    ":"    "); 
        txt = (*afp)->name; if (!txt) txt = "..";
	fprintf(stderr,"%s (%s) ",txt,(*afp)->title);
	count++;
	afp++;
    }
    fprintf(stderr,"\n");
}

--- NEW FILE: ax25.c ---
/*
 * lib/ax25.c This file contains an implementation of the "AX.25"
 *              support functions.
 *
 * Version:     $Id: ax25.c,v 1.2 2006-08-31 09:32:17 dslinux_amadeus Exp $
 *
 * NOTE:        I will redo this module as soon as I got the libax25.a
 *              library sorted out.  This library contains some useful
 *              and often used address conversion functions, database
 *              lookup stuff, and more of the like.
 *
 * Author:      Fred N. van Kempen, <waltje at uwalt.nl.mugnet.org>
 *              Copyright 1993 MicroWalt Corporation
 *
 *              This program 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 of the License, or  (at
 *              your option) any later version.
 */
#include "config.h"

#if HAVE_AFAX25 || HAVE_HWAX25
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#if ((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1)) && !defined(__UCLIBC__)
#include <netax25/ax25.h>
#else
#include <linux/ax25.h>
#endif
#include <net/if_arp.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"
#include "util.h"

static char AX25_errmsg[128];

extern struct aftype ax25_aftype;

static char *AX25_print(unsigned char *ptr)
{
    static char buff[8];
    int i;

    for (i = 0; i < 6; i++) {
	buff[i] = ((ptr[i] & 0377) >> 1);
	if (buff[i] == ' ')
	    buff[i] = '\0';
    }
    buff[6] = '\0';
    i = ((ptr[6] & 0x1E) >> 1);
    if (i != 0)
	sprintf(&buff[strlen(buff)], "-%d", i);
    return (buff);
}


/* Display an AX.25 socket address. */
static char *
 AX25_sprint(struct sockaddr *sap, int numeric)
{
    static char buf[64];

    if (sap->sa_family == 0xFFFF || sap->sa_family == 0)
	return safe_strncpy(buf, _("[NONE SET]"), sizeof(buf));
    return (AX25_print(((struct sockaddr_ax25 *) sap)->sax25_call.ax25_call));
}


static int AX25_input(int type, char *bufp, struct sockaddr *sap)
{
    unsigned char *ptr;
    char *orig, c;
    int i;

    sap->sa_family = ax25_aftype.af;
    ptr = ((struct sockaddr_ax25 *) sap)->sax25_call.ax25_call;

    /* First, scan and convert the basic callsign. */
    orig = bufp;
    i = 0;
    while ((*bufp != '\0') && (*bufp != '-') && (i < 6)) {
	c = *bufp++;
	if (islower(c))
	    c = toupper(c);
	if (!(isupper(c) || isdigit(c))) {
	    safe_strncpy(AX25_errmsg, _("Invalid callsign"), sizeof(AX25_errmsg));
#ifdef DEBUG
	    fprintf(stderr, "ax25_input(%s): %s !\n", AX25_errmsg, orig);
#endif
	    errno = EINVAL;
	    return (-1);
	}
	*ptr++ = (unsigned char) ((c << 1) & 0xFE);
	i++;
    }

    /* Callsign too long? */
    if ((i == 6) && (*bufp != '-') && (*bufp != '\0')) {
	strcpy(AX25_errmsg, _("Callsign too long"));
#ifdef DEBUG
	fprintf(stderr, "ax25_input(%s): %s !\n", AX25_errmsg, orig);
#endif
	errno = E2BIG;
	return (-1);
    }
    /* Nope, fill out the address bytes with blanks. */
    while (i++ < sizeof(ax25_address) - 1) {
	*ptr++ = (unsigned char) ((' ' << 1) & 0xFE);
    }

    /* See if we need to add an SSID field. */
    if (*bufp == '-') {
	i = atoi(++bufp);
	*ptr = (unsigned char) ((i << 1) & 0xFE);
    } else {
	*ptr = (unsigned char) '\0';
    }

    /* All done. */
#ifdef DEBUG
    fprintf(stderr, "ax25_input(%s): ", orig);
    for (i = 0; i < sizeof(ax25_address); i++)
	fprintf(stderr, "%02X ", sap->sa_data[i] & 0377);
    fprintf(stderr, "\n");
#endif

    return (0);
}


/* Display an error message. */
static void AX25_herror(char *text)
{
    if (text == NULL)
	fprintf(stderr, "%s\n", AX25_errmsg);
    else
	fprintf(stderr, "%s: %s\n", text, AX25_errmsg);
}


static int AX25_hinput(char *bufp, struct sockaddr *sap)
{
    if (AX25_input(0, bufp, sap) < 0)
	return (-1);
    sap->sa_family = ARPHRD_AX25;
    return (0);
}

#if 0
/* Set the line discipline of a terminal line. */
static int KISS_set_disc(int fd, int disc)
{
    if (ioctl(fd, TIOCSETD, &disc) < 0) {
	fprintf(stderr, "KISS_set_disc(%d): %s\n", disc, strerror(errno));
	return (-errno);
    }
    return (0);
}


/* Start the KISS encapsulation on the file descriptor. */
static int KISS_init(int fd)
{
    if (KISS_set_disc(fd, N_SLIP) < 0)
	return (-1);
    if (ioctl(fd, SIOCSIFENCAP, 4) < 0)
	return (-1);
    return (0);
}
#endif

struct hwtype ax25_hwtype =
{
    "ax25", NULL, /*"AMPR AX.25", */ ARPHRD_AX25, 7,
    AX25_print, AX25_hinput, NULL
};

struct aftype ax25_aftype =
{
    "ax25", NULL, /*"AMPR AX.25", */ AF_AX25, 7,
    AX25_print, AX25_sprint, AX25_input, AX25_herror,
    NULL, NULL, NULL,
    -1,
    "/proc/net/ax25"
};

#endif				/* HAVE_xxAX25 */

--- NEW FILE: rose.c ---
/*
 * lib/rose.c This file contains an implementation of the "ROSE"
 *              support functions for the NET-2 base distribution.
 *
 * Version:     $Id: rose.c,v 1.2 2006-08-31 09:32:19 dslinux_amadeus Exp $
 *
 * Author:      Terry Dawson, VK2KTJ, <terry at perf.no.itg.telstra.com.au>
 *              based on ax25.c by:
 *              Fred N. van Kempen, <waltje at uwalt.nl.mugnet.org>
 *              Copyright 1993 MicroWalt Corporation
 *
 *              This program 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 of the License, or  (at
 *              your option) any later version.
 */
#include "config.h"

#if HAVE_AFROSE || HAVE_HWROSE
#include <features.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if_arp.h>		/* ARPHRD_ROSE */
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"

#ifndef _NETROSE_ROSE_H
#include <linux/ax25.h>
#include <linux/rose.h>
/* this will check for the broken #define PF_ROSE AF_ROSE define in some older kernel headers */
#undef AF_ROSE
#if PF_ROSE == AF_ROSE
#warning "Your <linux/rose.h> is broken and defines PF_ROSE, better remove the define in /usr/include/linux/rose.h (using private define for PF_ROSE meanwhile)"
#undef PF_ROSE
#define PF_ROSE         11      /* Amateur Radio X.25 PLP       */
#endif
/* now restore the value of AF_ROSE (which had to be deleted to catch the case where #define AF_ROSE PF_ROSE) */
#define AF_ROSE         PF_ROSE
#endif

static char ROSE_errmsg[128];

extern struct aftype rose_aftype;

static char *
 ROSE_print(unsigned char *ptr)
{
    static char buff[12];

    snprintf(buff, sizeof(buff), "%02x%02x%02x%02x%02x", ptr[0], ptr[1], ptr[2], ptr[3], ptr[4]);
    buff[10] = '\0';
    return (buff);
}

/* Display a ROSE socket address. */
static char *
 ROSE_sprint(struct sockaddr *sap, int numeric)
{
    if (sap->sa_family == 0xFFFF || sap->sa_family == 0)
	return _("[NONE SET]");

    return (ROSE_print(((struct sockaddr_rose *) sap)->srose_addr.rose_addr));
}


static int ROSE_input(int type, char *bufp, struct sockaddr *sap)
{
    char *ptr;
    int i, o;

    sap->sa_family = rose_aftype.af;
    ptr = ((struct sockaddr_rose *) sap)->srose_addr.rose_addr;

    /* Node address the correct length ? */
    if (strlen(bufp) != 10) {
	strcpy(ROSE_errmsg, _("Node address must be ten digits"));
#ifdef DEBUG
	fprintf(stderr, "rose_input(%s): %s !\n", ROSE_errmsg, orig);
#endif
	errno = EINVAL;
	return (-1);
    }
    /* Ok, lets set it */
    for (i = 0, o = 0; i < 5; i++) {
	o = i * 2;
	ptr[i] = (((bufp[o] - '0') << 4) | (bufp[o + 1] - '0'));
    }

    /* All done. */
#ifdef DEBUG
    fprintf(stderr, "rose_input(%s): ", orig);
    for (i = 0; i < sizeof(rose_address); i++)
	fprintf(stderr, "%02X ", sap->sa_data[i] & 0377);
    fprintf(stderr, "\n");
#endif

    return (0);
}


/* Display an error message. */
static void ROSE_herror(char *text)
{
    if (text == NULL)
	fprintf(stderr, "%s\n", ROSE_errmsg);
    else
	fprintf(stderr, "%s: %s\n", text, ROSE_errmsg);
}


static int ROSE_hinput(char *bufp, struct sockaddr *sap)
{
    if (ROSE_input(0, bufp, sap) < 0)
	return (-1);
    sap->sa_family = ARPHRD_ROSE;
    return (0);
}

struct hwtype rose_hwtype =
{
    "rose", NULL, /*"AMPR ROSE", */ ARPHRD_ROSE, 10,
    ROSE_print, ROSE_hinput, NULL
};

struct aftype rose_aftype =
{
    "rose", NULL, /*"AMPR ROSE", */ AF_ROSE, 10,
    ROSE_print, ROSE_sprint, ROSE_input, ROSE_herror,
    NULL, NULL, NULL,
    -1,
    "/proc/net/rose"
};

#endif				/* HAVE_xxROSE */

--- NEW FILE: inet6_gr.c ---
/*
   Modifications:
   1998-07-01 - Arnaldo Carvalho de Melo - GNU gettext instead of catgets,
   snprintf instead of sprintf
 */

#include "config.h"

#if HAVE_AFINET6
#include <asm/types.h>
#include <asm/param.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
/* #include <net/route.h> realy broken */
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <resolv.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#ifndef __GLIBC__
#include <netinet6/ipv6_route.h>	/* glibc doesn't have this */
#endif
#include "version.h"
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"
#include "net-features.h"

/* neighbour discovery from linux-2.4.0/include/net/neighbour.h */

#define NUD_INCOMPLETE  0x01
#define NUD_REACHABLE   0x02
#define NUD_STALE       0x04
#define NUD_DELAY       0x08
#define NUD_PROBE       0x10
#define NUD_FAILED      0x20

#define NUD_NOARP       0x40
#define NUD_PERMANENT   0x80
#define NUD_NONE        0x00

#define NTF_PROXY       0x08    /* == ATF_PUBL */
#define NTF_ROUTER      0x80
#define NTF_02          0x02  /* waiting for answer of Alexey -eckes */
#define NTF_04          0x04  /* waiting for answer of Alexey -eckes */

/* */


extern struct aftype inet6_aftype;


int rprint_fib6(int ext, int numeric)
{
    char buff[4096], iface[16], flags[16];
    char addr6[128], naddr6[128];
    struct sockaddr_in6 saddr6, snaddr6;
    int num, iflags, metric, refcnt, use, prefix_len, slen;
    FILE *fp = fopen(_PATH_PROCNET_ROUTE6, "r");
    
    char addr6p[8][5], saddr6p[8][5], naddr6p[8][5];

    if (!fp) {
	perror(_PATH_PROCNET_ROUTE6);
        printf(_("INET6 (IPv6) not configured in this system.\n"));
	return 1;
    }
    printf(_("Kernel IPv6 routing table\n"));

    printf(_("Destination                                 "
	     "Next Hop                                "
	     "Flags Metric Ref    Use Iface\n"));

    while (fgets(buff, 1023, fp)) {
	num = sscanf(buff, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %4s%4s%4s%4s%4s%4s%4s%4s %02x %4s%4s%4s%4s%4s%4s%4s%4s %08x %08x %08x %08x %s\n",
		     addr6p[0], addr6p[1], addr6p[2], addr6p[3],
		     addr6p[4], addr6p[5], addr6p[6], addr6p[7],
		     &prefix_len,
		     saddr6p[0], saddr6p[1], saddr6p[2], saddr6p[3],
		     saddr6p[4], saddr6p[5], saddr6p[6], saddr6p[7],
		     &slen,
		     naddr6p[0], naddr6p[1], naddr6p[2], naddr6p[3],
		     naddr6p[4], naddr6p[5], naddr6p[6], naddr6p[7],
		     &metric, &use, &refcnt, &iflags, iface);
#if 0
	if (num < 23)
	    continue;
#endif
	if (!(iflags & RTF_UP))
	    continue;
	/* Fetch and resolve the target address. */
	snprintf(addr6, sizeof(addr6), "%s:%s:%s:%s:%s:%s:%s:%s",
		 addr6p[0], addr6p[1], addr6p[2], addr6p[3],
		 addr6p[4], addr6p[5], addr6p[6], addr6p[7]);
	inet6_aftype.input(1, addr6, (struct sockaddr *) &saddr6);
	snprintf(addr6, sizeof(addr6), "%s/%d",
		 inet6_aftype.sprint((struct sockaddr *) &saddr6, 1),
		 prefix_len);

	/* Fetch and resolve the nexthop address. */
	snprintf(naddr6, sizeof(naddr6), "%s:%s:%s:%s:%s:%s:%s:%s",
		 naddr6p[0], naddr6p[1], naddr6p[2], naddr6p[3],
		 naddr6p[4], naddr6p[5], naddr6p[6], naddr6p[7]);
	inet6_aftype.input(1, naddr6, (struct sockaddr *) &snaddr6);
	snprintf(naddr6, sizeof(naddr6), "%s",
		 inet6_aftype.sprint((struct sockaddr *) &snaddr6, 1));

	/* Decode the flags. */
	strcpy(flags, "U");
	if (iflags & RTF_GATEWAY)
	    strcat(flags, "G");
	if (iflags & RTF_HOST)
	    strcat(flags, "H");
	if (iflags & RTF_DEFAULT)
	    strcat(flags, "D");
	if (iflags & RTF_ADDRCONF)
	    strcat(flags, "A");
	if (iflags & RTF_CACHE)
	    strcat(flags, "C");

	/* Print the info. */
	printf("%-43s %-39s %-5s %-6d %-2d %7d %-8s\n",
	       addr6, naddr6, flags, metric, refcnt, use, iface);
    }

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

int rprint_cache6(int ext, int numeric)
{
    char buff[4096], iface[16], flags[16];
    char addr6[128], haddr[20], statestr[20];
    struct sockaddr_in6 saddr6;
    int type, num, refcnt, prefix_len, location, state, gc;
    long tstamp, expire, ndflags, reachable, stale, delete;
    FILE *fp = fopen(_PATH_PROCNET_NDISC, "r");
    char addr6p[8][5], haddrp[6][3];

    if (!fp) {
	ESYSNOT("nd_print", "ND Table");
	return 1;
    }
    printf(_("Kernel IPv6 Neighbour Cache\n"));

    if (ext == 2)
	printf(_("Neighbour                                   "
		 "HW Address        "
		 "Iface    Flags Ref State\n"));
    else
	printf(_("Neighbour                                   "
		 "HW Address        "
	"Iface    Flags Ref State            Stale(sec) Delete(sec)\n"));


    while (fgets(buff, 1023, fp)) {
	num = sscanf(buff, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %08lx %08lx %08lx %04x %04x %04lx %8s %2s%2s%2s%2s%2s%2s\n",
		     addr6p[0], addr6p[1], addr6p[2], addr6p[3],
		     addr6p[4], addr6p[5], addr6p[6], addr6p[7],
		     &location, &prefix_len, &type, &state, &expire, &tstamp, &reachable, &gc, &refcnt,
		     &ndflags, iface,
	haddrp[0], haddrp[1], haddrp[2], haddrp[3], haddrp[4], haddrp[5]);

	/* Fetch and resolve the nexthop address. */
	snprintf(addr6, sizeof(addr6), "%s:%s:%s:%s:%s:%s:%s:%s",
		 addr6p[0], addr6p[1], addr6p[2], addr6p[3],
		 addr6p[4], addr6p[5], addr6p[6], addr6p[7]);
	inet6_aftype.input(1, addr6, (struct sockaddr *) &saddr6);
	snprintf(addr6, sizeof(addr6), "%s/%d",
	       inet6_aftype.sprint((struct sockaddr *) &saddr6, numeric),
		 prefix_len);

	/* Fetch the  hardware address. */
	snprintf(haddr, sizeof(haddr), "%s:%s:%s:%s:%s:%s",
	haddrp[0], haddrp[1], haddrp[2], haddrp[3], haddrp[4], haddrp[5]);

	/* Decode the flags. */
	flags[0] = '\0';
	if (ndflags & NTF_ROUTER)
	    strcat(flags, "R");
	if (ndflags & NTF_04)
	    strcat(flags, "x");
	if (ndflags & NTF_02)
	    strcat(flags, "h");
	if (ndflags & NTF_PROXY)
	    strcat(flags, "P");

	/* Decode the state */
	switch (state) {
	case NUD_NONE:
	    strcpy(statestr, "NONE");
	    break;
	case NUD_INCOMPLETE:
	    strcpy(statestr, "INCOMPLETE");
	    break;
	case NUD_REACHABLE:
	    strcpy(statestr, "REACHABLE");
	    break;
	case NUD_STALE:
	    strcpy(statestr, "STALE");
	    break;
	case NUD_DELAY:
	    strcpy(statestr, "DELAY");
	    break;
	case NUD_PROBE:
	    strcpy(statestr, "PROBE");
	    break;
	case NUD_FAILED:
	    strcpy(statestr, "FAILED");
	    break;
	case NUD_NOARP:
	    strcpy(statestr, "NOARP");
	    break;
	case NUD_PERMANENT:
	    strcpy(statestr, "PERM");
	    break;
	default:
	    snprintf(statestr, sizeof(statestr), "UNKNOWN(%02x)", state);
	    break;
	}

	/* Print the info. */
	printf("%-43s %-17s %-8s %-5s %-3d %-16s",
	       addr6, haddr, iface, flags, refcnt, statestr);

	stale = 0;
	if (state == NUD_REACHABLE)
	    stale = reachable > tstamp ? reachable - tstamp : 0;
	delete = gc > tstamp ? gc - tstamp : 0;
	if (ext != 2) {
	    printf(" %-9ld ", stale / HZ);
	    if (refcnt)
		printf(" * ");
	    else
		printf(" %-7ld ", delete / HZ);
	}
	printf("\n");
    }

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

int INET6_rprint(int options)
{
    int ext = options & FLAG_EXT;
    int numeric = options & (FLAG_NUM_HOST | FLAG_SYM);
    int rc = E_INTERN;

    if (options & FLAG_FIB)
	if ((rc = rprint_fib6(ext, numeric)))
	    return (rc);

    if (options & FLAG_CACHE)
	if ((rc = rprint_cache6(ext, numeric)))
	    return (rc);
    return (rc);
}

#endif				/* HAVE_AFINET6 */

--- NEW FILE: sit.c ---
/*
 * lib/sit.c  This file contains the SIT HW-type support.
 *
 * Version:    $Id: sit.c,v 1.2 2006-08-31 09:32:19 dslinux_amadeus Exp $
 *
 * Author:      Fred N. van Kempen, <waltje at uwalt.nl.mugnet.org>
 *              Copyright 1993 MicroWalt Corporation
 *
 *              Based on slip.c, modified by Frank Strauss, Aug 1996
 *
 *              This program 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 of the License, or  (at
 *              your option) any later version.
 */
#include "config.h"

#if HAVE_HWSIT

#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if_arp.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include "net-support.h"
#include "pathnames.h"

#ifndef ARPHRD_SIT
#warning "No definition of ARPHRD_SIT in <net/if_arp.h>, using private value 776"
#define ARPHRD_SIT 776
#endif

struct hwtype sit_hwtype =
{
    "sit", NULL, /*"IPv6-in-IPv4", */ ARPHRD_SIT, 0,
    NULL, NULL, NULL, 0
};

#endif				/* HAVE_HWSIT */

--- NEW FILE: unix.c ---
/*
 * lib/unix.c This file contains the general hardware types.
 *
 * Version:     $Id: unix.c,v 1.2 2006-08-31 09:32:19 dslinux_amadeus Exp $
 *
 * Author:      Fred N. van Kempen, <waltje at uwalt.nl.mugnet.org>
 *              Copyright 1993 MicroWalt Corporation
 *
 *              This program 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 of the License, or  (at
 *              your option) any later version.
 */
#include "config.h"

#include <sys/types.h>
#include <sys/socket.h>
#if HAVE_AFUNIX
#include <sys/un.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"
#include "util.h"


/* Display an UNSPEC address. */
static char *UNSPEC_print(unsigned char *ptr)
{
    static char buff[64];
    char *pos;
    unsigned int i;

    pos = buff;
    for (i = 0; i < sizeof(struct sockaddr); i++) {
	pos += sprintf(pos, "%02X-", (*ptr++ & 0377));
    }
    buff[strlen(buff) - 1] = '\0';
    return (buff);
}


/* Display an UNSPEC socket address. */
static char *UNSPEC_sprint(struct sockaddr *sap, int numeric)
{
    static char buf[64];

    if (sap->sa_family == 0xFFFF || sap->sa_family == 0)
	return safe_strncpy(buf, _("[NONE SET]"), sizeof(buf));
    return (UNSPEC_print(sap->sa_data));
}


#if HAVE_AFUNIX

/* Display a UNIX domain address. */
static char *UNIX_print(unsigned char *ptr)
{
    return (ptr);
}


/* Display a UNIX domain address. */
static char *UNIX_sprint(struct sockaddr *sap, int numeric)
{
    static char buf[64];

    if (sap->sa_family == 0xFFFF || sap->sa_family == 0)
	return safe_strncpy(buf, _("[NONE SET]"), sizeof(buf));
    return (UNIX_print(sap->sa_data));
}


struct aftype unix_aftype =
{
    "unix", NULL, /*"UNIX Domain", */ AF_UNIX, 0,
    UNIX_print, UNIX_sprint, NULL, NULL,
    NULL, NULL, NULL,
    -1,
    "/proc/net/unix"
};
#endif				/* HAVE_AFUNIX */


struct aftype unspec_aftype =
{
    "unspec", NULL, /*"UNSPEC", */ AF_UNSPEC, 0,
    UNSPEC_print, UNSPEC_sprint, NULL, NULL,
    NULL,
};

--- NEW FILE: netrom_gr.c ---
/*
 * lib/netrom_gr.c    This file contains an implementation of the NET/ROM
 *                      route support functions.
 *
 * Version:     $Id: netrom_gr.c,v 1.2 2006-08-31 09:32:18 dslinux_amadeus Exp $
 *
 * Author:      Bernd Eckenfels, <ecki at lina.inka.de>
 *              Copyright 1999 Bernd Eckenfels, Germany
 *              base on Code from Jonathan Naylor <jsn at Cs.Nott.AC.UK>
 *
 * Changes:
 * 980701 {0.02} Arnaldo Carvalho de Melo   GNU gettext instead of catgets
 * 
 *
 *              This program 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 of the License, or  (at
 *              your option) any later version.
 */
#include "config.h"

#if HAVE_AFNETROM
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"

/* UGLY */

int NETROM_rprint(int options)
{
    FILE *f1 = fopen(_PATH_PROCNET_NR_NODES, "r");
    FILE *f2 = fopen(_PATH_PROCNET_NR_NEIGH, "r");
    char buffer[256];
    int qual, n, w;
    /*int ext = options & FLAG_EXT;
       int numeric = options & FLAG_NUM_HOST; */

    f1 = fopen(_PATH_PROCNET_NR_NODES, "r");
    if (!f1) perror(_PATH_PROCNET_NR_NODES);
    f2 = fopen(_PATH_PROCNET_NR_NEIGH, "r");
    if (!f2) perror(_PATH_PROCNET_NR_NEIGH);

    if (f1 == NULL || f2 == NULL) {
	printf(_("NET/ROM not configured in this system.\n"));
	return 1;
    }
    printf(_("Kernel NET/ROM routing table\n"));
    printf(_("Destination  Mnemonic  Quality  Neighbour  Iface\n"));
    fgets(buffer, 256, f1);
    while (fgets(buffer, 256, f1)) {
	buffer[9] = 0;
	buffer[17] = 0;
	w = atoi(buffer + 19) - 1;
	printf("%-9s    %-7s   ",
	       buffer, buffer + 10);
	qual = atoi(buffer + 24 + 15 * w);
	n = atoi(buffer + 32 + 15 * w);
	rewind(f2);
	fgets(buffer, 256, f2);
	while (fgets(buffer, 256, f2)) {
	    if (atoi(buffer) == n) {
		buffer[15] = 0;
		buffer[20] = 0;
		printf("%3d      %-9s  %s\n",
		       qual, buffer + 6, buffer + 16);
		break;
	    }
	}
    }
    fclose(f1);
    fclose(f2);
    return 0;
}

#endif				/* HAVE_AFNETROM */

--- NEW FILE: ec_hw.c ---
/*
 * lib/ec_hw.c  This file contains an implementation of the Econet
 *              hardware support functions.
 *
 * Version:     $Id: ec_hw.c,v 1.2 2006-08-31 09:32:17 dslinux_amadeus Exp $
 *
 * Author:      Philip Blundell <philb at gnu.org>
 *
 *              This program 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 of the License, or  (at
 *              your option) any later version.
 */
#include "config.h"

#if HAVE_HWEC

#include <net/if_arp.h>
#include "net-support.h"

struct hwtype ec_hwtype =
{
    "ec", NULL /* "Econet" */, ARPHRD_ECONET, 0,
    NULL, NULL, NULL
};

#endif

--- NEW FILE: strip.c ---
/*
 * lib/strip.c	This file contains an implementation of the STRIP
 *		support functions.
 *
 * Version:	strip.c	1.20 1999/04/22 eswierk
 *
 * Author:	Stuart Cheshire <cheshire at cs.stanford.edu>
 *
 *		This program 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 of the License, or  (at
 *		your option) any later version.
 */
#include "config.h"

#if HAVE_HWSTRIP

#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if_arp.h>
#include <linux/types.h>
#include <linux/if_strip.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include "net-support.h"
#include "pathnames.h"
#include "util.h"
#include "intl.h"


extern struct hwtype strip_hwtype;

static char *
pr_strip(unsigned char *ptr)
{
  static char buff[64];
  if(ptr[1])
      sprintf(buff, "%02x-%02x%02x-%02x%02x", *(ptr+1), *(ptr+2), *(ptr+3),
          *(ptr+4), *(ptr+5));
   else
      sprintf(buff, "%02x%02x-%02x%02x", *(ptr+2), *(ptr+3), *(ptr+4),
	  *(ptr+5));
  return buff;
}

static int
in_strip(char *bufp, struct sockaddr *sap)
{
  int i,i0;
  MetricomAddress *haddr = (MetricomAddress *) (sap->sa_data);


  sap->sa_family = strip_hwtype.type;

  /* figure out what the device-address should be */
  i0 = i = (bufp[0] == '*') ? 1 : 0;

  while (bufp[i] && (bufp[i] != '-'))
    i++;

  if (bufp[i] != '-')
    return -1;

  if(i-i0 == 2)
  {
     haddr->c[1] = strtol(&bufp[i0], 0, 16);
     i++;
     if(bufp[i] == 0) return -1;
  }else{
     haddr->c[1] = 0;
     i=i0;
  }
  haddr->c[2] = strtol(&bufp[i], 0, 16) >> 8;
  haddr->c[3] = strtol(&bufp[i], 0, 16) & 0xFF;

  while (bufp[i] && (bufp[i] != '-'))
    i++;

  if (bufp[i] != '-')
    return -1;

  haddr->c[4] = strtol(&bufp[i+1], 0, 16) >> 8;
  haddr->c[5] = strtol(&bufp[i+1], 0, 16) & 0xFF;
  haddr->c[0] = 0;

  return 0;
}



/* Start the STRIP encapsulation on the file descriptor. */
static int do_strip(int fd)
	{
	int disc = N_STRIP;
	if (ioctl(fd, TIOCSETD, &disc) < 0)
		{
		fprintf(stderr, "STRIP_set_disc(%d): %s\n", disc, strerror(errno));
		return(-errno);
		}
	return(0);
	}

struct hwtype strip_hwtype = {
  "strip", "Metricom Starmode IP", ARPHRD_METRICOM, sizeof(MetricomAddress),
  pr_strip, in_strip, do_strip, 0
};

#endif	/* HAVE_HWSTRIP */

--- NEW FILE: slip.c ---
/*
 * lib/slip.c This file contains the SLIP HW-type support.
 *
 * Version:     $Id: slip.c,v 1.2 2006-08-31 09:32:19 dslinux_amadeus Exp $
 *
 * Author:      Fred N. van Kempen, <waltje at uwalt.nl.mugnet.org>
 *              Copyright 1993 MicroWalt Corporation
 *
 *              Modified by Alan Cox, May 94 to cover NET-3
 *
 *              This program 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 of the License, or  (at
 *              your option) any later version.
 */
#include "config.h"

#if HAVE_HWSLIP

#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if_arp.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include "net-support.h"
#include "pathnames.h"


struct hwtype slip_hwtype =
{
    "slip", NULL, /*"Serial Line IP", */ ARPHRD_SLIP, 0,
    NULL, NULL, NULL
};
struct hwtype cslip_hwtype =
{
    "cslip", NULL, /*"VJ Serial Line IP", */ ARPHRD_CSLIP, 0,
    NULL, NULL, NULL
};
struct hwtype slip6_hwtype =
{
    "slip6", NULL, /*"6-bit Serial Line IP", */ ARPHRD_SLIP6, 0,
    NULL, NULL, NULL
};
struct hwtype cslip6_hwtype =
{
    "cslip6", NULL, /*"VJ 6-bit Serial Line IP", */ ARPHRD_CSLIP6, 0,
    NULL, NULL, NULL
};
struct hwtype adaptive_hwtype =
{
    "adaptive", NULL, /*"Adaptive Serial Line IP", */ ARPHRD_ADAPT, 0,
    NULL, NULL, NULL
};
#endif				/* HAVE_HWSLIP */

--- NEW FILE: hw.c ---
/*
 * lib/hw.c   This file contains the top-level part of the hardware
 *              support functions module.
 *
 * Version:     $Id: hw.c,v 1.2 2006-08-31 09:32:18 dslinux_amadeus Exp $
 *
 * Maintainer:  Bernd 'eckes' Eckenfels, <net-tools at lina.inka.de>
 *
 * Author:      Fred N. van Kempen, <waltje at uwalt.nl.mugnet.org>
 *              Copyright 1993 MicroWalt Corporation
 *
 *980701 {1.21}  Arnaldo C. Melo       GNU gettext instead of catgets
 *
 *              This program 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 of the License, or  (at
 *              your option) any later version.
 */
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if_arp.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include "config.h"
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"

extern struct hwtype unspec_hwtype;
extern struct hwtype loop_hwtype;

extern struct hwtype slip_hwtype;
extern struct hwtype cslip_hwtype;
extern struct hwtype slip6_hwtype;
extern struct hwtype cslip6_hwtype;
extern struct hwtype adaptive_hwtype;
extern struct hwtype strip_hwtype;

extern struct hwtype ether_hwtype;
extern struct hwtype fddi_hwtype;
extern struct hwtype hippi_hwtype;
extern struct hwtype tr_hwtype;
#ifdef ARPHRD_IEEE802_TR
extern struct hwtype tr_hwtype1;
#endif

extern struct hwtype ax25_hwtype;
extern struct hwtype rose_hwtype;
extern struct hwtype netrom_hwtype;
extern struct hwtype x25_hwtype;
extern struct hwtype tunnel_hwtype;

extern struct hwtype ash_hwtype;

extern struct hwtype ppp_hwtype;

extern struct hwtype arcnet_hwtype;

extern struct hwtype dlci_hwtype;
extern struct hwtype frad_hwtype;

extern struct hwtype hdlc_hwtype;
extern struct hwtype lapb_hwtype;

extern struct hwtype sit_hwtype;

extern struct hwtype irda_hwtype;

extern struct hwtype ec_hwtype;

static struct hwtype *hwtypes[] =
{

    &loop_hwtype,

#if HAVE_HWSLIP
    &slip_hwtype,
    &cslip_hwtype,
    &slip6_hwtype,
    &cslip6_hwtype,
    &adaptive_hwtype,
#endif
#if HAVE_HWSTRIP
    &strip_hwtype,
#endif
#if HAVE_HWASH
    &ash_hwtype,
#endif
#if HAVE_HWETHER
    &ether_hwtype,
#endif
#if HAVE_HWTR
    &tr_hwtype,
#ifdef ARPHRD_IEEE802_TR
    &tr_hwtype1, 
#endif
#endif
#if HAVE_HWAX25
    &ax25_hwtype,
#endif
#if HAVE_HWNETROM
    &netrom_hwtype,
#endif
#if HAVE_HWROSE
    &rose_hwtype,
#endif
#if HAVE_HWTUNNEL
    &tunnel_hwtype,
#endif
#if HAVE_HWPPP
    &ppp_hwtype,
#endif
#if HAVE_HWHDLCLAPB
    &hdlc_hwtype,
    &lapb_hwtype,
#endif
#if HAVE_HWARC
    &arcnet_hwtype,
#endif
#if HAVE_HWFR
    &dlci_hwtype,
    &frad_hwtype,
#endif
#if HAVE_HWSIT
    &sit_hwtype,
#endif
#if HAVE_HWFDDI
    &fddi_hwtype,
#endif
#if HAVE_HWHIPPI
    &hippi_hwtype,
#endif
#if HAVE_HWIRDA
    &irda_hwtype,
#endif
#if HAVE_HWEC
    &ec_hwtype,
#endif
#if HAVE_HWX25
    &x25_hwtype,
#endif
    &unspec_hwtype,
    NULL
};

static short sVhwinit = 0;

void hwinit()
{
    loop_hwtype.title = _("Local Loopback");
    unspec_hwtype.title = _("UNSPEC");
#if HAVE_HWSLIP
    slip_hwtype.title = _("Serial Line IP");
    cslip_hwtype.title = _("VJ Serial Line IP");
    slip6_hwtype.title = _("6-bit Serial Line IP");
    cslip6_hwtype.title = _("VJ 6-bit Serial Line IP");
    adaptive_hwtype.title = _("Adaptive Serial Line IP");
#endif
#if HAVE_HWETHER
    ether_hwtype.title = _("Ethernet");
#endif
#if HAVE_HWASH
    ash_hwtype.title = _("Ash");
#endif
#if HAVE_HWFDDI
    fddi_hwtype.title = _("Fiber Distributed Data Interface");
#endif
#if HAVE_HWHIPPI
    hippi_hwtype.title = _("HIPPI");
#endif
#if HAVE_HWAX25
    ax25_hwtype.title = _("AMPR AX.25");
#endif
#if HAVE_HWROSE
    rose_hwtype.title = _("AMPR ROSE");
#endif
#if HAVE_HWNETROM
    netrom_hwtype.title = _("AMPR NET/ROM");
#endif
#if HAVE_HWX25
    x25_hwtype.title = _("generic X.25");
#endif
#if HAVE_HWTUNNEL
    tunnel_hwtype.title = _("IPIP Tunnel");
#endif
#if HAVE_HWPPP
    ppp_hwtype.title = _("Point-to-Point Protocol");
#endif
#if HAVE_HWHDLCLAPB
    hdlc_hwtype.title = _("(Cisco)-HDLC");
    lapb_hwtype.title = _("LAPB");
#endif
#if HAVE_HWARC
    arcnet_hwtype.title = _("ARCnet");
#endif
#if HAVE_HWFR
    dlci_hwtype.title = _("Frame Relay DLCI");
    frad_hwtype.title = _("Frame Relay Access Device");
#endif
#if HAVE_HWSIT
    sit_hwtype.title = _("IPv6-in-IPv4");
#endif
#if HAVE_HWIRDA
    irda_hwtype.title = _("IrLAP");
#endif
#if HAVE_HWTR
    tr_hwtype.title = _("16/4 Mbps Token Ring");
#ifdef ARPHRD_IEEE802_TR
    tr_hwtype1.title = _("16/4 Mbps Token Ring (New)") ; 
#endif
#endif
#if HAVE_HWEC
    ec_hwtype.title = _("Econet");
#endif
    sVhwinit = 1;
}

/* Check our hardware type table for this type. */
struct hwtype *get_hwtype(const char *name)
{
    struct hwtype **hwp;

    if (!sVhwinit)
	hwinit();

    hwp = hwtypes;
    while (*hwp != NULL) {
	if (!strcmp((*hwp)->name, name))
	    return (*hwp);
	hwp++;
    }
    return (NULL);
}


/* Check our hardware type table for this type. */
struct hwtype *get_hwntype(int type)
{
    struct hwtype **hwp;

    if (!sVhwinit)
	hwinit();

    hwp = hwtypes;
    while (*hwp != NULL) {
	if ((*hwp)->type == type)
	    return (*hwp);
	hwp++;
    }
    return (NULL);
}

/* type: 0=all, 1=ARPable */
void print_hwlist(int type) {
    int count = 0;
    char * txt;
    struct hwtype **hwp;

    if (!sVhwinit)
	hwinit();

    hwp = hwtypes;
    while (*hwp != NULL) {
	if (((type == 1) && ((*hwp)->alen == 0)) || ((*hwp)->type == -1)) {
		hwp++; continue;
	}
	if ((count % 3) == 0) fprintf(stderr,count?"\n    ":"    "); 
        txt = (*hwp)->name; if (!txt) txt = "..";
	fprintf(stderr,"%s (%s) ",txt,(*hwp)->title);
	count++;
	hwp++;
    }
    fprintf(stderr,"\n");
}

/* return 1 if address is all zeros */
int hw_null_address(struct hwtype *hw, void *ap)
{
    unsigned int i;
    unsigned char *address = (unsigned char *)ap;
    for (i = 0; i < hw->alen; i++)
	if (address[i])
	    return 0;
    return 1;
}

--- NEW FILE: ipx_sr.c ---
#include "config.h"

#if HAVE_AFIPX
#include <sys/param.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <sys/ioctl.h>
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <resolv.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include "version.h"
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"

#include "net-features.h"

extern struct aftype ipx_aftype;

/* static int skfd = -1; */

int IPX_rinput(int action, int ext, char **args)
{

    fprintf(stderr, _("IPX: this needs to be written\n"));
    return (0);
}
#endif				/* HAVE_AFIPX */

--- NEW FILE: inet6_sr.c ---
/*
   Modifications:
   1998-07-01 - Arnaldo Carvalho de Melo - GNU gettext instead of catgets
 */

#include "config.h"

#if HAVE_AFINET6
#include <asm/types.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <resolv.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#ifdef __GLIBC__
#include <net/route.h>
#else
#include <netinet6/ipv6_route.h>	/* glibc does not have this */
#endif
#include "version.h"
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"
#include "net-features.h"



extern struct aftype inet6_aftype;

static int skfd = -1;


static int usage(void)
{
    fprintf(stderr, _("Usage: inet6_route [-vF] del Target\n"));
    fprintf(stderr, _("       inet6_route [-vF] add Target [gw Gw] [metric M] [[dev] If]\n"));
    fprintf(stderr, _("       inet6_route [-FC] flush      NOT supported\n"));
    return (E_USAGE);
}


static int INET6_setroute(int action, int options, char **args)
{
    struct in6_rtmsg rt;
    struct ifreq ifr;
    struct sockaddr_in6 sa6;
    char target[128], gateway[128] = "NONE";
    int metric, prefix_len;
    char *devname = NULL;
    char *cp;

    if (*args == NULL)
	return (usage());

    strcpy(target, *args++);
    if (!strcmp(target, "default")) {
        prefix_len = 0;
	memset(&sa6, 0, sizeof(sa6));
    } else {
        if ((cp = strchr(target, '/'))) {
	    prefix_len = atol(cp + 1);
	    if ((prefix_len < 0) || (prefix_len > 128))
		usage();
	    *cp = 0;
	} else {
	    prefix_len = 128;
	}
	if (inet6_aftype.input(1, target, (struct sockaddr *) &sa6) < 0
	    && inet6_aftype.input(0, target, (struct sockaddr *) &sa6) < 0) {
	    inet6_aftype.herror(target);
	    return (1);
	}
    }

    /* Clean out the RTREQ structure. */
    memset((char *) &rt, 0, sizeof(struct in6_rtmsg));

    memcpy(&rt.rtmsg_dst, sa6.sin6_addr.s6_addr, sizeof(struct in6_addr));

    /* Fill in the other fields. */
    rt.rtmsg_flags = RTF_UP;
    if (prefix_len == 128)
	rt.rtmsg_flags |= RTF_HOST;
    rt.rtmsg_metric = 1;
    rt.rtmsg_dst_len = prefix_len;

    while (*args) {
	if (!strcmp(*args, "metric")) {

	    args++;
	    if (!*args || !isdigit(**args))
		return (usage());
	    metric = atoi(*args);
	    rt.rtmsg_metric = metric;
	    args++;
	    continue;
	}
	if (!strcmp(*args, "gw") || !strcmp(*args, "gateway")) {
	    args++;
	    if (!*args)
		return (usage());
	    if (rt.rtmsg_flags & RTF_GATEWAY)
		return (usage());
	    strcpy(gateway, *args);
	    if (inet6_aftype.input(1, gateway,
				   (struct sockaddr *) &sa6) < 0) {
		inet6_aftype.herror(gateway);
		return (E_LOOKUP);
	    }
	    memcpy(&rt.rtmsg_gateway, sa6.sin6_addr.s6_addr,
		   sizeof(struct in6_addr));
	    rt.rtmsg_flags |= RTF_GATEWAY;
	    args++;
	    continue;
	}
	if (!strcmp(*args, "mod")) {
	    args++;
	    rt.rtmsg_flags |= RTF_MODIFIED;
	    continue;
	}
	if (!strcmp(*args, "dyn")) {
	    args++;
	    rt.rtmsg_flags |= RTF_DYNAMIC;
	    continue;
	}
	if (!strcmp(*args, "device") || !strcmp(*args, "dev")) {
	    args++;
	    if (!*args)
		return (usage());
	} else if (args[1])
	    return (usage());

	devname = *args;
	args++;
    }

    /* Create a socket to the INET6 kernel. */
    if ((skfd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
	perror("socket");
	return (E_SOCK);
    }
    if (devname) {
	memset(&ifr, 0, sizeof(ifr));
	strcpy(ifr.ifr_name, devname);

	if (ioctl(skfd, SIOGIFINDEX, &ifr) < 0) {
	    perror("SIOGIFINDEX");
	    return (E_SOCK);
	}
	rt.rtmsg_ifindex = ifr.ifr_ifindex;
    } else
	rt.rtmsg_ifindex = 0;

    /* Tell the kernel to accept this route. */
    if (action == RTACTION_DEL) {
	if (ioctl(skfd, SIOCDELRT, &rt) < 0) {
	    perror("SIOCDELRT");
	    close(skfd);
	    return (E_SOCK);
	}
    } else {
	if (ioctl(skfd, SIOCADDRT, &rt) < 0) {
	    perror("SIOCADDRT");
	    close(skfd);
	    return (E_SOCK);
	}
    }

    /* Close the socket. */
    (void) close(skfd);
    return (0);
}

int INET6_rinput(int action, int options, char **args)
{
    if (action == RTACTION_FLUSH) {
	fprintf(stderr, _("Flushing `inet6' routing table not supported\n"));
	return (usage());
    }
    if ((*args == NULL) || (action == RTACTION_HELP))
	return (usage());

    return (INET6_setroute(action, options, args));
}
#endif				/* HAVE_AFINET6 */

--- NEW FILE: arcnet.c ---
/*
 * lib/arcnet.c       This file contains an implementation of the "ARCnet"
 *              support functions for the NET-2 base distribution.
 *
 * Version:     $Id: arcnet.c,v 1.2 2006-08-31 09:32:17 dslinux_amadeus Exp $
 *
 * Author:      Fred N. van Kempen, <waltje at uwalt.nl.mugnet.org>
 *              Copyright 1993 MicroWalt Corporation
 *
 *              This program 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 of the License, or  (at
 *              your option) any later version.
 */
#include "config.h"

#if HAVE_HWARC
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if_arp.h>
#include <linux/if_ether.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"
#include "util.h"

extern struct hwtype arcnet_hwtype;


/* Display an ARCnet address in readable format. */
static char *pr_arcnet(unsigned char *ptr)
{
    static char buff[64];

    snprintf(buff, sizeof(buff), "%02X", (ptr[0] & 0377));
    return (buff);
}


/* Input an ARCnet address and convert to binary. */
static int in_arcnet(char *bufp, struct sockaddr *sap)
{
    unsigned char *ptr;
    char c, *orig;
    int i, val;

    sap->sa_family = arcnet_hwtype.type;
    ptr = sap->sa_data;

    i = 0;
    orig = bufp;
    while ((*bufp != '\0') && (i < 1)) {
	val = 0;
	c = *bufp++;
	if (isdigit(c))
	    val = c - '0';
	else if (c >= 'a' && c <= 'f')
	    val = c - 'a' + 10;
	else if (c >= 'A' && c <= 'F')
	    val = c - 'A' + 10;
	else {
#ifdef DEBUG
	    fprintf(stderr, _("in_arcnet(%s): invalid arcnet address!\n"), orig);
#endif
	    errno = EINVAL;
	    return (-1);
	}
	val <<= 4;
	c = *bufp++;
	if (isdigit(c))
	    val |= c - '0';
	else if (c >= 'a' && c <= 'f')
	    val |= c - 'a' + 10;
	else if (c >= 'A' && c <= 'F')
	    val |= c - 'A' + 10;
	else {
#ifdef DEBUG
	    fprintf(stderr, _("in_arcnet(%s): invalid arcnet address!\n"), orig);
#endif
	    errno = EINVAL;
	    return (-1);
	}
	*ptr++ = (unsigned char) (val & 0377);
	i++;

	/* We might get a semicolon here - not required. */
	if (*bufp == ':') {
	    if (i == ETH_ALEN) {
#ifdef DEBUG
		fprintf(stderr, _("in_arcnet(%s): trailing : ignored!\n"),
			orig)
#endif
		    ;		/* nothing */
	    }
	    bufp++;
	}
    }

    /* That's it.  Any trailing junk? */
    if ((i == ETH_ALEN) && (*bufp != '\0')) {
#ifdef DEBUG
	fprintf(stderr, _("in_arcnet(%s): trailing junk!\n"), orig);
	errno = EINVAL;
	return (-1);
#endif
    }
#ifdef DEBUG
    fprintf(stderr, "in_arcnet(%s): %s\n", orig, pr_arcnet(sap->sa_data));
#endif

    return (0);
}


struct hwtype arcnet_hwtype =
{
    "arcnet", NULL, /*"2.5Mbps ARCnet", */ ARPHRD_ARCNET, 1,
    pr_arcnet, in_arcnet, NULL
};


#endif				/* HAVE_HWARC */

--- NEW FILE: nstrcmp.c ---
/* Copyright 1998 by Andi Kleen. Subject to the GPL. */
/* $Id: nstrcmp.c,v 1.2 2006-08-31 09:32:18 dslinux_amadeus Exp $ */ 
#include <ctype.h>
#include <stdlib.h>
#include "util.h"

/* like strcmp(), but knows about numbers */
int nstrcmp(const char *astr, const char *b)
{
    const char *a = astr;

    while (*a == *b) {
	if (*a == '\0')
	    return 0;
	a++;
	b++;
    }
    if (isdigit(*a)) {
	if (!isdigit(*b))
	    return -1;
	while (a > astr) {
	    a--;
	    if (!isdigit(*a)) {
		a++;
		break;
	    }
	    if (!isdigit(*b))
		return -1;
	    b--;
	}
	return atoi(a) > atoi(b) ? 1 : -1;
    }
    return *a - *b;
}

--- NEW FILE: x25_gr.c ---
/*
 * lib/x25_gr.c	This file contains an implementation of the "X.25"
 *		route print support functions.
 *
 * Version:	lib/x25_gr.c	1.00	08/15/98
 *
 * Author:	Stephane Fillod, <sfillod at charybde.gyptis.frmug.org>
 * 		based on ax25_gr.c by:
 *		Bernd Eckenfels, <ecki at lina.inka.de>
 *		Copyright 1999 Bernd Eckenfels, Germany
 *		base on Code from Jonathan Naylor <jsn at Cs.Nott.AC.UK>
 *
 *		This program 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 of the License, or  (at
 *		your option) any later version.
 */
#include "config.h"

#if HAVE_AFX25
#if 0
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <linux/x25.h>
#include <linux/if_arp.h>	/* ARPHRD_X25 */
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include "net-support.h"
#include "pathnames.h"
#define  EXTERN
#if 0
#include "net-locale.h"
#endif
#include "intl.h"

/* is in net/x25.h, not in the public header file linux/x25.h. Why?*/
#ifndef X25_ADDR_LEN
#define X25_ADDR_LEN 16
#endif

int X25_rprint(int options)
{
	FILE *f=fopen(_PATH_PROCNET_X25_ROUTE, "r");
	char buffer[256];
	char *p;
	int  digits;

	if(f==NULL)
	{
		printf( _("X.25 not configured in this system.\n")); /* xxx */
		return 1;
	}
	printf( _("Kernel X.25 routing table\n")); /* xxx */
	printf( _("Destination          Iface\n")); /* xxx */
	fgets(buffer,256,f);
	while(fgets(buffer,256,f))
	{
		p = strchr(buffer,'\n');
		if (p)
			*p=0;

		buffer[24]=0;
		buffer[35]=0;
		digits=atoi(buffer+17);
		if (digits < 0 || digits > 15)
			digits=15;
		buffer[digits]=0;
		if (digits == 0)
			printf("*                    %-5s\n", buffer+25);
		else
			printf("%s/%*d   %-5s\n",
				buffer,digits-17,digits,buffer+25);
	}
	fclose(f);
	return 0;
}

#endif	/* HAVE_AFX25 */

--- NEW FILE: x25.c ---
/*
 * lib/x25.c	This file contains an implementation of the "X.25"
 *		support functions for the NET-3 base distribution.
 *
 * Version:	@(#)x25.c	1.00	08/15/98
 *
 * Author:	Stephane Fillod, <sfillod at charybde.gyptis.frmug.org>
 *		based on ax25.c by:
 * 		Fred N. van Kempen, <waltje at uwalt.nl.mugnet.org>
 *		Copyright 1993 MicroWalt Corporation
 *
 *		This program 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 of the License, or  (at
 *		your option) any later version.
 */
#include "config.h"

#if HAVE_AFX25 || HAVE_HWX25
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <linux/x25.h>
#include <net/if_arp.h>		/* ARPHRD_X25 */
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include "net-support.h"
#include "pathnames.h"
#define  EXTERN
#if 0
#include "net-locale.h"
#endif
#include "intl.h"

static char X25_errmsg[128];


extern struct aftype x25_aftype;

/* is in net/x25.h, not in the public header file linux/x25.h. Why?*/
#ifndef X25_ADDR_LEN
#define X25_ADDR_LEN 16
#endif


static char *
X25_print(unsigned char *ptr)
{
  static char buff[X25_ADDR_LEN+1];

  strncpy(buff, ptr, X25_ADDR_LEN);
  buff[X25_ADDR_LEN] = '\0';
  return(buff);

}


/* Display an X.25 socket address. */
static char *
X25_sprint(struct sockaddr *sap, int numeric)
{
  if (sap->sa_family == 0xFFFF || sap->sa_family == 0)
    return( _("[NONE SET]"));
  return(X25_print(((struct sockaddr_x25 *)sap)->sx25_addr.x25_addr));
}


/*
 * return the sigdigits of the address
 */
static int
X25_input(int type, char *bufp, struct sockaddr *sap)
{
  unsigned char *ptr;
  char *p;
  unsigned int sigdigits;

  sap->sa_family = x25_aftype.af;
  ptr = ((struct sockaddr_x25 *)sap)->sx25_addr.x25_addr;


  /* Address the correct length ? */
  if (strlen(bufp)>18) {
        strcpy(X25_errmsg, _("Address can't exceed eighteen digits with sigdigits"));
#ifdef DEBUG
        fprintf(stderr, "x25_input(%s): %s !\n", X25_errmsg, orig);
#endif
        errno = EINVAL;
        return(-1);
  }


  if ((p = strchr(bufp, '/')) != NULL) {
        *p = '\0';
        sigdigits = atoi(p + 1);
  } else {
        sigdigits = strlen(bufp);
  }

  if (strlen(bufp) < 1 || strlen(bufp) > 15 || sigdigits > strlen(bufp)) {
	*p = '/';
        strcpy(X25_errmsg, _("Invalid address"));
#ifdef DEBUG
        fprintf(stderr, "x25_input(%s): %s !\n", X25_errmsg, orig);
#endif
        errno = EINVAL;
        return(-1);
  }

  strncpy(ptr, bufp, sigdigits+1);

  /* All done. */
#ifdef DEBUG
  fprintf(stderr, "x25_input(%s): ", orig);
  for (i = 0; i < sizeof(x25_address); i++)
	fprintf(stderr, "%02X ", sap->sa_data[i] & 0377);
  fprintf(stderr, "\n");
#endif

  return sigdigits;
}


/* Display an error message. */
static void
X25_herror(char *text)
{
  if (text == NULL) fprintf(stderr, "%s\n", X25_errmsg);
    else fprintf(stderr, "%s: %s\n", text, X25_errmsg);
}


static int
X25_hinput(char *bufp, struct sockaddr *sap)
{
  if (X25_input(0, bufp, sap) < 0) return(-1);
  sap->sa_family = ARPHRD_X25;
  return(0);
}


struct hwtype x25_hwtype = {
  "x25",	NULL, /*"CCITT X.25",*/		ARPHRD_X25,	X25_ADDR_LEN,
  X25_print,	X25_hinput,	NULL
};

struct aftype x25_aftype =
{   
    "x25", NULL, /*"CCITT X.25", */ AF_X25, X25_ADDR_LEN,
    X25_print, X25_sprint, X25_input, X25_herror,
    X25_rprint, X25_rinput, NULL /* getmask */,
    -1,
    "/proc/net/x25"
};


#endif	/* HAVE_xxX25 */

--- NEW FILE: util-ank.c ---
/*
 * utils.c
 *
 *		This program 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 of the License, or (at your option) any later version.
 *
 * Authors:	Alexey Kuznetsov, <kuznet at ms2.inr.ac.ru>
 *
 *
 * Changes:
 *
 * Rani Assaf <rani at magic.metawire.com> 980929:	resolve addresses
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <syslog.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <resolv.h>
#include <limits.h>

#include "intl.h"
#include "util-ank.h"

#ifndef AF_INET6
#define AF_INET6	10
#endif

int scan_number(char *arg, unsigned *val)
{
	unsigned long res;
	char *ptr;

	if (!arg || !*arg)
		return -1;
	res = strtoul(arg, &ptr, 0);
	if (!ptr || ptr == arg || *ptr || res > UINT_MAX)
		return -1;
	*val = res;
	return 0;
}

int get_integer(int *val, char *arg, int base)
{
	long res;
	char *ptr;

	if (!arg || !*arg)
		return -1;
	res = strtol(arg, &ptr, base);
	if (!ptr || ptr == arg || *ptr || res > INT_MAX || res < INT_MIN)
		return -1;
	*val = res;
	return 0;
}

int get_unsigned(unsigned *val, char *arg, int base)
{
	unsigned long res;
	char *ptr;

	if (!arg || !*arg)
		return -1;
	res = strtoul(arg, &ptr, base);
	if (!ptr || ptr == arg || *ptr || res > UINT_MAX)
		return -1;
	*val = res;
	return 0;
}

int get_u32(__u32 *val, char *arg, int base)
{
	unsigned long res;
	char *ptr;

	if (!arg || !*arg)
		return -1;
	res = strtoul(arg, &ptr, base);
	if (!ptr || ptr == arg || *ptr || res > 0xFFFFFFFFUL)
		return -1;
	*val = res;
	return 0;
}

int get_u16(__u16 *val, char *arg, int base)
{
	unsigned long res;
	char *ptr;

	if (!arg || !*arg)
		return -1;
	res = strtoul(arg, &ptr, base);
	if (!ptr || ptr == arg || *ptr || res > 0xFFFF)
		return -1;
	*val = res;
	return 0;
}

int get_u8(__u8 *val, char *arg, int base)
{
	unsigned long res;
	char *ptr;

	if (!arg || !*arg)
		return -1;
	res = strtoul(arg, &ptr, base);
	if (!ptr || ptr == arg || *ptr || res > 0xFF)
		return -1;
	*val = res;
	return 0;
}

int get_s16(__s16 *val, char *arg, int base)
{
	long res;
	char *ptr;

	if (!arg || !*arg)
		return -1;
	res = strtol(arg, &ptr, base);
	if (!ptr || ptr == arg || *ptr || res > 0x7FFF || res < -0x8000)
		return -1;
	*val = res;
	return 0;
}

int get_s8(__s8 *val, char *arg, int base)
{
	long res;
	char *ptr;

	if (!arg || !*arg)
		return -1;
	res = strtol(arg, &ptr, base);
	if (!ptr || ptr == arg || *ptr || res > 0x7F || res < -0x80)
		return -1;
	*val = res;
	return 0;
}

int get_addr_1(inet_prefix *addr, char *name, int family)
{
	char *cp;
	unsigned char *ap = (unsigned char*)addr->data;
	int i;

	memset(addr, 0, sizeof(*addr));

	if (strcmp(name, "default") == 0 || strcmp(name, "any") == 0) {
		addr->family = family;
		addr->bytelen = (family == AF_INET6 ? 16 : 4);
		addr->bitlen = -1;
		return 0;
	}

	if (strchr(name, ':')) {
		addr->family = AF_INET6;
		if (family != AF_UNSPEC && family != AF_INET6)
			return -1;
		if (inet_pton(AF_INET6, name, addr->data) <= 0)
			return -1;
		addr->bytelen = 16;
		addr->bitlen = -1;
		return 0;
	}

	addr->family = AF_INET;
	if (family != AF_UNSPEC && family != AF_INET)
		return -1;
	addr->bytelen = 4;
	addr->bitlen = -1;
	for (cp=name, i=0; *cp; cp++) {
		if (*cp <= '9' && *cp >= '0') {
			ap[i] = 10*ap[i] + (*cp-'0');
			continue;
		}
		if (*cp == '.' && ++i <= 3)
			continue;
		return -1;
	}
	return 0;
}

int get_prefix_1(inet_prefix *dst, char *arg, int family)
{
	int err;
	unsigned plen;
	char *slash;

	memset(dst, 0, sizeof(*dst));

	if (strcmp(arg, "default") == 0 || strcmp(arg, "any") == 0) {
		dst->family = family;
		dst->bytelen = 0;
		dst->bitlen = 0;
		return 0;
	}

	slash = strchr(arg, '/');
	if (slash)
		*slash = 0;
	err = get_addr_1(dst, arg, family);
	if (err == 0) {
		dst->bitlen = (dst->family == AF_INET6 ? 128 : 32);
		if (slash) {
			if (scan_number(slash+1, &plen) || plen > dst->bitlen) {
				err = -1;
				goto done;
			}
			dst->bitlen = plen;
		}
	}
done:
	if (slash)
		*slash = '/';
	return err;
}

int get_addr(inet_prefix *dst, char *arg, int family)
{
	if (get_addr_1(dst, arg, family)) {
		fprintf(stderr, _("ip: %s is invalid inet address\n"), arg);
		exit(1);
	}
	return 0;
}

int get_prefix(inet_prefix *dst, char *arg, int family)
{
	if (get_prefix_1(dst, arg, family)) {
		fprintf(stderr, _("ip: %s is invalid inet prefix\n"), arg);
		exit(1);
	}
	return 0;
}

__u32 get_addr32(char *name)
{
	inet_prefix addr;
	if (get_addr_1(&addr, name, AF_INET)) {
		fprintf(stderr, _("ip: %s is invalid IPv4 address\n"), name);
		exit(1);
	}
	return addr.data[0];
}

void invarg(char *msg)
{
	fprintf(stderr, _("ip: argument is wrong: %s\n"), msg);
	exit(1);
}

int matches(char *cmd, char *pattern)
{
	int len = strlen(cmd);
	if (len > strlen(pattern))
		return -1;
	return memcmp(pattern, cmd, len);
}

int inet_addr_match(inet_prefix *a, inet_prefix *b, int bits)
{
	__u32 *a1 = a->data;
	__u32 *a2 = b->data;
	int words = bits >> 0x05;

	bits &= 0x1f;

	if (words)
		if (memcmp(a1, a2, words << 2))
			return -1;

	if (bits) {
		__u32 w1, w2;
		__u32 mask;

		w1 = a1[words];
		w2 = a2[words];

		mask = htonl((0xffffffff) << (0x20 - bits));

		if ((w1 ^ w2) & mask)
			return 1;
	}

	return 0;
}

const char *format_host(int af, void *addr, __u8 *abuf, int alen)
{
#ifdef RESOLVE_HOSTNAMES
	if (resolve_hosts) {
		int addrlen = 0;
		struct hostent *h_ent;
		switch (af) {
		case AF_INET:
			addrlen = 4;
			break;
		case AF_INET6:
			addrlen = 16;
			break;
		}
		if (addrlen &&
		    (h_ent = gethostbyaddr(addr, addrlen, af)) != NULL) {
			snprintf(abuf, alen-1, "%s", h_ent->h_name);
			return abuf;
		}
	}
#endif
	return inet_ntop(af, addr, abuf, alen);
}

--- NEW FILE: setroute.c ---
/*
 * lib/setroute.c     This file contains a small interface function to
 *                      use the AF specific input routine for the routing
 *                      table.
 *
 * NET-LIB      A collection of functions used from the base set of the
 *              NET-3 Networking Distribution for the LINUX operating
 *              system. (net-tools, net-drivers)
 *
 * Version:     $Id: setroute.c,v 1.2 2006-08-31 09:32:19 dslinux_amadeus Exp $
 *
 * Author:      Bernd 'eckes' Eckenfels <net-tools at lina.inka.de>
 *              Copyright 1999 Bernd Eckenfels, Germany
 *
 * Modifications:
 *
 *960221 {0.01} Bernd Eckenfels:        generated from getroute.c
 *960413 {0.02} Bernd Eckenfels:        new RTACTION support
 *960809        Frank Strauss:          INET6
 *
 *              This program 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 of the License, or  (at
 *              your option) any later version.
 */
#include <stdio.h>
#include <string.h>
#include "net-support.h"
#include "pathnames.h"
#include "version.h"
#include "config.h"
#include "intl.h"

extern struct aftype unspec_aftype;
extern struct aftype unix_aftype;
extern struct aftype inet_aftype;
extern struct aftype inet6_aftype;
extern struct aftype ax25_aftype;
extern struct aftype netrom_aftype;
extern struct aftype ipx_aftype;
extern struct aftype ddp_aftype;
extern struct aftype x25_aftype;

void setroute_init(void)
{
#if HAVE_AFINET
    inet_aftype.rinput = INET_rinput;
#endif
#if HAVE_AFINET6
    inet6_aftype.rinput = INET6_rinput;
#endif
#if HAVE_AFNETROM
    netrom_aftype.rinput = NETROM_rinput;
#endif
#if HAVE_AFIPX
    ipx_aftype.rinput = IPX_rinput;
#endif
#if HAVE_AFX25
    x25_aftype.rinput = X25_rinput;
#endif
#if 0
#if HAVE_AFAX25
    ax25_aftype.rinput = AX25_rinput;
#endif
#if HAVE_AFATALK
    ddp_aftype.rinput = DDP_rinput;
#endif
#endif
}


int route_edit(int action, const char *afname, int options, char **argv)
{
    struct aftype *ap;

    ap = get_aftype(afname);

    if (!ap) {
	fprintf(stderr, _("Address family `%s' not supported.\n"), afname);
	return (E_OPTERR);
    }
    if (!ap->rinput) {
	fprintf(stderr, _("No routing for address family `%s'.\n"), ap->name);
	return (E_OPTERR);
    }
    return (ap->rinput(action, options, argv));
}

--- NEW FILE: irda.c ---
/*********************************************************************
 *                
 * Filename:      irda.c
 * Version:       0.1
 * Description:   A first attempt to make ifconfig understand IrDA
 * Status:        Experimental.
 * Author:        Dag Brattli <dagb at cs.uit.no>
 * Created at:    Wed Apr 21 09:03:09 1999
 * Modified at:   Wed Apr 21 09:17:05 1999
 * Modified by:   Dag Brattli <dagb at cs.uit.no>
 * 
 *     This program 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 of 
 *     the License, or (at your option) any later version.
 * 
 *     This program 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 this program; if not, write to the Free Software 
 *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
 *     MA 02111-1307 USA
 *     
 ********************************************************************/

#include "config.h"

#if HAVE_AFIRDA || HAVE_HWIRDA
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if_arp.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"
#include "util.h"

/* Probably not a good idea to include <linux/if_arp.h> */
#ifndef ARPHRD_IRDA
#define ARPHRD_IRDA 783
#endif

/*
 * Function irda_print (ptr)
 *
 *    Print hardware address of interface
 *
 */
static char *irda_print(unsigned char *ptr)
{
    static char buff[8];

    sprintf(&buff[strlen(buff)], "%02x:%02x:%02x:%02x", ptr[3], ptr[2], 
	    ptr[1], ptr[0]);

    return (buff);
}

struct hwtype irda_hwtype =
{
     "irda", NULL, ARPHRD_IRDA, 2,
     irda_print, NULL, NULL, 0
};

#endif				/* HAVE_xxIRDA */

--- NEW FILE: activate.c ---
/*
 * lib/activate.c     This file contains a small interface function to
 *                      use the HW specific activate routines for line
 *                      disciplines
 *
 * NET-LIB      A collection of functions used from the base set of the
 *              NET-3 Networking Distribution for the LINUX operating
 *              system. (net-tools, net-drivers)
 *
 * Version:     $Id: activate.c,v 1.2 2006-08-31 09:32:17 dslinux_amadeus Exp $
 *
 * Author:      Bernd 'eckes' Eckenfels <net-tools at lina.inka.de>
 *              Copyright 1996 Bernd Eckenfels, Germany
 *
 * Modifications:
 *
 *960322 {0.01} Bernd Eckenfels:        creation
 *980411 {0.01i} Arnaldo Carvalho:      i18n: now uses gettext
 *
 *              This program 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 of the License, or  (at
 *              your option) any later version.
 */
#include <stdio.h>
#include <string.h>
#include "net-support.h"
#include "pathnames.h"
#include "version.h"
#include "config.h"
#include "intl.h"

extern struct hwtype slip_hwtype;
extern struct hwtype cslip_hwtype;
extern struct hwtype slip6_hwtype;
extern struct hwtype cslip6_hwtype;
extern struct hwtype adaptive_hwtype;
extern struct hwtype ppp_hwtype;

extern int SLIP_activate(int fd);
extern int CSLIP_activate(int fd);
extern int SLIP6_activate(int fd);
extern int CSLIP6_activate(int fd);
extern int ADAPTIVE_activate(int fd);
extern int PPP_activate(int fd);

void activate_init(void)
{
#if HAVE_HWSLIP
    slip_hwtype.activate = SLIP_activate;
    cslip_hwtype.activate = CSLIP_activate;
    slip6_hwtype.activate = SLIP6_activate;
    cslip6_hwtype.activate = CSLIP6_activate;
    adaptive_hwtype.activate = ADAPTIVE_activate;
#endif
#if HAVE_HWPPP
    ppp_hwtype.activate = PPP_activate;
#endif
}

int activate_ld(const char *hwname, int fd)
{
    struct hwtype *hw;

    hw = get_hwtype(hwname);

    if (!hw) {
	fprintf(stderr, _("Hardware type `%s' not supported.\n"), hwname);
	return (E_NOSUPP);
    }
    if (!hw->activate) {
	fprintf(stderr, _("Cannot change line discipline to `%s'.\n"), hw->name);
	return (E_OPTERR);
    }
    return (hw->activate(fd));
}

--- NEW FILE: tunnel.c ---
/*
 *    Tunnel.c, Alan Cox 1995.
 *
 */

#include "config.h"

#if HAVE_HWTUNNEL
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if_arp.h>
#include <linux/if_ether.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include "net-support.h"
#include "pathnames.h"

extern struct hwtype ether_hwtype;

static char *pr_tunnel(unsigned char *ptr)
{
    return ("");
}


static int in_tunnel(char *bufp, struct sockaddr *sap)
{
    return (-1);
}


struct hwtype tunnel_hwtype =
{
    "tunnel", NULL, /*"IPIP Tunnel", */ ARPHRD_TUNNEL, 0,
    pr_tunnel, in_tunnel, NULL, 0
};


#endif				/* HAVE_HWTUNNEL */

--- NEW FILE: ipx.c ---
/*
 *            IPX protocol output functions.
 *              [Not yet input]
 *
 *                      Alan Cox  <Alan.Cox at linux.org>
 *
 *              This program 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 of the License, or  (at
 *              your option) any later version.
 * Modifications:
 * 1998-07-01 - Arnaldo Carvalho de Melo - GNU gettext instead of catgets,
 *                                         snprintf instead of sprintf
 */
#include "config.h"

#if HAVE_AFIPX
#include <asm/types.h>
#include <sys/types.h>
#include <sys/socket.h>
#if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1)
#include <netipx/ipx.h>
#else
#include "ipx.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include "version.h"
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"
#include "util.h"

#if (IPX_NODE_LEN != 6)
#error "IPX_NODE_LEN != 6"
#endif

/* Display a ipx domain address. */
static char *IPX_print(unsigned char *ptr)
{
    static char buff[64];
    struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) (ptr - 2);
    int t;


    for (t = IPX_NODE_LEN; t; t--)
	if (sipx->sipx_node[t - 1])
	    break;

    if (t && ntohl(sipx->sipx_network))
	snprintf(buff, sizeof(buff), "%08lX:%02X%02X%02X%02X%02X%02X",
		 (long int) ntohl(sipx->sipx_network),
		 (int) sipx->sipx_node[0], (int) sipx->sipx_node[1],
		 (int) sipx->sipx_node[2], (int) sipx->sipx_node[3],
		 (int) sipx->sipx_node[4], (int) sipx->sipx_node[5]);
    else if (!t && ntohl(sipx->sipx_network))
	snprintf(buff, sizeof(buff), "%08lX", (long int) ntohl(sipx->sipx_network));
    else if (t && !ntohl(sipx->sipx_network))
	snprintf(buff, sizeof(buff), "%02X%02X%02X%02X%02X%02X",
		 (int) sipx->sipx_node[0], (int) sipx->sipx_node[1],
		 (int) sipx->sipx_node[2], (int) sipx->sipx_node[3],
		 (int) sipx->sipx_node[4], (int) sipx->sipx_node[5]);
    else
	buff[0] = '\0';
    return (buff);
}


/* Display a ipx domain address. */
static char *IPX_sprint(struct sockaddr *sap, int numeric)
{
    static char buf[64];

    if (sap->sa_family != AF_IPX)
	return safe_strncpy(buf, _("[NONE SET]"), sizeof(buf));
    return (IPX_print(sap->sa_data));
}


static int IPX_getsock(char *bufp, struct sockaddr *sap)
{
    char *sp = bufp, *bp;
    unsigned int i;
    unsigned char val;
    struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) sap;

    sipx->sipx_port = 0;

    val = 0;
    bp = (char *) sipx->sipx_node;
    for (i = 0; i < sizeof(sipx->sipx_node); i++) {
	*sp = toupper(*sp);

	if ((*sp >= 'A') && (*sp <= 'F'))
	    bp[i] |= (int) (*sp - 'A') + 10;
	else if ((*sp >= '0') && (*sp <= '9'))
	    bp[i] |= (int) (*sp - '0');
	else
	    return (-1);

	bp[i] <<= 4;
	sp++;
	*sp = toupper(*sp);

	if ((*sp >= 'A') && (*sp <= 'F'))
	    bp[i] |= (int) (*sp - 'A') + 10;
	else if ((*sp >= '0') && (*sp <= '9'))
	    bp[i] |= (int) (*sp - '0');
	else
	    return (-1);

	sp++;
    }
    if ((memcmp(sipx->sipx_node, "\0\0\0\0\0\0\0\0", IPX_NODE_LEN) == 0) ||
	(memcmp(sipx->sipx_node, "\377\377\377\377\377\377", IPX_NODE_LEN) == 0))
	return (-1);

    return (0);
}

/* XXX define type which makes verbose format checks AF_input */

static int IPX_input(int type, char *bufp, struct sockaddr *sap)
{
    struct sockaddr_ipx *sai = (struct sockaddr_ipx *) sap;
    unsigned long netnum;
    char *ep;
    int nbo;

    sai->sipx_family = AF_IPX;
    sai->sipx_network = htonl(0);
    sai->sipx_node[0] = sai->sipx_node[1] = sai->sipx_node[2] =
	sai->sipx_node[3] = sai->sipx_node[4] = sai->sipx_node[5] = '\0';
    sai->sipx_port = 0;

    if (type & 4)
	nbo = 1;
    else
	nbo = 0;

    type &= 3;
    if (type <= 1) {
	netnum = strtoul(bufp, &ep, 16);
	if ((netnum == 0xffffffffL) || (netnum == 0L))
	    return (-1);
	if (nbo)
	    sai->sipx_network = netnum;
	else
	    sai->sipx_network = htonl(netnum);
    }
    if (type == 1) {
	if (*ep != '\0')
	    return (-2);
	return (0);
    }
    if (type == 0) {
	if (*ep != ':')
	    return (-3);
	bufp = ep + 1;
    }
    return (IPX_getsock(bufp, sap));
}


struct aftype ipx_aftype =
{
    "ipx", NULL, /*"IPX", */ AF_IPX, 0,
    IPX_print, IPX_sprint, IPX_input, NULL,
    NULL /*IPX_rprint */ , NULL, NULL,
    -1,
    "/proc/net/ipx"
};

#endif

--- NEW FILE: sockets.c ---
/* sockets.c. Rewriten by Andi Kleen. Subject to the GPL. */

/* philb 14/11/98: we now stash the socket file descriptor inside
   the `aftype' structure rather than keeping it in a pile of separate
   variables.  This is necessary so that "ifconfig eth0 broadcast ..."
   issues ioctls to the right socket for the address family in use;
   picking one at random doesn't always work.  */

#include <sys/socket.h>
#include <stdio.h>
#include <unistd.h>

#include "config.h"
#include "sockets.h"
#include "intl.h"
#include "util.h"
#include "net-support.h"

int skfd = -1;			/* generic raw socket desc.     */

int sockets_open(int family)
{
    struct aftype **aft;
    int sfd = -1;
    static int force = -1;

    if (force < 0) {
	force = 0;
	if (kernel_version() < KRELEASE(2, 1, 0))
	    force = 1;
	if (access("/proc/net", R_OK))
	    force = 1;
    }
    for (aft = aftypes; *aft; aft++) {
	struct aftype *af = *aft;
	int type = SOCK_DGRAM;
	if (af->af == AF_UNSPEC)
	    continue;
	if (family && family != af->af)
	    continue;
	if (af->fd != -1) {
	    sfd = af->fd;
	    continue;
	}
	/* Check some /proc file first to not stress kmod */
	if (!family && !force && af->flag_file) {
	    if (access(af->flag_file, R_OK))
		continue;
	}
#if HAVE_AFNETROM
	if (af->af == AF_NETROM)
	    type = SOCK_SEQPACKET;
#endif
#if HAVE_AFX25
       if (af->af == AF_X25)
           type = SOCK_SEQPACKET;
#endif
	af->fd = socket(af->af, type, 0);
	if (af->fd >= 0)
	    sfd = af->fd;
    }
    if (sfd < 0)
	fprintf(stderr, _("No usable address families found.\n"));
    return sfd;
}

--- NEW FILE: masq_info.c ---
/*
 * lib/masq_info.c    This file contains a the functio masq_info
 *                      to print a table of current masquerade connections.
 *
 * NET-LIB      A collection of functions used from the base set of the
 *              NET-3 Networking Distribution for the LINUX operating
 *              system. (net-tools, net-drivers)
 *
 * Version:     $Id: masq_info.c,v 1.2 2006-08-31 09:32:18 dslinux_amadeus Exp $
 *
 * Author:      Bernd 'eckes' Eckenfels <net-tools at lina.inka.de>
 *              Copyright 1999 Bernd Eckenfels, Germany
 *
 * Modifications:
 *
 *960217 {0.01} Bernd Eckenfels:        creatin from the code of
 *                                      Jos Vos' ipfwadm 2.0beta1
 *950218 {0.02} Bernd Eckenfels:        <linux/if.h> added
 *
 *980405 {0.03} Arnaldo Carvalho:       i18n CATGETS -> gettext
 *
 *              This program 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 of the License, or  (at
 *              your option) any later version.
 */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <unistd.h>
#include "net-support.h"
#include "pathnames.h"
#include "version.h"
#include "config.h"
#include "intl.h"
#include "net-features.h"

#if HAVE_FW_MASQUERADE

struct masq {
    unsigned long expires;	/* Expiration timer */
    char *proto;		/* Which protocol are we talking? */
    struct sockaddr_in src, dst;	/* Source and destination IP addresses */
    unsigned short sport, dport;	/* Source and destination ports */
    unsigned short mport;	/* Masqueraded port */
    unsigned long initseq;	/* Add delta from this seq. on */
    short delta;		/* Delta in sequence numbers */
    short pdelta;		/* Delta in sequence numbers before last */
};

static struct aftype *ap;	/* current address family       */
static int has_pdelta;

static void print_masq(struct masq *ms, int numeric_host, int numeric_port,
		       int ext)
{
    unsigned long minutes, seconds, sec100s;

    printf("%-4s", ms->proto);

    sec100s = ms->expires % 100L;
    seconds = (ms->expires / 100L) % 60;
    minutes = ms->expires / 6000L;

    printf("%3ld:%02ld.%02ld ", minutes, seconds, sec100s);

    if (ext > 1) {
	if (has_pdelta)
	    printf("%10lu %5hd %5hd ", ms->initseq,
		   ms->delta, ms->pdelta);
	else
	    printf("%10lu %5hd     - ", ms->initseq,
		   ms->delta);
    }
    printf("%-20s ", ap->sprint((struct sockaddr *) &(ms->src), numeric_host));
    printf("%-20s ", ap->sprint((struct sockaddr *) &(ms->dst), numeric_host));

    printf("%s -> ", get_sname(ms->sport, ms->proto, numeric_port));
    printf("%s", get_sname(ms->dport, ms->proto, numeric_port));
    printf(" (%s)\n", get_sname(ms->mport, ms->proto, numeric_port));
}


static int read_masqinfo(FILE * f, struct masq *mslist, int nmslist)
{
    int n, nread = 0;
    struct masq *ms;
    char buf[256];

    for (nread = 0; nread < nmslist; nread++) {
	ms = &mslist[nread];
	if (has_pdelta) {
	    if ((n = fscanf(f, " %s %lX:%hX %lX:%hX %hX %lX %hd %hd %lu",
			    buf,
		  (unsigned long *) &ms->src.sin_addr.s_addr, &ms->sport,
		  (unsigned long *) &ms->dst.sin_addr.s_addr, &ms->dport,
			    &ms->mport, &ms->initseq, &ms->delta,
			    &ms->pdelta, &ms->expires)) == -1)
		return nread;
	} else {
	    if ((n = fscanf(f, " %s %lX:%hX %lX:%hX %hX %lX %hd %lu",
			    buf,
		  (unsigned long *) &ms->src.sin_addr.s_addr, &ms->sport,
		  (unsigned long *) &ms->dst.sin_addr.s_addr, &ms->dport,
			    &ms->mport, &ms->initseq, &ms->delta,
			    &ms->expires)) == -1)
		return nread;
	}
	if ((has_pdelta && (n != 10)) || (!has_pdelta && (n != 9))) {
	    EINTERN("masq_info.c", "ip_masquerade format error");
	    return (-1);
	}
	ms->src.sin_family = AF_INET;
	ms->dst.sin_family = AF_INET;

	if (strcmp("TCP", buf) == 0)
	    ms->proto = "tcp";
	else if (strcmp("UDP", buf) == 0)
	    ms->proto = "udp";
	else if (strcmp("ICMP", buf) == 0)
	    ms->proto = "icmp";
	else if (strcmp("GRE", buf) == 0)
	    ms->proto = "gre";
	else if (strcmp("ESP", buf) == 0)
	    ms->proto = "esp";
	else {
	    EINTERN("masq_info.c", "ip_masquerade unknown type");
	    return (-1);
	}

	/* we always keep these addresses in network byte order */
	ms->src.sin_addr.s_addr = htonl(ms->src.sin_addr.s_addr);
	ms->dst.sin_addr.s_addr = htonl(ms->dst.sin_addr.s_addr);
	ms->sport = htons(ms->sport);
	ms->dport = htons(ms->dport);
	ms->mport = htons(ms->mport);
    }
    return nread;
}


int ip_masq_info(int numeric_host, int numeric_port, int ext)
{
    FILE *f;
    int i;
    char buf[256];
    struct masq *mslist;
    int ntotal = 0, nread;

    if (!(f = fopen(_PATH_PROCNET_IP_MASQ, "r"))) {
	if (errno != ENOENT) {
	    perror(_PATH_PROCNET_IP_MASQ);
	    return (-1);
	}
	ESYSNOT("netstat", "ip_masquerade");
	return (1);
    }
    if ((ap = get_aftype("inet")) == NULL) {
	ENOSUPP("masq_info", "AF INET");
	fclose(f);
	return (-1);
    }
    fgets(buf, sizeof(buf), f);
    has_pdelta = strstr(buf, "PDelta") ? 1 : 0;

    mslist = (struct masq *) malloc(16 * sizeof(struct masq));
    if (!mslist) {
	EINTERN("masq_info", "malloc() failed");
	fclose(f);
	return (-1);
    }
    while ((nread = read_masqinfo(f, &(mslist[ntotal]), 16)) == 16) {
	ntotal += nread;
	mslist = (struct masq *) realloc(mslist,
				    (ntotal + 16) * sizeof(struct masq));
	if (!mslist) {
	    EINTERN("masq_info", "realloc() failed");
	    fclose(f);
	    return (-1);
	}
    }
    fclose(f);

    if (nread < 0) {
	if (mslist)
	    free(mslist);
	return (-1);
    }
    ntotal += nread;

    if (ntotal > 0) {
	printf(_("IP masquerading entries\n"));
	switch (ext) {
	case 1:
	    printf(_("prot   expire source               destination          ports\n"));
	    break;
	default:
	    printf(_("prot   expire    initseq delta prevd source               destination          ports\n"));
	    break;
	}
	for (i = 0; i < ntotal; i++)
	    print_masq(&(mslist[i]), numeric_host, numeric_port, ext);
	if (mslist)
	    free(mslist);

    }
    return 0;
}
#endif

--- NEW FILE: hdlclapb.c ---
/*
 * lib/hdlclapb.c 
 *              This file contains the HDLC/LAPB support for the NET-2 base
 *              distribution.
 *
 * Version:    $Id: hdlclapb.c,v 1.2 2006-08-31 09:32:18 dslinux_amadeus Exp $
 *
 * Original Author:     
 *              Fred N. van Kempen, <waltje at uwalt.nl.mugnet.org>
 *              Copyright 1993 MicroWalt Corporation
 *
 *              Modified by Alan Cox, May 94 to cover NET-3
 *
 *              This program 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 of the License, or  (at
 *              your option) any later version.
 */
#include "config.h"

#if HAVE_HWHDLCLAPB

#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if_arp.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include "net-support.h"
#include "pathnames.h"

#ifndef ARPHRD_HDLC
#warning "No definition of ARPHRD_HDLC in <net/if_arp.h>, using private value 513"
#define ARPHRD_HDLC 513
#endif

#ifndef ARPHRD_LAPB
#warning "No definition of ARPHRD_HDLC in <net/if_arp.h>, using private value 516"
#define ARPHRD_LAPB 516
#endif

struct hwtype hdlc_hwtype =
{
    "hdlc", NULL, /*"(Cisco) HDLC", */ ARPHRD_HDLC, 0,
    NULL, NULL, NULL, 0
};
struct hwtype lapb_hwtype =
{
    "lapb", NULL, /*"LAPB", */ ARPHRD_LAPB, 0,
    NULL, NULL, NULL, 0
};

#endif				/* HAVE_HWHDLCLAPB */

--- NEW FILE: pathnames.h ---

/*
 * lib/pathnames.h    This file contains the definitions of the path 
 *                      names used by the NET-LIB.
 *
 * NET-LIB      
 *
 * Version:     lib/pathnames.h 1.37 (1997-08-23)
 *
 * Author:      Fred N. van Kempen, <waltje at uwalt.nl.mugnet.org>
 */

/* pathnames of the procfs files used by NET. */
#define _PATH_PROCNET_IGMP		"/proc/net/igmp"
#define _PATH_PROCNET_IGMP6		"/proc/net/igmp6"
#define _PATH_PROCNET_TCP		"/proc/net/tcp"
#define _PATH_PROCNET_TCP6		"/proc/net/tcp6"
#define _PATH_PROCNET_UDP		"/proc/net/udp"
#define _PATH_PROCNET_UDP6		"/proc/net/udp6"
#define _PATH_PROCNET_RAW		"/proc/net/raw"
#define _PATH_PROCNET_RAW6		"/proc/net/raw6"
#define _PATH_PROCNET_UNIX		"/proc/net/unix"
#define _PATH_PROCNET_ROUTE		"/proc/net/route"
#define _PATH_PROCNET_ROUTE6		"/proc/net/ipv6_route"
#define _PATH_PROCNET_RTCACHE		"/proc/net/rt_cache"
#define _PATH_PROCNET_AX25_ROUTE	"/proc/net/ax25_route"
#define _PATH_PROCNET_NR		"/proc/net/nr"
#define _PATH_PROCNET_NR_NEIGH		"/proc/net/nr_neigh"
#define _PATH_PROCNET_NR_NODES		"/proc/net/nr_nodes"
#define _PATH_PROCNET_ARP		"/proc/net/arp"
#define _PATH_PROCNET_AX25		"/proc/net/ax25"
#define _PATH_PROCNET_IPX		"/proc/net/ipx"
#define _PATH_PROCNET_IPX_ROUTE		"/proc/net/ipx_route"
#define _PATH_PROCNET_ATALK		"/proc/net/appletalk"
#define _PATH_PROCNET_IP_BLK		"/proc/net/ip_block"
#define _PATH_PROCNET_IP_FWD		"/proc/net/ip_forward"
#define _PATH_PROCNET_IP_ACC		"/proc/net/ip_acct"
#define _PATH_PROCNET_IP_MASQ		"/proc/net/ip_masquerade"
#define _PATH_PROCNET_NDISC		"/proc/net/ndisc"
#define _PATH_PROCNET_IFINET6		"/proc/net/if_inet6"
#define _PATH_PROCNET_DEV		"/proc/net/dev"
#define _PATH_PROCNET_RARP		"/proc/net/rarp"
#define _PATH_ETHERS			"/etc/ethers"
#define _PATH_PROCNET_ROSE_ROUTE	"/proc/net/rose_routes"
#define _PATH_PROCNET_X25              "/proc/net/x25"
#define _PATH_PROCNET_X25_ROUTE                "/proc/net/x25_routes"
#define _PATH_PROCNET_DEV_MCAST		"/proc/net/dev_mcast"

/* pathname for the netlink device */
#define _PATH_DEV_ROUTE	"/dev/route"

/* End of pathnames.h */

--- NEW FILE: rose_gr.c ---

/*
 * lib/rose_gr.c      This file contains an implementation of the "ROSE"
 *                      route print support functions.
 *
 * Version:     $Id: rose_gr.c,v 1.2 2006-08-31 09:32:19 dslinux_amadeus Exp $
 *
 * Author:      Terry Dawson, VK2KTJ, <terry at perf.no.itg.telstra.com.au>
 *              based on ax25_gr.c by:
 *              Bernd Eckenfels, <ecki at lina.inka.de>
 *              Copyright 1999 Bernd Eckenfels, Germany
 *              base on Code from Jonathan Naylor <jsn at Cs.Nott.AC.UK>
 *
 *              This program 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 of the License, or  (at
 *              your option) any later version.
 */
#include "config.h"

#if HAVE_AFROSE
#if 0
#include <sys/types.h>
#include <sys/ioctl.h>
#include <linux/rose.h>
#include <sys/socket.h>
#include <net/if_arp.h>		/* ARPHRD_ROSE */
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"

int ROSE_rprint(int options)
{
    FILE *f = NULL;
    char buffer[256];
    int use;

    f=fopen(_PATH_PROCNET_ROSE_ROUTE, "r");
    if (f == NULL) {
	perror(_PATH_PROCNET_ROSE_ROUTE);
	printf(_("ROSE not configured in this system.\n"));	/* xxx */
	return 1;
    }
    printf(_("Kernel ROSE routing table\n"));
    printf(_("Destination  Iface    Use\n"));
    fgets(buffer, 256, f);
    while (fgets(buffer, 256, f)) {
	buffer[9] = 0;
	buffer[14] = 0;
	use = atoi(buffer + 15);
	printf("%-9s    %-5s  %5d\n",
	       buffer, buffer + 10, use);
    }
    fclose(f);
    return 0;
}

#endif				/* HAVE_AFROSE */

--- NEW FILE: inet6.c ---
/*
 * lib/inet6.c        This file contains an implementation of the "INET6"
 *              support functions for the net-tools.
 *              (most of it copied from lib/inet.c 1.26).
 *
 * Version:     $Id: inet6.c,v 1.2 2006-08-31 09:32:18 dslinux_amadeus Exp $
 *
 * Author:      Fred N. van Kempen, <waltje at uwalt.nl.mugnet.org>
 *              Copyright 1993 MicroWalt Corporation
 *
 * Modified:
 *960808 {0.01} Frank Strauss :         adapted for IPv6 support
 *980701 {0.02} Arnaldo C. Melo:        GNU gettext instead of catgets
 *990824        Bernd Eckenfels:	clear members for selecting v6 address
 *
 *              This program 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 of the License, or  (at
 *              your option) any later version.
 */
#include "config.h"

#if HAVE_AFINET6
#include <asm/types.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <resolv.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include "version.h"
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"
#include "util.h"

extern int h_errno;		/* some netdb.h versions don't export this */

static int INET6_resolve(char *name, struct sockaddr_in6 *sin6)
{
    struct addrinfo req, *ai;
    int s;

    memset (&req, '\0', sizeof req);
    req.ai_family = AF_INET6;
    if ((s = getaddrinfo(name, NULL, &req, &ai))) {
	fprintf(stderr, "getaddrinfo: %s: %d\n", name, s);
	return -1;
    }
    memcpy(sin6, ai->ai_addr, sizeof(struct sockaddr_in6));

    freeaddrinfo(ai);

    return (0);
}

#ifndef IN6_IS_ADDR_UNSPECIFIED
#define IN6_IS_ADDR_UNSPECIFIED(a) \
        (((__u32 *) (a))[0] == 0 && ((__u32 *) (a))[1] == 0 && \
         ((__u32 *) (a))[2] == 0 && ((__u32 *) (a))[3] == 0)
#endif


static int INET6_rresolve(char *name, struct sockaddr_in6 *sin6, int numeric)
{
    int s;

    /* Grmpf. -FvK */
    if (sin6->sin6_family != AF_INET6) {
#ifdef DEBUG
	fprintf(stderr, _("rresolve: unsupport address family %d !\n"),
		sin6->sin6_family);
#endif
	errno = EAFNOSUPPORT;
	return (-1);
    }
    if (numeric & 0x7FFF) {
	inet_ntop(AF_INET6, &sin6->sin6_addr, name, 80);
	return (0);
    }
    if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
        if (numeric & 0x8000)
	    strcpy(name, "default");
	else
	    strcpy(name, "*");
	return (0);
    }

    if ((s = getnameinfo((struct sockaddr *) sin6, sizeof(struct sockaddr_in6),
			 name, 255 /* !! */ , NULL, 0, 0))) {
	fputs("getnameinfo failed\n", stderr);
	return -1;
    }
    return (0);
}


static void INET6_reserror(char *text)
{
    herror(text);
}


/* Display an Internet socket address. */
static char *INET6_print(unsigned char *ptr)
{
    static char name[80];

    inet_ntop(AF_INET6, (struct in6_addr *) ptr, name, 80);
    return name;
}


/* Display an Internet socket address. */
/* dirty! struct sockaddr usually doesn't suffer for inet6 addresses, fst. */
static char *INET6_sprint(struct sockaddr *sap, int numeric)
{
    static char buff[128];

    if (sap->sa_family == 0xFFFF || sap->sa_family == 0)
	return safe_strncpy(buff, _("[NONE SET]"), sizeof(buff));
    if (INET6_rresolve(buff, (struct sockaddr_in6 *) sap, numeric) != 0)
	return safe_strncpy(buff, _("[UNKNOWN]"), sizeof(buff));
    return (buff);
}


static int INET6_getsock(char *bufp, struct sockaddr *sap)
{
    struct sockaddr_in6 *sin6;

    sin6 = (struct sockaddr_in6 *) sap;
    sin6->sin6_family = AF_INET6;
    sin6->sin6_port = 0;

    if (inet_pton(AF_INET6, bufp, sin6->sin6_addr.s6_addr) <= 0)
	return (-1);

    return 16;			/* ?;) */
}

static int INET6_input(int type, char *bufp, struct sockaddr *sap)
{
    switch (type) {
    case 1:
	return (INET6_getsock(bufp, sap));
    default:
	return (INET6_resolve(bufp, (struct sockaddr_in6 *) sap));
    }
}


struct aftype inet6_aftype =
{
    "inet6", NULL, /*"IPv6", */ AF_INET6, sizeof(struct in6_addr),
    INET6_print, INET6_sprint, INET6_input, INET6_reserror,
    INET6_rprint, INET6_rinput, NULL,

    -1,
    "/proc/net/if_inet6"
};


#endif				/* HAVE_AFINET6 */

--- NEW FILE: getargs.c ---
/*
 * lib/getargs.c      General argument parser.
 *
 * Version:     $Id: getargs.c,v 1.2 2006-08-31 09:32:18 dslinux_amadeus Exp $
 *
 * Author:      Fred N. van Kempen, <waltje at uwalt.nl.mugnet.org>
 *              Copyright 1993,1994 MicroWalt Corporation
 *
 *              This program 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 of the License, or  (at
 *              your option) any later version.
 */
#include "config.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "net-support.h"
#include "pathnames.h"


/* Split the input string into multiple fields. */
int getargs(char *string, char *arguments[])
{
    int len = strlen(string); 
    char temp[len+1];
    char *sp, *ptr;
    int i, argc;
    char want;

    /*
     * Copy the string into a buffer.  We may have to modify
     * the original string because of all the quoting...
     */
    sp = string;
    i = 0;
    strcpy(temp, string);
    ptr = temp;

    /*
     * Look for delimiters ("); if present whatever
     * they enclose will be considered one argument.
     */
    while (*ptr != '\0' && i < 31) {
	/* Ignore leading whitespace on input string. */
	while (*ptr == ' ' || *ptr == '\t')
	    ptr++;

	/* Set string pointer. */
	arguments[i++] = sp;

	/* Check for any delimiters. */
	if (*ptr == '"' || *ptr == '\'') {
	    /*
	     * Copy the string up to any whitespace OR the next
	     * delimiter. If the delimiter was escaped, skip it
	     * as it if was not there.
	     */
	    want = *ptr++;
	    while (*ptr != '\0') {
		if (*ptr == want && *(ptr - 1) != '\\') {
		    ptr++;
		    break;
		}
		*sp++ = *ptr++;
	    }
	} else {
	    /* Just copy the string up to any whitespace. */
	    while (*ptr != '\0' && *ptr != ' ' && *ptr != '\t')
		*sp++ = *ptr++;
	}
	*sp++ = '\0';

	/* Skip trailing whitespace. */
	if (*ptr != '\0') {
	    while (*ptr == ' ' || *ptr == '\t')
		ptr++;
	}
    }
    argc = i;
    while (i < 32)
	arguments[i++] = (char *) NULL;
    return (argc);
}

--- NEW FILE: fddi.c ---
/*
 * lib/fddi.c This file contains an implementation of the "FDDI"
 *              support functions.
 *
 * Version:     $Id: fddi.c,v 1.2 2006-08-31 09:32:17 dslinux_amadeus Exp $
 *
 * Author:      Lawrence V. Stefani, <stefani at lkg.dec.com>
 *
 * 1998-07-01 - Arnaldo Carvalho de Melo <acme at conectiva.com.br> GNU gettext
 *
 *              This program 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 of the License, or  (at
 *              your option) any later version.
 */
#include "config.h"

#include <features.h>

#if HAVE_HWFDDI
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if_arp.h>
#ifndef ARPHRD_FDDI
#error "No FDDI Support in your current Kernelsource Tree."
#error "Disable HW Type FDDI"
#endif
#if __GLIBC__ >= 2
#include <netinet/if_fddi.h>
#else
#include <linux/if_fddi.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"
#include "util.h"

extern struct hwtype fddi_hwtype;


/* Display an FDDI address in readable format. */
static char *pr_fddi(unsigned char *ptr)
{
    static char buff[64];

    snprintf(buff, sizeof(buff), "%02X-%02X-%02X-%02X-%02X-%02X",
	     (ptr[0] & 0377), (ptr[1] & 0377), (ptr[2] & 0377),
	     (ptr[3] & 0377), (ptr[4] & 0377), (ptr[5] & 0377)
	);
    return (buff);
}


/* Input an FDDI address and convert to binary. */
static int in_fddi(char *bufp, struct sockaddr *sap)
{
    unsigned char *ptr;
    char c, *orig;
    int i, val;

    sap->sa_family = fddi_hwtype.type;
    ptr = sap->sa_data;

    i = 0;
    orig = bufp;
    while ((*bufp != '\0') && (i < FDDI_K_ALEN)) {
	val = 0;
	c = *bufp++;
	if (isdigit(c))
	    val = c - '0';
	else if (c >= 'a' && c <= 'f')
	    val = c - 'a' + 10;
	else if (c >= 'A' && c <= 'F')
	    val = c - 'A' + 10;
	else {
#ifdef DEBUG
	    fprintf(stderr, _("in_fddi(%s): invalid fddi address!\n"), orig);
#endif
	    errno = EINVAL;
	    return (-1);
	}
	val <<= 4;
	c = *bufp++;
	if (isdigit(c))
	    val |= c - '0';
	else if (c >= 'a' && c <= 'f')
	    val |= c - 'a' + 10;
	else if (c >= 'A' && c <= 'F')
	    val |= c - 'A' + 10;
	else {
#ifdef DEBUG
	    fprintf(stderr, _("in_fddi(%s): invalid fddi address!\n"), orig);
#endif
	    errno = EINVAL;
	    return (-1);
	}
	*ptr++ = (unsigned char) (val & 0377);
	i++;

	/* We might get a semicolon here - not required. */
	if (*bufp == ':') {
	    if (i == FDDI_K_ALEN) {
#ifdef DEBUG
		fprintf(stderr, _("in_fddi(%s): trailing : ignored!\n"),
			orig)
#endif
		    ;		/* nothing */
	    }
	    bufp++;
	}
    }

    /* That's it.  Any trailing junk? */
    if ((i == FDDI_K_ALEN) && (*bufp != '\0')) {
#ifdef DEBUG
	fprintf(stderr, _("in_fddi(%s): trailing junk!\n"), orig);
	errno = EINVAL;
	return (-1);
#endif
    }
#ifdef DEBUG
    fprintf(stderr, "in_fddi(%s): %s\n", orig, pr_fddi(sap->sa_data));
#endif

    return (0);
}


struct hwtype fddi_hwtype =
{
    "fddi", NULL, /*"Fiber Distributed Data Interface (FDDI)", */ ARPHRD_FDDI, FDDI_K_ALEN,
    pr_fddi, in_fddi, NULL
};


#endif				/* HAVE_HWFDDI */

--- NEW FILE: netrom_sr.c ---
#include "config.h"

#if HAVE_AFNETROM
#include <sys/param.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
/* #include <net/route.h> realy broken */
#include <sys/ioctl.h>
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <resolv.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include "version.h"
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"
#include "net-features.h"

extern struct aftype netrom_aftype;

/* static int skfd = -1; */

/* acme: orphaned... */
#if 0
static int usage(void)
{
    fprintf(stderr, _("netrom usage\n"));

    return (E_USAGE);
}
#endif


int NETROM_rinput(int action, int ext, char **args)
{

    fprintf(stderr, _("NET/ROM: this needs to be written\n"));
    return (0);
}
#endif				/* HAVE_AFNETROM */

--- NEW FILE: hippi.c ---
/*
 * lib/hippi.c        This file contains an implementation of the "HIPPI"
 *              support functions for the NET-2 base distribution.
 *
 * Version:     $Id: hippi.c,v 1.2 2006-08-31 09:32:18 dslinux_amadeus Exp $
 *
 * Author:      Fred N. van Kempen, <waltje at uwalt.nl.mugnet.org>
 *              Copyright 1993 MicroWalt Corporation
 *
 *              Modified for HIPPI by Jes Sorensen, <Jes.Sorensen at cern.ch>
 *
 *              This program 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 of the License, or  (at
 *              your option) any later version.
 */
#include "config.h"

#if HAVE_HWHIPPI
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if_arp.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"
#include "util.h"

/*
 *    HIPPI magic constants.
 */

#define HIPPI_ALEN	6	/* Bytes in one HIPPI hw-addr        */
#ifndef ARPHRD_HIPPI
#define ARPHRD_HIPPI    780
#warning "ARPHRD_HIPPI is not defined in <net/if_arp.h>. Using private value 708"
#endif

extern struct hwtype hippi_hwtype;


/* Display an HIPPI address in readable format. */
static char *pr_hippi(unsigned char *ptr)
{
    static char buff[64];

    sprintf(buff, "%02X:%02X:%02X:%02X:%02X:%02X",
	    (ptr[0] & 0377), (ptr[1] & 0377), (ptr[2] & 0377),
	    (ptr[3] & 0377), (ptr[4] & 0377), (ptr[5] & 0377)
	);
    return (buff);
}


/* Input an HIPPI address and convert to binary. */
static int in_hippi(char *bufp, struct sockaddr *sap)
{
    unsigned char *ptr;
    char c, *orig;
    int i, val;

    sap->sa_family = hippi_hwtype.type;
    ptr = sap->sa_data;

    i = 0;
    orig = bufp;
    while ((*bufp != '\0') && (i < HIPPI_ALEN)) {
	val = 0;
	c = *bufp++;
	if (isdigit(c))
	    val = c - '0';
	else if (c >= 'a' && c <= 'f')
	    val = c - 'a' + 10;
	else if (c >= 'A' && c <= 'F')
	    val = c - 'A' + 10;
	else {
#ifdef DEBUG
	    fprintf(stderr, _("in_hippi(%s): invalid hippi address!\n"), orig);
#endif
	    errno = EINVAL;
	    return (-1);
	}
	val <<= 4;
	c = *bufp++;
	if (isdigit(c))
	    val |= c - '0';
	else if (c >= 'a' && c <= 'f')
	    val |= c - 'a' + 10;
	else if (c >= 'A' && c <= 'F')
	    val |= c - 'A' + 10;
	else {
#ifdef DEBUG
	    fprintf(stderr, _("in_hippi(%s): invalid hippi address!\n"), orig);
#endif
	    errno = EINVAL;
	    return (-1);
	}
	*ptr++ = (unsigned char) (val & 0377);
	i++;

	/* We might get a semicolon here - not required. */
	if (*bufp == ':') {
	    if (i == HIPPI_ALEN) {
#ifdef DEBUG
		fprintf(stderr, _("in_hippi(%s): trailing : ignored!\n"), orig)
#endif
		    ;		/* nothing */
	    }
	    bufp++;
	}
    }

    /* That's it.  Any trailing junk? */
    if ((i == HIPPI_ALEN) && (*bufp != '\0')) {
#ifdef DEBUG
	fprintf(stderr, _("in_hippi(%s): trailing junk!\n"), orig);
	errno = EINVAL;
	return (-1);
#endif
    }
#ifdef DEBUG
    fprintf(stderr, "in_hippi(%s): %s\n", orig, pr_hippi(sap->sa_data));
#endif

    return (0);
}


struct hwtype hippi_hwtype =
{
    "hippi", NULL, /*"HIPPI", */ ARPHRD_HIPPI, HIPPI_ALEN,
    pr_hippi, in_hippi, NULL, 0
};


#endif				/* HAVE_HWHIPPI */

--- NEW FILE: inet_sr.c ---
/*
   Modifications:
   1998-07-01 - Arnaldo Carvalho de Melo - GNU gettext instead of catgets
   1999-10-07 - Kurt Garloff		 - for -host and gws: prefer host names
						over networks (or even reject)
 */

#include "config.h"

#if HAVE_AFINET
#include <asm/types.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <net/route.h> /* realy broken */
#include <sys/ioctl.h>
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <resolv.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include "version.h"
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"
#include "net-features.h"
#include "util.h"

#if HAVE_NEW_ADDRT
#define mask_in_addr(x) (((struct sockaddr_in *)&((x).rt_genmask))->sin_addr.s_addr)
#define full_mask(x) (x)
#else
#define mask_in_addr(x) ((x).rt_genmask)
#define full_mask(x) (((struct sockaddr_in *)&(x))->sin_addr.s_addr)
#endif

extern struct aftype inet_aftype;

static int skfd = -1;


static int usage(void)
{
    fprintf(stderr, _("Usage: inet_route [-vF] del {-host|-net} Target[/prefix] [gw Gw] [metric M] [[dev] If]\n"));
    fprintf(stderr, _("       inet_route [-vF] add {-host|-net} Target[/prefix] [gw Gw] [metric M]\n"));
    fprintf(stderr, _("                              [netmask N] [mss Mss] [window W] [irtt I]\n"));
    fprintf(stderr, _("                              [mod] [dyn] [reinstate] [[dev] If]\n"));
    fprintf(stderr, _("       inet_route [-vF] add {-host|-net} Target[/prefix] [metric M] reject\n"));
    fprintf(stderr, _("       inet_route [-FC] flush      NOT supported\n"));
    return (E_USAGE);
}

static int INET_setroute(int action, int options, char **args)
{
    struct rtentry rt;
    char target[128], gateway[128] = "NONE", netmask[128] = "default";
    int xflag, isnet;

    xflag = 0;

    if (!strcmp(*args, "#net")) {
	xflag = 1;
	args++;
    } else if (!strcmp(*args, "#host")) {
	xflag = 2;
	args++;
    }
    if (*args == NULL)
	return (usage());

    safe_strncpy(target, *args++, (sizeof target));

    /* Clean out the RTREQ structure. */
    memset((char *) &rt, 0, sizeof(struct rtentry));

    /* Special hack for /prefix syntax */
    {
	union {
	    struct sockaddr_in m;
	    struct sockaddr d;
	} mask;
	int n;

	n = inet_aftype.getmask(target, &mask.d, netmask);
	if (n < 0)
	    return usage();
	else if (n)
	    rt.rt_genmask = full_mask(mask.d);
    }

    /* Prefer hostname lookup is -host flag was given */
    if ((isnet = inet_aftype.input((xflag!=2? 0: 256), target, &rt.rt_dst)) < 0) {
	inet_aftype.herror(target);
	return (1);
    }
    switch (xflag) {
    case 1:
       isnet = 1; break;
    case 2:
       isnet = 0; break;
    default:
       break;
    }

    /* Fill in the other fields. */
    rt.rt_flags = (RTF_UP | RTF_HOST);
    if (isnet)
	rt.rt_flags &= ~RTF_HOST;

    while (*args) {
	if (!strcmp(*args, "metric")) {
	    int metric;

	    args++;
	    if (!*args || !isdigit(**args))
		return (usage());
	    metric = atoi(*args);
#if HAVE_NEW_ADDRT
	    rt.rt_metric = metric + 1;
#else
	    ENOSUPP("inet_setroute", "NEW_ADDRT (metric)");
#endif
	    args++;
	    continue;
	}
	if (!strcmp(*args, "netmask")) {
	    struct sockaddr mask;

	    args++;
	    if (!*args || mask_in_addr(rt))
		return (usage());
	    safe_strncpy(netmask, *args, (sizeof netmask));
	    if ((isnet = inet_aftype.input(0, netmask, &mask)) < 0) {
		inet_aftype.herror(netmask);
		return (E_LOOKUP);
	    }
	    rt.rt_genmask = full_mask(mask);
	    args++;
	    continue;
	}
	if (!strcmp(*args, "gw") || !strcmp(*args, "gateway")) {
	    args++;
	    if (!*args)
		return (usage());
	    if (rt.rt_flags & RTF_GATEWAY)
		return (usage());
	    safe_strncpy(gateway, *args, (sizeof gateway));
	    if ((isnet = inet_aftype.input(256, gateway, &rt.rt_gateway)) < 0) {
		inet_aftype.herror(gateway);
		return (E_LOOKUP);
	    }
	    if (isnet) {
		fprintf(stderr, _("route: %s: cannot use a NETWORK as gateway!\n"),
			gateway);
		return (E_OPTERR);
	    }
	    rt.rt_flags |= RTF_GATEWAY;
	    args++;
	    continue;
	}
	if (!strcmp(*args, "mss") || !strcmp(*args,"mtu")) {
	    args++;
	    rt.rt_flags |= RTF_MSS;
	    if (!*args)
		return (usage());
	    rt.rt_mss = atoi(*args);
	    args++;
	    if (rt.rt_mss < 64 || rt.rt_mss > 65536) {
		fprintf(stderr, _("route: Invalid MSS/MTU.\n"));
		return (E_OPTERR);
	    }
	    continue;
	}
	if (!strcmp(*args, "window")) {
	    args++;
	    if (!*args)
		return (usage());
	    rt.rt_flags |= RTF_WINDOW;
	    rt.rt_window = atoi(*args);
	    args++;
	    if (rt.rt_window < 128) {
		fprintf(stderr, _("route: Invalid window.\n"));
		return (E_OPTERR);
	    }
	    continue;
	}
	if (!strcmp(*args, "irtt")) {
	    args++;
	    if (!*args)
		return (usage());
	    args++;
#if HAVE_RTF_IRTT
	    rt.rt_flags |= RTF_IRTT;
	    rt.rt_irtt = atoi(*(args - 1));
	    rt.rt_irtt *= (HZ / 100);	/* FIXME */
#if 0				/* FIXME: do we need to check anything of this? */
	    if (rt.rt_irtt < 1 || rt.rt_irtt > (120 * HZ)) {
		fprintf(stderr, _("route: Invalid initial rtt.\n"));
		return (E_OPTERR);
	    }
#endif
#else
	    ENOSUPP("inet_setroute", "RTF_IRTT");
#endif
	    continue;
	}
	if (!strcmp(*args, "reject")) {
	    args++;
#if HAVE_RTF_REJECT
	    rt.rt_flags |= RTF_REJECT;
#else
	    ENOSUPP("inet_setroute", "RTF_REJECT");
#endif
	    continue;
	}
	if (!strcmp(*args, "mod")) {
	    args++;
	    rt.rt_flags |= RTF_MODIFIED;
	    continue;
	}
	if (!strcmp(*args, "dyn")) {
	    args++;
	    rt.rt_flags |= RTF_DYNAMIC;
	    continue;
	}
	if (!strcmp(*args, "reinstate")) {
	    args++;
	    rt.rt_flags |= RTF_REINSTATE;
	    continue;
	}
	if (!strcmp(*args, "device") || !strcmp(*args, "dev")) {
	    args++;
	    if (rt.rt_dev || *args == NULL)
		return usage();
	    rt.rt_dev = *args++;
	    continue;
	}
	/* nothing matches */
	if (!rt.rt_dev) {
	    rt.rt_dev = *args++;
	    if (*args)
		return usage();	/* must be last to catch typos */
	} else
	    return usage();
    }

#if HAVE_RTF_REJECT
    if ((rt.rt_flags & RTF_REJECT) && !rt.rt_dev)
	rt.rt_dev = "lo";
#endif

    /* sanity checks.. */
    if (mask_in_addr(rt)) {
	__u32 mask = ~ntohl(mask_in_addr(rt));
	if ((rt.rt_flags & RTF_HOST) && mask != 0xffffffff) {
	    fprintf(stderr, _("route: netmask %.8x doesn't make sense with host route\n"), mask);
	    return (E_OPTERR);
	}
	if (mask & (mask + 1)) {
	    fprintf(stderr, _("route: bogus netmask %s\n"), netmask);
	    return (E_OPTERR);
	}
	mask = ((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr;
	if (mask & ~mask_in_addr(rt)) {
	    fprintf(stderr, _("route: netmask doesn't match route address\n"));
	    return (E_OPTERR);
	}
    }
    /* Fill out netmask if still unset */
    if ((action == RTACTION_ADD) && rt.rt_flags & RTF_HOST)
	mask_in_addr(rt) = 0xffffffff;

    /* Create a socket to the INET kernel. */
    if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
	perror("socket");
	return (E_SOCK);
    }
    /* Tell the kernel to accept this route. */
    if (action == RTACTION_DEL) {
	if (ioctl(skfd, SIOCDELRT, &rt) < 0) {
	    perror("SIOCDELRT");
	    close(skfd);
	    return (E_SOCK);
	}
    } else {
	if (ioctl(skfd, SIOCADDRT, &rt) < 0) {
	    perror("SIOCADDRT");
	    close(skfd);
	    return (E_SOCK);
	}
    }

    /* Close the socket. */
    (void) close(skfd);
    return (0);
}

int INET_rinput(int action, int options, char **args)
{
    if (action == RTACTION_FLUSH) {
	fprintf(stderr, _("Flushing `inet' routing table not supported\n"));
	return (usage());
    }
    if (options & FLAG_CACHE) {
	fprintf(stderr, _("Modifying `inet' routing cache not supported\n"));
	return (usage());
    }
    if ((*args == NULL) || (action == RTACTION_HELP))
	return (usage());

    return (INET_setroute(action, options, args));
}
#endif				/* HAVE_AFINET */

--- NEW FILE: ddp.c ---
/*
 *              DDP protocol output functions.
 *              [Not yet input]
 *
 *                      Alan Cox  <Alan.Cox at linux.org>
 *
 *		$Id: ddp.c,v 1.2 2006-08-31 09:32:17 dslinux_amadeus Exp $
 *
 *              This program 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 of the License, or  (at
 *              your option) any later version.
 */
#include "config.h"

#if HAVE_AFATALK
#include <asm/types.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/atalk.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"
#include "util.h"

/* Display a ddp domain address. */
static char *ddp_print(unsigned char *ptr)
{
    static char buff[64];
    struct sockaddr_at *sat = (struct sockaddr_at *) (ptr - 2);
    sprintf(buff, "%d/%d", (int) ntohs(sat->sat_addr.s_net), (int) sat->sat_addr.s_node);
    return (buff);
}


/* Display a ddp domain address. */
static char *ddp_sprint(struct sockaddr *sap, int numeric)
{
    static char buf[64];

    if (sap->sa_family != AF_APPLETALK)
	return safe_strncpy(buf, _("[NONE SET]"), sizeof(buf));
    return (ddp_print(sap->sa_data));
}


struct aftype ddp_aftype =
{
    "ddp", NULL, /*"Appletalk DDP", */ AF_APPLETALK, 0,
    ddp_print, ddp_sprint, NULL, NULL,
    NULL /*DDP_rprint */ , NULL, NULL,
    -1,
    "/proc/net/appletalk"
};

#endif

--- NEW FILE: inet.c ---
/*
 * lib/inet.c This file contains an implementation of the "INET"
 *              support functions for the net-tools.
 *              (NET-3 base distribution).
 *
 * Version:    $Id: inet.c,v 1.2 2006-08-31 09:32:18 dslinux_amadeus Exp $
 *
 * Author:      Fred N. van Kempen, <waltje at uwalt.nl.mugnet.org>
 *              Copyright 1993 MicroWalt Corporation
 *
 * Modified:
 *960113 {1.21} Bernd Eckenfels :       rresolve cache bug.
 *960128 {1.22} Bernd Eckenfels :       endian bug in print
 *960203 {1.23} Bernd Eckenfels :       net-features support
 *960217 {1.24} Bernd Eckenfels :       get_sname
 *960219 {1.25} Bernd Eckenfels :       extern int h_errno
 *960329 {1.26} Bernd Eckenfels :       resolve 255.255.255.255 
 *980101 {1.27} Bernd Eckenfels :	resolve raw sockets in /etc/protocols
 *990302 {1.28} Phil Blundell   :       add netmask to INET_rresolve
 *991007        Kurt Garloff	:	rresolve, resolve: may be hosts
 *		<garloff at suse.de>	store type (host?) in cache 
 *
 *              This program 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 of the License, or  (at
 *              your option) any later version.
 */
#include "config.h"

/* FIXME.  Split this file into inet4.c for the IPv4 specific parts
   and inet.c for those shared between IPv4 and IPv6.  */

#if HAVE_AFINET || HAVE_AFINET6
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <resolv.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include "version.h"
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"
#include "util.h"

extern int h_errno;		/* some netdb.h versions don't export this */

/* cache */
struct addr {
    struct sockaddr_in addr;
    char *name;
    int host;
    struct addr *next;
};

struct service {
    int number;
    char *name;
    struct service *next;
};

static struct service *tcp_name = NULL, *udp_name = NULL, *raw_name = NULL;

#if HAVE_AFINET

static struct addr *INET_nn = NULL;	/* addr-to-name cache           */


static int INET_resolve(char *name, struct sockaddr_in *sin, int hostfirst)
{
    struct hostent *hp;
    struct netent *np;

    /* Grmpf. -FvK */
    sin->sin_family = AF_INET;
    sin->sin_port = 0;

    /* Default is special, meaning 0.0.0.0. */
    if (!strcmp(name, "default")) {
	sin->sin_addr.s_addr = INADDR_ANY;
	return (1);
    }
    /* Look to see if it's a dotted quad. */
    if (inet_aton(name, &sin->sin_addr)) {
	return 0;
    }
#ifdef EMBED
    return(-1);
#else
    /* If we expect this to be a hostname, try hostname database first */
#ifdef DEBUG
    if (hostfirst) fprintf (stderr, "gethostbyname (%s)\n", name);
#endif
    if (hostfirst && 
	(hp = gethostbyname(name)) != (struct hostent *) NULL) {
	memcpy((char *) &sin->sin_addr, (char *) hp->h_addr_list[0], 
		sizeof(struct in_addr));
	return 0;
    }
    /* Try the NETWORKS database to see if this is a known network. */
#ifdef DEBUG
    fprintf (stderr, "getnetbyname (%s)\n", name);
#endif
    if ((np = getnetbyname(name)) != (struct netent *) NULL) {
	sin->sin_addr.s_addr = htonl(np->n_net);
	return 1;
    }
    if (hostfirst) {
	/* Don't try again */
	errno = h_errno;
	return -1;
    }
#ifdef DEBUG
    res_init();
    _res.options |= RES_DEBUG;
#endif

#ifdef DEBUG
    fprintf (stderr, "gethostbyname (%s)\n", name);
#endif
    if ((hp = gethostbyname(name)) == (struct hostent *) NULL) {
	errno = h_errno;
	return -1;
    }
    memcpy((char *) &sin->sin_addr, (char *) hp->h_addr_list[0], 
	   sizeof(struct in_addr));

    return 0;
#endif
}


/* numeric: & 0x8000: default instead of *, 
 *	    & 0x4000: host instead of net, 
 *	    & 0x0fff: don't resolve
 */
static int INET_rresolve(char *name, size_t len, struct sockaddr_in *sin, 
			 int numeric, unsigned int netmask)
{
    struct hostent *ent;
    struct netent *np;
    struct addr *pn;
    unsigned long ad, host_ad;
    int host = 0;

    /* Grmpf. -FvK */
    if (sin->sin_family != AF_INET) {
#ifdef DEBUG
	fprintf(stderr, _("rresolve: unsupport address family %d !\n"), sin->sin_family);
#endif
	errno = EAFNOSUPPORT;
	return (-1);
    }
    ad = (unsigned long) sin->sin_addr.s_addr;
#ifdef DEBUG
    fprintf (stderr, "rresolve: %08lx, mask %08x, num %08x \n", ad, netmask, numeric);
#endif
    if (ad == INADDR_ANY) {
	if ((numeric & 0x0FFF) == 0) {
	    if (numeric & 0x8000)
		safe_strncpy(name, "default", len);
	    else
	        safe_strncpy(name, "*", len);
	    return (0);
	}
    }
    if (numeric & 0x0FFF) {
        safe_strncpy(name, inet_ntoa(sin->sin_addr), len);
	return (0);
    }

    if ((ad & (~netmask)) != 0 || (numeric & 0x4000))
	host = 1;
#if 0
    INET_nn = NULL;
#endif
    pn = INET_nn;
    while (pn != NULL) {
	if (pn->addr.sin_addr.s_addr == ad && pn->host == host) {
	    safe_strncpy(name, pn->name, len);
#ifdef DEBUG
	    fprintf (stderr, "rresolve: found %s %08lx in cache\n", (host? "host": "net"), ad);
#endif
	    return (0);
	}
	pn = pn->next;
    }

    host_ad = ntohl(ad);
    np = NULL;
    ent = NULL;
#ifndef EMBED
    if (host) {
#ifdef DEBUG
	fprintf (stderr, "gethostbyaddr (%08lx)\n", ad);
#endif
	ent = gethostbyaddr((char *) &ad, 4, AF_INET);
	if (ent != NULL)
	    safe_strncpy(name, ent->h_name, len);
    }
#ifndef __UC_LIBC__
    else {
#ifdef DEBUG
	fprintf (stderr, "getnetbyaddr (%08lx)\n", host_ad);
#endif
	np = getnetbyaddr(host_ad, AF_INET);
	if (np != NULL)
	    safe_strncpy(name, np->n_name, len);
    }
#endif
#endif
    if ((ent == NULL) && (np == NULL))
	safe_strncpy(name, inet_ntoa(sin->sin_addr), len);
    pn = (struct addr *) malloc(sizeof(struct addr));
    pn->addr = *sin;
    pn->next = INET_nn;
    pn->host = host;
    pn->name = (char *) malloc(strlen(name) + 1);
    strcpy(pn->name, name);
    INET_nn = pn;

    return (0);
}


static void INET_reserror(char *text)
{
    herror(text);
}


/* Display an Internet socket address. */
static char *INET_print(unsigned char *ptr)
{
    return (inet_ntoa((*(struct in_addr *) ptr)));
}


/* Display an Internet socket address. */
static char *INET_sprint(struct sockaddr *sap, int numeric)
{
    static char buff[128];

    if (sap->sa_family == 0xFFFF || sap->sa_family == 0)
	return safe_strncpy(buff, _("[NONE SET]"), sizeof(buff));

    if (INET_rresolve(buff, sizeof(buff), (struct sockaddr_in *) sap, 
		      numeric, 0xffffff00) != 0)
	return (NULL);

    return (buff);
}

char *INET_sprintmask(struct sockaddr *sap, int numeric, 
		      unsigned int netmask)
{
    static char buff[128];

    if (sap->sa_family == 0xFFFF || sap->sa_family == 0)
	return safe_strncpy(buff, _("[NONE SET]"), sizeof(buff));
    if (INET_rresolve(buff, sizeof(buff), (struct sockaddr_in *) sap, 
		      numeric, netmask) != 0)
	return (NULL);
    return (buff);
}


static int INET_getsock(char *bufp, struct sockaddr *sap)
{
    char *sp = bufp, *bp;
    unsigned int i;
    unsigned val;
    struct sockaddr_in *sin;

    sin = (struct sockaddr_in *) sap;
    sin->sin_family = AF_INET;
    sin->sin_port = 0;

    val = 0;
    bp = (char *) &val;
    for (i = 0; i < sizeof(sin->sin_addr.s_addr); i++) {
	*sp = toupper(*sp);

	if ((*sp >= 'A') && (*sp <= 'F'))
	    bp[i] |= (int) (*sp - 'A') + 10;
	else if ((*sp >= '0') && (*sp <= '9'))
	    bp[i] |= (int) (*sp - '0');
	else
	    return (-1);

	bp[i] <<= 4;
	sp++;
	*sp = toupper(*sp);

	if ((*sp >= 'A') && (*sp <= 'F'))
	    bp[i] |= (int) (*sp - 'A') + 10;
	else if ((*sp >= '0') && (*sp <= '9'))
	    bp[i] |= (int) (*sp - '0');
	else
	    return (-1);

	sp++;
    }
    sin->sin_addr.s_addr = htonl(val);

    return (sp - bufp);
}

static int INET_input(int type, char *bufp, struct sockaddr *sap)
{
    switch (type) {
    case 1:
	return (INET_getsock(bufp, sap));
    case 256:
	return (INET_resolve(bufp, (struct sockaddr_in *) sap, 1));
    default:
	return (INET_resolve(bufp, (struct sockaddr_in *) sap, 0));
    }
}

static int INET_getnetmask(char *adr, struct sockaddr *m, char *name)
{
    struct sockaddr_in *mask = (struct sockaddr_in *) m;
    char *slash, *end;
    int prefix;

    if ((slash = strchr(adr, '/')) == NULL)
	return 0;

    *slash++ = '\0';
    prefix = strtoul(slash, &end, 0);
    if (*end != '\0')
	return -1;

    if (name) {
	sprintf(name, "/%d", prefix);
    }
    mask->sin_family = AF_INET;
    mask->sin_addr.s_addr = htonl(~(0xffffffffU >> prefix));
    return 1;
}


struct aftype inet_aftype =
{
    "inet", NULL, /*"DARPA Internet", */ AF_INET, sizeof(unsigned long),
    INET_print, INET_sprint, INET_input, INET_reserror,
    NULL /*INET_rprint */ , NULL /*INET_rinput */ ,
    INET_getnetmask,
    -1,
    NULL
};

#endif				/* HAVE_AFINET */

static void add2list(struct service **namebase, struct service *item)
{
    if (*namebase == NULL) {
	*namebase = item;
	item->next = NULL;
    } else {
	item->next = *namebase;
	*namebase = item;
    }
}


static struct service *searchlist(struct service *servicebase, int number)
{
    struct service *item;

    for (item = servicebase; item != NULL; item = item->next) {
	if (item->number == number)
	    return (item);
    }
    return (NULL);
}


#ifndef __UC_LIBC__
static int read_services(void)
{
    struct servent *se;
    struct protoent *pe;
    struct service *item;

    setservent(1);
    while ((se = getservent())) {
	/* Allocate a service entry. */
	item = (struct service *) malloc(sizeof(struct service));
	if (item == NULL)
	    perror("netstat");
	item->name = strdup(se->s_name);
	item->number = se->s_port;

	/* Fill it in. */
	if (!strcmp(se->s_proto, "tcp")) {
	    add2list(&tcp_name, item);
	} else if (!strcmp(se->s_proto, "udp")) {
	    add2list(&udp_name, item);
	} else if (!strcmp(se->s_proto, "raw")) {
	    add2list(&raw_name, item);
	}
    }
    endservent();
    setprotoent(1);
    while ((pe = getprotoent())) {
	/* Allocate a service entry. */
	item = (struct service *) malloc(sizeof(struct service));
	if (item == NULL)
	    perror("netstat");
	item->name = strdup(pe->p_name);
	item->number = htons(pe->p_proto);
	add2list(&raw_name, item);
    }
    endprotoent();
    return (0);
}
#endif


char *get_sname(int socknumber, char *proto, int numeric)
{
    static char buffer[64], init = 0;
    struct service *item;

    if (socknumber == 0)
	return ("*");
    if (numeric) {
	sprintf(buffer, "%d", ntohs(socknumber));
	return (buffer);
    }
#ifndef __UC_LIBC__
    if (!init) {
	(void) read_services();
	init = 1;
    }
#endif
    buffer[0] = '\0';
    if (!strcmp(proto, "tcp")) {
	if ((item = searchlist(tcp_name, socknumber)) != NULL)
	    sprintf(buffer, "%s", item->name);
    } else if (!strcmp(proto, "udp")) {
	if ((item = searchlist(udp_name, socknumber)) != NULL)
	    sprintf(buffer, "%s", item->name);
    } else if (!strcmp(proto, "raw")) {
	if ((item = searchlist(raw_name, socknumber)) != NULL)
	    sprintf(buffer, "%s", item->name);

    }
    if (!buffer[0])
	sprintf(buffer, "%d", ntohs(socknumber));
    return (buffer);
}

#endif				/* HAVE_AFINET || HAVE_AFINET6 */

--- NEW FILE: ppp.c ---
/*
 * lib/ppp.c  This file contains the SLIP support for the NET-2 base
 *              distribution.
 *
 * Version:     $Id: ppp.c,v 1.2 2006-08-31 09:32:18 dslinux_amadeus Exp $
 *
 * Author:      Fred N. van Kempen, <waltje at uwalt.nl.mugnet.org>
 *              Copyright 1993 MicroWalt Corporation
 *
 *              Modified by Alan Cox, May 94 to cover NET-3
 *                       
 * Changes:
 * 980701 {1.12} Arnaldo Carvalho de Melo - GNU gettext instead of catgets
 *
 *              This program 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 of the License, or  (at
 *              your option) any later version.
 */
#include "config.h"

#if HAVE_HWPPP

#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if_arp.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"

/* Start the PPP encapsulation on the file descriptor. */
static int do_ppp(int fd)
{
    fprintf(stderr, _("You cannot start PPP with this program.\n"));
    return -1;
}


struct hwtype ppp_hwtype =
{
    "ppp", NULL, /*"Point-Point Protocol", */ ARPHRD_PPP, 0,
    NULL, NULL, do_ppp, 0
};


#endif				/* HAVE_PPP */

--- NEW FILE: frame.c ---
/*
 * lib/frame.c        This file contains the Frame Relay support.
 *
 * Version:     $Id: frame.c,v 1.2 2006-08-31 09:32:17 dslinux_amadeus Exp $
 *
 * Maintainer:  Bernd 'eckes' Eckenfels, <net-tools at lina.inka.de>
 *
 * Author:      Mike McLagan <mike.mclagan at linux.org>
 *
 * Changes:
 *
 *962303 {0.01} Mike McLagan :          creation
 *960413 {0.02} Bernd Eckenfels :       included in net-lib
 *
 *              This program 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 of the License, or  (at
 *              your option) any later version.
 */
#include "config.h"

#if HAVE_HWFR

#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if_arp.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include "net-support.h"
#include "pathnames.h"

char *pr_dlci(unsigned char *ptr)
{
    static char buf[12];

    snprintf(buf, sizeof(buf), "%i", *(short *) ptr);
    return (buf);
}

struct hwtype dlci_hwtype =
{
    "dlci", NULL, /*"Frame Relay DLCI", */ ARPHRD_DLCI, 3,
    pr_dlci, NULL, NULL, 0
};

struct hwtype frad_hwtype =
{
    "frad", NULL, /*"Frame Relay Access Device", */ ARPHRD_FRAD, 0,
    NULL, NULL, NULL, 0
};
#endif				/* HAVE_HWFR */

--- NEW FILE: net-features.h ---
/*
 * lib/net-features.h This file contains the definitions of all kernel
 *                      dependend features.
 *
 * Version:     features.h 0.03 (1996-03-22)
 *
 * Author:      Bernd Eckenfels <net-tools at lina.inka.de>
 *              Copyright 1996 Bernd Eckenfels, Germany
 *
 * Modifications:
 *960201 {0.01} Bernd Eckenfels:        creation
 *960202 {0.02} Bernd Eckenfels:        HW and AF added
 *960322 {0.03} Bernd Eckenfels:        moved into the NET-LIB
 *980630 {0.04} Arnaldo Carvalho de Melo: changed NLS for I18N
 *
 *              This program 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 of the License, or  (at
 *              your option) any later version.
 */

/* 
 *    This needs to be included AFTER the KErnel Header Files
 *      one of the FEATURE_ should be defined to get the Feature Variable
 *      definition included
 */

#ifndef _NET_FEATURES_H
#define _NET_FEATURES_H

/* detect the present features */

#if defined (SIOCADDRTOLD) || defined (RTF_IRTT)	/* route */
#define HAVE_NEW_ADDRT 1
#endif

#ifdef RTF_IRTT			/* route */
#define HAVE_RTF_IRTT 1
#endif

#ifdef RTF_REJECT		/* route */
#define HAVE_RTF_REJECT 1
#endif

/* compose the feature information string */

#if defined (FEATURE_ARP) || defined (FEATURE_ROUTE) || defined (FEATURE_NETSTAT)
static char *Features =

/* ---------------------------------------------------- */
#ifdef FEATURE_ROUTE

#if HAVE_NEW_ADDRT
"+"
#else
"-"
#endif
"NEW_ADDRT "

#if HAVE_RTF_IRTT
"+"
#else
"-"
#endif
"RTF_IRTT "

#if HAVE_RTF_REJECT
"+"
#else
"-"
#endif
"RTF_REJECT "

#endif				/* FEATURE_ROUTE */
/* ---------------------------------------------------- */


/* ---------------------------------------------------- */
#ifdef FEATURE_NETSTAT

#if HAVE_NEW_ADDRT
"+"
#else
"-"
#endif
"NEW_ADDRT "

#if HAVE_RTF_IRTT
"+"
#else
"-"
#endif
"RTF_IRTT "

#if HAVE_RTF_REJECT
"+"
#else
"-"
#endif
"RTF_REJECT "

#if HAVE_FW_MASQUERADE
"+"
#else
"-"
#endif
"FW_MASQUERADE "

#endif				/* FEATURE_NETSTAT */
/* ---------------------------------------------------- */


#if I18N
"+I18N"
#else
"-I18N"
#endif				/* I18N */


"\nAF: "
#ifdef DFLT_AF
"(" DFLT_AF ")"
#endif

#if HAVE_AFUNIX
" +"
#else
" -"
#endif
"UNIX "
#if HAVE_AFINET
"+"
#else
"-"
#endif
"INET "
#if HAVE_AFINET6
"+"
#else
"-"
#endif
"INET6 "
#if HAVE_AFIPX
"+"
#else
"-"
#endif
"IPX "
#if HAVE_AFAX25
"+"
#else
"-"
#endif
"AX25 "
#if HAVE_AFNETROM
"+"
#else
"-"
#endif
"NETROM "
#if HAVE_AFX25
"+"
#else
"-"
#endif
"X25 "
#if HAVE_AFATALK
"+"
#else
"-"
#endif
"ATALK "
#if HAVE_AFECONET
"+"
#else
"-"
#endif
"ECONET "
#if HAVE_AFROSE
"+"
#else
"-"
#endif
"ROSE "

"\nHW: "

#ifdef DFLT_HW
"(" DFLT_HW ")"
#endif

#if HAVE_HWETHER
" +"
#else
" -"
#endif
"ETHER "
#if HAVE_HWARC
"+"
#else
"-"
#endif
"ARC "
#if HAVE_HWSLIP
"+"
#else
"-"
#endif
"SLIP "
#if HAVE_HWPPP
"+"
#else
"-"
#endif
"PPP "
#if HAVE_HWTUNNEL
"+"
#else
"-"
#endif
"TUNNEL "
#if HAVE_HWTR
"+"
#else
"-"
#endif
"TR "
#if HAVE_HWAX25
"+"
#else
"-"
#endif
"AX25 "

#if HAVE_HWNETROM
"+"
#else
"-"
#endif
"NETROM "

#if HAVE_HWX25
"+"
#else
"-"
#endif
"X25 "

#if HAVE_HWFR
"+"
#else
"-"
#endif
"FR "

#if HAVE_HWROSE
"+"
#else
"-"
#endif
"ROSE "

#if HAVE_HWASH
"+"
#else
"-"
#endif
"ASH "

#if HAVE_HWSIT
"+"
#else
"-"
#endif
"SIT "

#if HAVE_HWFDDI
"+"
#else
"-"
#endif
"FDDI "

#if HAVE_HWHIPPI
"+"
#else
"-"
#endif
"HIPPI "

#if HAVE_HWHDLCLAPB
"+"
#else
"-"
#endif
"HDLC/LAPB "
;


#endif				/* FEATURE_* */

#endif				/* _NET_FEATURES_H */
/* End of features.h */

--- NEW FILE: ash.c ---
/*
 * lib/ash.c  This file contains an implementation of the Ash
 *              support functions for the NET-2 base distribution.
 * $Id: ash.c,v 1.2 2006-08-31 09:32:17 dslinux_amadeus Exp $
 */

#include "config.h"

#if HAVE_HWASH || HAVE_AFASH

#include <sys/types.h>
#include <sys/socket.h>
#include <net/if_arp.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"
#include "util.h"

#define ASH_ALEN		64

static unsigned char hamming[16] =
{
    0x15, 0x02, 0x49, 0x5e, 0x64, 0x73, 0x38, 0x2f,
    0xd0, 0xc7, 0x8c, 0x9b, 0xa1, 0xb6, 0xfd, 0xea
};

/* Display an Ash address in readable format. */
static char *
pr_ash(unsigned char *ptr)
{
    static char buff[128];
    char *p = buff;
    unsigned int i = 0;

    p[0] = '[';
    p++;
    while (ptr[i] != 0xc9 && ptr[i] != 0xff && (i < ASH_ALEN))
	sprintf(p++, "%1x", ptr[i++]);
    *(p++) = ']';
    *p = 0;

    return buff;
}

#if HAVE_HWASH

#ifndef ARPHRD_ASH
#warning "No definition of ARPHRD_ASH in <net/if_arp.h>, using private value 517"
#define ARPHRD_ASH 517
#endif

struct hwtype ash_hwtype;

static int 
in_ash(char *bufp, struct sockaddr *sap)
{
    unsigned char *ptr;
    unsigned int i = 0;

    sap->sa_family = ash_hwtype.type;
    ptr = sap->sa_data;

    while (bufp && i < ASH_ALEN) {
	char *next;
	int hop = strtol(bufp, &next, 16);
	ptr[i++] = hamming[hop];
	switch (*next) {
	case ':':
	    bufp = next + 1;
	    break;
	case 0:
	    bufp = NULL;
	    break;
	default:
	    fprintf(stderr, _("Malformed Ash address"));
	    memset(ptr, 0xc9, ASH_ALEN);
	    return -1;
	}
    }

    while (i < ASH_ALEN)
	ptr[i++] = 0xc9;

    return 0;
}

struct hwtype ash_hwtype =
{
    "ash", NULL, ARPHRD_ASH, ASH_ALEN,
    pr_ash, in_ash, NULL,
    1
};

#endif	/* HAVE_HWASH */

#if HAVE_AFASH

/* Display an Ash socket address. */
static char *
pr_sash(struct sockaddr *sap, int numeric)
{
    static char buf[64];

    if (sap->sa_family != AF_ASH)
	return safe_strncpy(buf, "[NONE SET]", 64);
    return pr_ash(sap->sa_data);
}

struct aftype ash_aftype =
{
    "ash", NULL, AF_ASH, 0,
    pr_ash, pr_sash, NULL, NULL,
    NULL, NULL, NULL,
    -1,
    "/proc/sys/net/ash"
};

#endif	/* HAVE_AFASH */

#endif	/* HAVE_AFASH || HAVE_HWASH */

--- NEW FILE: ppp_ac.c ---
/*
 * lib/ppp_ac.c       This file contains the activation for the
 *              PPP line disciplines, called from activate_ld().
 *
 * Version:     $Id: ppp_ac.c,v 1.2 2006-08-31 09:32:18 dslinux_amadeus Exp $
 *
 * Author:      Bernd 'eckes' Eckenfels
 *
 *              This program 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 of the License, or  (at
 *              your option) any later version.
 */
#include "config.h"

#if HAVE_HWPPP

#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if_arp.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"

/* Start the VJ-SLIP encapsulation on the file descriptor. */
int PPP_activate(int fd)
{
    fprintf(stderr, _("Sorry, use pppd!\n"));	/* FIXME */
    return (-1);
}

#endif				/* HAVE_HWPPP */

--- NEW FILE: proc.h ---


/* Generate a suitable scanf format for a column title line */
char *proc_gen_fmt(char *name, int more, FILE * fh,...);
int   proc_guess_fmt(char *name, FILE* fh,...);

--- NEW FILE: ipx_gr.c ---
/* support for ap->rresolv missing */
/*
   Modifications:
   1998-07-01 - Arnaldo Carvalho de Melo - GNU gettext instead of catgets,
   snprintf instead of sprintf
 */

#include "config.h"

#if HAVE_AFIPX
#include <asm/types.h>
#include <sys/types.h>
#include <sys/socket.h>
#if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1)
#include <netipx/ipx.h>
#else
#include "ipx.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include "version.h"
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"

/* UGLY */

int IPX_rprint(int options)
{
    /* int ext = options & FLAG_EXT; */
    int numeric = options & FLAG_NUM_HOST;
    char buff[1024];
    char net[128], router_net[128];
    char router_node[128];
    int num;
    FILE *fp = fopen(_PATH_PROCNET_IPX_ROUTE, "r");
    struct aftype *ap;
    struct sockaddr sa;

    if ((ap = get_afntype(AF_IPX)) == NULL) {
	EINTERN("lib/ipx_rt.c", "AF_IPX missing");
	return (-1);
    }

    if (!fp) {
        perror(_PATH_PROCNET_IPX_ROUTE);
        printf(_("IPX not configured in this system.\n"));
	return 1;
    }

    printf(_("Kernel IPX routing table\n"));	/* xxx */
    printf(_("Destination               Router Net                Router Node\n"));

    fgets(buff, 1023, fp);

    while (fgets(buff, 1023, fp)) {
	num = sscanf(buff, "%s %s %s", net, router_net, router_node);
	if (num < 3)
	    continue;

	/* Fetch and resolve the Destination */
	(void) ap->input(5, net, &sa);
	strcpy(net, ap->sprint(&sa, numeric));

	/* Fetch and resolve the Router Net */
	(void) ap->input(5, router_net, &sa);
	strcpy(router_net, ap->sprint(&sa, numeric));

	/* Fetch and resolve the Router Node */
	(void) ap->input(2, router_node, &sa);
	strcpy(router_node, ap->sprint(&sa, numeric));

	printf("%-25s %-25s %-25s\n", net, router_net, router_node);
    }

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

#endif				/* HAVE_AFIPX */

--- NEW FILE: interface.c ---
/* Code to manipulate interface information, shared between ifconfig and
   netstat. 

   10/1998 partly rewriten by Andi Kleen to support an interface list.   
   I don't claim that the list operations are efficient @).  

   8/2000  Andi Kleen make the list operations a bit more efficient.
   People are crazy enough to use thousands of aliases now.

   $Id: interface.c,v 1.2 2006-08-31 09:32:18 dslinux_amadeus Exp $
 */

#include "config.h"

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <net/if.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>

#if HAVE_AFIPX
#if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1)
#include <netipx/ipx.h>
#else
#include "ipx.h"
#endif
#endif

#if HAVE_AFECONET
#include <neteconet/ec.h>
#endif

#ifdef HAVE_HWSLIP
#include <linux/if_slip.h>
#include <net/if_arp.h>
#endif

#include "net-support.h"
#include "pathnames.h"
#include "version.h"
#include "proc.h"

#include "interface.h"
#include "sockets.h"
#include "util.h"
#include "intl.h"

#ifdef IFF_PORTSEL
const char *if_port_text[][4] =
{
  /* Keep in step with <linux/netdevice.h> */
    {"unknown", NULL, NULL, NULL},
    {"10base2", "bnc", "coax", NULL},
    {"10baseT", "utp", "tpe", NULL},
    {"AUI", "thick", "db15", NULL},
    {"100baseT", NULL, NULL, NULL},
    {"100baseTX", NULL, NULL, NULL},
    {"100baseFX", NULL, NULL, NULL},
    {NULL, NULL, NULL, NULL},
};
#endif

#define IPV6_ADDR_ANY		0x0000U

#define IPV6_ADDR_UNICAST      	0x0001U
#define IPV6_ADDR_MULTICAST    	0x0002U
#define IPV6_ADDR_ANYCAST	0x0004U

#define IPV6_ADDR_LOOPBACK	0x0010U
#define IPV6_ADDR_LINKLOCAL	0x0020U
#define IPV6_ADDR_SITELOCAL	0x0040U

#define IPV6_ADDR_COMPATv4	0x0080U

#define IPV6_ADDR_SCOPE_MASK	0x00f0U

#define IPV6_ADDR_MAPPED	0x1000U
#define IPV6_ADDR_RESERVED	0x2000U		/* reserved address space */

int procnetdev_vsn = 1;

int ife_short;

static struct interface *int_list, *int_last;

static int if_readlist_proc(char *);

static struct interface *add_interface(char *name)
{
    struct interface *ife, **nextp, *new;

    for (ife = int_last; ife; ife = ife->prev) {
	    int n = nstrcmp(ife->name, name); 
	    if (n == 0) 
		    return ife; 
	    if (n < 0) 
		    break; 
    }
    new(new); 
    safe_strncpy(new->name, name, IFNAMSIZ); 
    nextp = ife ? &ife->next : &int_list;
    new->prev = ife;
    new->next = *nextp; 
    if (new->next) 
	    new->next->prev = new; 
    else
	    int_last = new; 
    *nextp = new; 
    return new; 
}

struct interface *lookup_interface(char *name)
{
    struct interface *ife = NULL;

    if (if_readlist_proc(name) < 0) 
	    return NULL; 
    ife = add_interface(name); 
    return ife;
}

int for_all_interfaces(int (*doit) (struct interface *, void *), void *cookie)
{
    struct interface *ife;

    if (!int_list && (if_readlist() < 0))
	return -1;
    for (ife = int_list; ife; ife = ife->next) {
	int err = doit(ife, cookie);
	if (err)
	    return err;
    }
    return 0;
}

int free_interface_list(void)
{
    struct interface *ife;
    while ((ife = int_list) != NULL) {
	int_list = ife->next;
	free(ife);
    }
    return 0;
}

static int if_readconf(void)
{
    int numreqs = 30;
    struct ifconf ifc;
    struct ifreq *ifr;
    int n, err = -1;
    int skfd;

    /* SIOCGIFCONF currently seems to only work properly on AF_INET sockets
       (as of 2.1.128) */ 
    skfd = get_socket_for_af(AF_INET);
    if (skfd < 0) {
	fprintf(stderr, _("warning: no inet socket available: %s\n"),
		strerror(errno));
	/* Try to soldier on with whatever socket we can get hold of.  */
	skfd = sockets_open(0);
	if (skfd < 0)
	    return -1;
    }

    ifc.ifc_buf = NULL;
    for (;;) {
	ifc.ifc_len = sizeof(struct ifreq) * numreqs;
	ifc.ifc_buf = xrealloc(ifc.ifc_buf, ifc.ifc_len);

	if (ioctl(skfd, SIOCGIFCONF, &ifc) < 0) {
	    perror("SIOCGIFCONF");
	    goto out;
	}
	if (ifc.ifc_len == sizeof(struct ifreq) * numreqs) {
	    /* assume it overflowed and try again */
	    numreqs += 10;
	    continue;
	}
	break;
    }

    ifr = ifc.ifc_req;
    for (n = 0; n < ifc.ifc_len; n += sizeof(struct ifreq)) {
	add_interface(ifr->ifr_name);
	ifr++;
    }
    err = 0;

out:
    free(ifc.ifc_buf);
    return err;
}

static char *get_name(char *name, char *p)
{
    while (isspace(*p))
	p++;
    while (*p) {
	if (isspace(*p))
	    break;
	if (*p == ':') {	/* could be an alias */
	    char *dot = p, *dotname = name;
	    *name++ = *p++;
	    while (isdigit(*p))
		*name++ = *p++;
	    if (*p != ':') {	/* it wasn't, backup */
		p = dot;
		name = dotname;
	    }
	    if (*p == '\0')
		return NULL;
	    p++;
	    break;
	}
	*name++ = *p++;
    }
    *name++ = '\0';
    return p;
}

static int procnetdev_version(char *buf)
{
    if (strstr(buf, "compressed"))
	return 3;
    if (strstr(buf, "bytes"))
	return 2;
    return 1;
}

static int get_dev_fields(char *bp, struct interface *ife)
{
    switch (procnetdev_vsn) {
    case 3:
	sscanf(bp,
	"%llu %llu %lu %lu %lu %lu %lu %lu %llu %llu %lu %lu %lu %lu %lu %lu",
	       &ife->stats.rx_bytes,
	       &ife->stats.rx_packets,
	       &ife->stats.rx_errors,
	       &ife->stats.rx_dropped,
	       &ife->stats.rx_fifo_errors,
	       &ife->stats.rx_frame_errors,
	       &ife->stats.rx_compressed,
	       &ife->stats.rx_multicast,

	       &ife->stats.tx_bytes,
	       &ife->stats.tx_packets,
	       &ife->stats.tx_errors,
	       &ife->stats.tx_dropped,
	       &ife->stats.tx_fifo_errors,
	       &ife->stats.collisions,
	       &ife->stats.tx_carrier_errors,
	       &ife->stats.tx_compressed);
	break;
    case 2:
	sscanf(bp, "%llu %llu %lu %lu %lu %lu %llu %llu %lu %lu %lu %lu %lu",
	       &ife->stats.rx_bytes,
	       &ife->stats.rx_packets,
	       &ife->stats.rx_errors,
	       &ife->stats.rx_dropped,
	       &ife->stats.rx_fifo_errors,
	       &ife->stats.rx_frame_errors,

	       &ife->stats.tx_bytes,
	       &ife->stats.tx_packets,
	       &ife->stats.tx_errors,
	       &ife->stats.tx_dropped,
	       &ife->stats.tx_fifo_errors,
	       &ife->stats.collisions,
	       &ife->stats.tx_carrier_errors);
	ife->stats.rx_multicast = 0;
	break;
    case 1:
	sscanf(bp, "%llu %lu %lu %lu %lu %llu %lu %lu %lu %lu %lu",
	       &ife->stats.rx_packets,
	       &ife->stats.rx_errors,
	       &ife->stats.rx_dropped,
	       &ife->stats.rx_fifo_errors,
	       &ife->stats.rx_frame_errors,

	       &ife->stats.tx_packets,
	       &ife->stats.tx_errors,
	       &ife->stats.tx_dropped,
	       &ife->stats.tx_fifo_errors,
	       &ife->stats.collisions,
	       &ife->stats.tx_carrier_errors);
	ife->stats.rx_bytes = 0;
	ife->stats.tx_bytes = 0;
	ife->stats.rx_multicast = 0;
	break;
    }
    return 0;
}

static int if_readlist_proc(char *target)
{
    static int proc_read; 
    FILE *fh;
    char buf[512];
    struct interface *ife;
    int err;

    if (proc_read) 
	    return 0; 
    if (!target) 
	    proc_read = 1;

    fh = fopen(_PATH_PROCNET_DEV, "r");
    if (!fh) {
		fprintf(stderr, _("Warning: cannot open %s (%s). Limited output.\n"),
			_PATH_PROCNET_DEV, strerror(errno)); 
		return if_readconf();
	}	
    fgets(buf, sizeof buf, fh);	/* eat line */
    fgets(buf, sizeof buf, fh);

#if 0				/* pretty, but can't cope with missing fields */
    fmt = proc_gen_fmt(_PATH_PROCNET_DEV, 1, fh,
		       "face", "",	/* parsed separately */
		       "bytes", "%lu",
		       "packets", "%lu",
		       "errs", "%lu",
		       "drop", "%lu",
		       "fifo", "%lu",
		       "frame", "%lu",
		       "compressed", "%lu",
		       "multicast", "%lu",
		       "bytes", "%lu",
		       "packets", "%lu",
		       "errs", "%lu",
		       "drop", "%lu",
		       "fifo", "%lu",
		       "colls", "%lu",
		       "carrier", "%lu",
		       "compressed", "%lu",
		       NULL);
    if (!fmt)
	return -1;
#else
    procnetdev_vsn = procnetdev_version(buf);
#endif

    err = 0;
    while (fgets(buf, sizeof buf, fh)) {
	char *s, name[IFNAMSIZ];
	s = get_name(name, buf);    
	ife = add_interface(name);
	get_dev_fields(s, ife);
	ife->statistics_valid = 1;
	if (target && !strcmp(target,name))
		break;
    }
    if (ferror(fh)) {
	perror(_PATH_PROCNET_DEV);
	err = -1;
	proc_read = 0; 
    }

#if 0
    free(fmt);
#endif
    fclose(fh);
    return err;
}

int if_readlist(void) 
{ 
    int err = if_readlist_proc(NULL); 
    if (!err)
	    err = if_readconf();
    return err;
} 

/* Support for fetching an IPX address */

#if HAVE_AFIPX
static int ipx_getaddr(int sock, int ft, struct ifreq *ifr)
{
    ((struct sockaddr_ipx *) &ifr->ifr_addr)->sipx_type = ft;
    return ioctl(sock, SIOCGIFADDR, ifr);
}
#endif

/* Fetch the interface configuration from the kernel. */
int if_fetch(struct interface *ife)
{
    struct ifreq ifr;
    int fd;
    char *ifname = ife->name; 

    strcpy(ifr.ifr_name, ifname);
    if (ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0)
	return (-1);
    ife->flags = ifr.ifr_flags;

    strcpy(ifr.ifr_name, ifname);
    if (ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0)
	memset(ife->hwaddr, 0, 32);
    else
	memcpy(ife->hwaddr, ifr.ifr_hwaddr.sa_data, 8);

    ife->type = ifr.ifr_hwaddr.sa_family;

    strcpy(ifr.ifr_name, ifname);
    if (ioctl(skfd, SIOCGIFMETRIC, &ifr) < 0)
	ife->metric = 0;
    else
	ife->metric = ifr.ifr_metric;

    strcpy(ifr.ifr_name, ifname);
    if (ioctl(skfd, SIOCGIFMTU, &ifr) < 0)
	ife->mtu = 0;
    else
	ife->mtu = ifr.ifr_mtu;

#ifdef HAVE_HWSLIP
    if (ife->type == ARPHRD_SLIP || ife->type == ARPHRD_CSLIP ||
	ife->type == ARPHRD_SLIP6 || ife->type == ARPHRD_CSLIP6 ||
	ife->type == ARPHRD_ADAPT) {
#ifdef SIOCGOUTFILL
	strcpy(ifr.ifr_name, ifname);
	if (ioctl(skfd, SIOCGOUTFILL, &ifr) < 0)
	    ife->outfill = 0;
	else
	    ife->outfill = (unsigned int) ifr.ifr_data;
#endif
#ifdef SIOCGKEEPALIVE
	strcpy(ifr.ifr_name, ifname);
	if (ioctl(skfd, SIOCGKEEPALIVE, &ifr) < 0)
	    ife->keepalive = 0;
	else
	    ife->keepalive = (unsigned int) ifr.ifr_data;
#endif
    }
#endif

    strcpy(ifr.ifr_name, ifname);
    if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0)
	memset(&ife->map, 0, sizeof(struct ifmap));
    else
	memcpy(&ife->map, &ifr.ifr_map, sizeof(struct ifmap));

    strcpy(ifr.ifr_name, ifname);
    if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0)
	memset(&ife->map, 0, sizeof(struct ifmap));
    else
	ife->map = ifr.ifr_map;

#ifdef HAVE_TXQUEUELEN
    strcpy(ifr.ifr_name, ifname);
    if (ioctl(skfd, SIOCGIFTXQLEN, &ifr) < 0)
	ife->tx_queue_len = -1;	/* unknown value */
    else
	ife->tx_queue_len = ifr.ifr_qlen;
#else
    ife->tx_queue_len = -1;	/* unknown value */
#endif

#if HAVE_AFINET
    /* IPv4 address? */
    fd = get_socket_for_af(AF_INET);
    if (fd >= 0) {
	strcpy(ifr.ifr_name, ifname);
	ifr.ifr_addr.sa_family = AF_INET;
	if (ioctl(fd, SIOCGIFADDR, &ifr) == 0) {
	    ife->has_ip = 1;
	    ife->addr = ifr.ifr_addr;
	    strcpy(ifr.ifr_name, ifname);
	    if (ioctl(fd, SIOCGIFDSTADDR, &ifr) < 0)
	        memset(&ife->dstaddr, 0, sizeof(struct sockaddr));
	    else
	        ife->dstaddr = ifr.ifr_dstaddr;

	    strcpy(ifr.ifr_name, ifname);
	    if (ioctl(fd, SIOCGIFBRDADDR, &ifr) < 0)
	        memset(&ife->broadaddr, 0, sizeof(struct sockaddr));
	    else
		ife->broadaddr = ifr.ifr_broadaddr;

	    strcpy(ifr.ifr_name, ifname);
	    if (ioctl(fd, SIOCGIFNETMASK, &ifr) < 0)
		memset(&ife->netmask, 0, sizeof(struct sockaddr));
	    else
		ife->netmask = ifr.ifr_netmask;
	} else
	    memset(&ife->addr, 0, sizeof(struct sockaddr));
    }
#endif

#if HAVE_AFATALK
    /* DDP address maybe ? */
    fd = get_socket_for_af(AF_APPLETALK);
    if (fd >= 0) {
	strcpy(ifr.ifr_name, ifname);
	if (ioctl(fd, SIOCGIFADDR, &ifr) == 0) {
	    ife->ddpaddr = ifr.ifr_addr;
	    ife->has_ddp = 1;
	}
    }
#endif

#if HAVE_AFIPX
    /* Look for IPX addresses with all framing types */
    fd = get_socket_for_af(AF_IPX);
    if (fd >= 0) {
	strcpy(ifr.ifr_name, ifname);
	if (!ipx_getaddr(fd, IPX_FRAME_ETHERII, &ifr)) {
	    ife->has_ipx_bb = 1;
	    ife->ipxaddr_bb = ifr.ifr_addr;
	}
	strcpy(ifr.ifr_name, ifname);
	if (!ipx_getaddr(fd, IPX_FRAME_SNAP, &ifr)) {
	    ife->has_ipx_sn = 1;
	    ife->ipxaddr_sn = ifr.ifr_addr;
	}
	strcpy(ifr.ifr_name, ifname);
	if (!ipx_getaddr(fd, IPX_FRAME_8023, &ifr)) {
	    ife->has_ipx_e3 = 1;
	    ife->ipxaddr_e3 = ifr.ifr_addr;
	}
	strcpy(ifr.ifr_name, ifname);
	if (!ipx_getaddr(fd, IPX_FRAME_8022, &ifr)) {
	    ife->has_ipx_e2 = 1;
	    ife->ipxaddr_e2 = ifr.ifr_addr;
	}
    }
#endif

#if HAVE_AFECONET
    /* Econet address maybe? */
    fd = get_socket_for_af(AF_ECONET);
    if (fd >= 0) {
	strcpy(ifr.ifr_name, ifname);
	if (ioctl(fd, SIOCGIFADDR, &ifr) == 0) {
	    ife->ecaddr = ifr.ifr_addr;
	    ife->has_econet = 1;
	}
    }
#endif

    return 0;
}

int do_if_fetch(struct interface *ife)
{ 
    if (if_fetch(ife) < 0) {
	char *errmsg; 
	if (errno == ENODEV) { 
	    /* Give better error message for this case. */ 
	    errmsg = _("Device not found"); 
	} else { 
	    errmsg = strerror(errno); 
	}
  	fprintf(stderr, _("%s: error fetching interface information: %s\n"),
		ife->name, errmsg);
	return -1;
    }
    return 0; 
}

int do_if_print(struct interface *ife, void *cookie)
{
    int *opt_a = (int *) cookie;
    int res; 

    res = do_if_fetch(ife); 
    if (res >= 0) {   
	if ((ife->flags & IFF_UP) || *opt_a)
	    ife_print(ife);
    }
    return res;
}

void ife_print_short(struct interface *ptr)
{
    printf("%-5.5s ", ptr->name);
    printf("%5d %3d", ptr->mtu, ptr->metric);
    /* If needed, display the interface statistics. */
    if (ptr->statistics_valid) {
	printf("%8llu %6lu %6lu %6lu",
	       ptr->stats.rx_packets, ptr->stats.rx_errors,
	       ptr->stats.rx_dropped, ptr->stats.rx_fifo_errors);
	printf("%8llu %6lu %6lu %6lu ",
	       ptr->stats.tx_packets, ptr->stats.tx_errors,
	       ptr->stats.tx_dropped, ptr->stats.tx_fifo_errors);
    } else {
	printf("%-56s", _("     - no statistics available -"));
    }
    /* DONT FORGET TO ADD THE FLAGS IN ife_print_long, too */
    if (ptr->flags == 0)
	printf(_("[NO FLAGS]"));
    if (ptr->flags & IFF_ALLMULTI)
	printf("A");
    if (ptr->flags & IFF_BROADCAST)
	printf("B");
    if (ptr->flags & IFF_DEBUG)
	printf("D");
    if (ptr->flags & IFF_LOOPBACK)
	printf("L");
    if (ptr->flags & IFF_MULTICAST)
	printf("M");
#ifdef HAVE_DYNAMIC
    if (ptr->flags & IFF_DYNAMIC)
	printf("d");
#endif
    if (ptr->flags & IFF_PROMISC)
	printf("P");
    if (ptr->flags & IFF_NOTRAILERS)
	printf("N");
    if (ptr->flags & IFF_NOARP)
	printf("O");
    if (ptr->flags & IFF_POINTOPOINT)
	printf("P");
    if (ptr->flags & IFF_SLAVE)
	printf("s");
    if (ptr->flags & IFF_MASTER)
	printf("m");
    if (ptr->flags & IFF_RUNNING)
	printf("R");
    if (ptr->flags & IFF_UP)
	printf("U");
    /* DONT FORGET TO ADD THE FLAGS IN ife_print_long, too */
    printf("\n");
}

void ife_print_long(struct interface *ptr)
{
    struct aftype *ap;
    struct hwtype *hw;
    int hf;
    int can_compress = 0;
    unsigned long long rx, tx, short_rx, short_tx;
    char Rext[5]="b";
    char Text[5]="b";

#if HAVE_AFIPX
    static struct aftype *ipxtype = NULL;
#endif
#if HAVE_AFECONET
    static struct aftype *ectype = NULL;
#endif
#if HAVE_AFATALK
    static struct aftype *ddptype = NULL;
#endif
#if HAVE_AFINET6
    FILE *f;
    char addr6[40], devname[20];
    struct sockaddr_in6 sap;
    int plen, scope, dad_status, if_idx;
    extern struct aftype inet6_aftype;
    char addr6p[8][5];
#endif

    ap = get_afntype(ptr->addr.sa_family);
    if (ap == NULL)
	ap = get_afntype(0);

    hf = ptr->type;

    if (hf == ARPHRD_CSLIP || hf == ARPHRD_CSLIP6)
	can_compress = 1;

    hw = get_hwntype(hf);
    if (hw == NULL)
	hw = get_hwntype(-1);

    printf(_("%-9s Link encap:%s  "), ptr->name, hw->title);
    /* For some hardware types (eg Ash, ATM) we don't print the 
       hardware address if it's null.  */
    if (hw->print != NULL && (! (hw_null_address(hw, ptr->hwaddr) &&
				  hw->suppress_null_addr)))
	printf(_("HWaddr %s  "), hw->print(ptr->hwaddr));
#ifdef IFF_PORTSEL
    if (ptr->flags & IFF_PORTSEL) {
	printf(_("Media:%s"), if_port_text[ptr->map.port][0]);
	if (ptr->flags & IFF_AUTOMEDIA)
	    printf(_("(auto)"));
    }
#endif
    printf("\n");

#if HAVE_AFINET
    if (ptr->has_ip) {
	printf(_("          %s addr:%s "), ap->name,
	       ap->sprint(&ptr->addr, 1));
	if (ptr->flags & IFF_POINTOPOINT) {
	    printf(_(" P-t-P:%s "), ap->sprint(&ptr->dstaddr, 1));
	}
	if (ptr->flags & IFF_BROADCAST) {
	    printf(_(" Bcast:%s "), ap->sprint(&ptr->broadaddr, 1));
	}
	printf(_(" Mask:%s\n"), ap->sprint(&ptr->netmask, 1));
    }
#endif

#if HAVE_AFINET6
    /* FIXME: should be integrated into interface.c.   */

    if ((f = fopen(_PATH_PROCNET_IFINET6, "r")) != NULL) {
	while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n",
		      addr6p[0], addr6p[1], addr6p[2], addr6p[3],
		      addr6p[4], addr6p[5], addr6p[6], addr6p[7],
		  &if_idx, &plen, &scope, &dad_status, devname) != EOF) {
	    if (!strcmp(devname, ptr->name)) {
		sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s",
			addr6p[0], addr6p[1], addr6p[2], addr6p[3],
			addr6p[4], addr6p[5], addr6p[6], addr6p[7]);
		inet6_aftype.input(1, addr6, (struct sockaddr *) &sap);
		printf(_("          inet6 addr: %s/%d"),
		 inet6_aftype.sprint((struct sockaddr *) &sap, 1), plen);
		printf(_(" Scope:"));
		switch (scope) {
		case 0:
		    printf(_("Global"));
		    break;
		case IPV6_ADDR_LINKLOCAL:
		    printf(_("Link"));
		    break;
		case IPV6_ADDR_SITELOCAL:
		    printf(_("Site"));
		    break;
		case IPV6_ADDR_COMPATv4:
		    printf(_("Compat"));
		    break;
		case IPV6_ADDR_LOOPBACK:
		    printf(_("Host"));
		    break;
		default:
		    printf(_("Unknown"));
		}
		printf("\n");
	    }
	}
	fclose(f);
    }
#endif

#if HAVE_AFIPX
    if (ipxtype == NULL)
	ipxtype = get_afntype(AF_IPX);

    if (ipxtype != NULL) {
	if (ptr->has_ipx_bb)
	    printf(_("          IPX/Ethernet II addr:%s\n"),
		   ipxtype->sprint(&ptr->ipxaddr_bb, 1));
	if (ptr->has_ipx_sn)
	    printf(_("          IPX/Ethernet SNAP addr:%s\n"),
		   ipxtype->sprint(&ptr->ipxaddr_sn, 1));
	if (ptr->has_ipx_e2)
	    printf(_("          IPX/Ethernet 802.2 addr:%s\n"),
		   ipxtype->sprint(&ptr->ipxaddr_e2, 1));
	if (ptr->has_ipx_e3)
	    printf(_("          IPX/Ethernet 802.3 addr:%s\n"),
		   ipxtype->sprint(&ptr->ipxaddr_e3, 1));
    }
#endif

#if HAVE_AFATALK
    if (ddptype == NULL)
	ddptype = get_afntype(AF_APPLETALK);
    if (ddptype != NULL) {
	if (ptr->has_ddp)
	    printf(_("          EtherTalk Phase 2 addr:%s\n"), ddptype->sprint(&ptr->ddpaddr, 1));
    }
#endif

#if HAVE_AFECONET
    if (ectype == NULL)
	ectype = get_afntype(AF_ECONET);
    if (ectype != NULL) {
	if (ptr->has_econet)
	    printf(_("          econet addr:%s\n"), ectype->sprint(&ptr->ecaddr, 1));
    }
#endif

    printf("          ");
    /* DONT FORGET TO ADD THE FLAGS IN ife_print_short, too */
    if (ptr->flags == 0)
	printf(_("[NO FLAGS] "));
    if (ptr->flags & IFF_UP)
	printf(_("UP "));
    if (ptr->flags & IFF_BROADCAST)
	printf(_("BROADCAST "));
    if (ptr->flags & IFF_DEBUG)
	printf(_("DEBUG "));
    if (ptr->flags & IFF_LOOPBACK)
	printf(_("LOOPBACK "));
    if (ptr->flags & IFF_POINTOPOINT)
	printf(_("POINTOPOINT "));
    if (ptr->flags & IFF_NOTRAILERS)
	printf(_("NOTRAILERS "));
    if (ptr->flags & IFF_RUNNING)
	printf(_("RUNNING "));
    if (ptr->flags & IFF_NOARP)
	printf(_("NOARP "));
    if (ptr->flags & IFF_PROMISC)
	printf(_("PROMISC "));
    if (ptr->flags & IFF_ALLMULTI)
	printf(_("ALLMULTI "));
    if (ptr->flags & IFF_SLAVE)
	printf(_("SLAVE "));
    if (ptr->flags & IFF_MASTER)
	printf(_("MASTER "));
    if (ptr->flags & IFF_MULTICAST)
	printf(_("MULTICAST "));
#ifdef HAVE_DYNAMIC
    if (ptr->flags & IFF_DYNAMIC)
	printf(_("DYNAMIC "));
#endif
    /* DONT FORGET TO ADD THE FLAGS IN ife_print_short */
    printf(_(" MTU:%d  Metric:%d"),
	   ptr->mtu, ptr->metric ? ptr->metric : 1);
#ifdef SIOCSKEEPALIVE
    if (ptr->outfill || ptr->keepalive)
	printf(_("  Outfill:%d  Keepalive:%d"),
	       ptr->outfill, ptr->keepalive);
#endif
    printf("\n");

    /* If needed, display the interface statistics. */

    if (ptr->statistics_valid) {
	/* XXX: statistics are currently only printed for the primary address,
	 *      not for the aliases, although strictly speaking they're shared
	 *      by all addresses.
	 */
	printf("          ");

	printf(_("RX packets:%llu errors:%lu dropped:%lu overruns:%lu frame:%lu\n"),
	       ptr->stats.rx_packets, ptr->stats.rx_errors,
	       ptr->stats.rx_dropped, ptr->stats.rx_fifo_errors,
	       ptr->stats.rx_frame_errors);
	if (can_compress)
	    printf(_("             compressed:%lu\n"), ptr->stats.rx_compressed);

	rx = ptr->stats.rx_bytes;  
	tx = ptr->stats.tx_bytes;
	short_rx = rx * 10;  
	short_tx = tx * 10;
	if (rx > 1048576) { short_rx /= 1048576;  strcpy(Rext, "Mb"); }
	else if (rx > 1024) { short_rx /= 1024;  strcpy(Rext, "Kb"); }
	if (tx > 1048576) { short_tx /= 1048576;  strcpy(Text, "Mb"); }
	else if (tx > 1024) { short_tx /= 1024;  strcpy(Text, "Kb"); }

	printf("          ");
	printf(_("TX packets:%llu errors:%lu dropped:%lu overruns:%lu carrier:%lu\n"),
	       ptr->stats.tx_packets, ptr->stats.tx_errors,
	       ptr->stats.tx_dropped, ptr->stats.tx_fifo_errors,
	       ptr->stats.tx_carrier_errors);
	printf(_("          collisions:%lu "), ptr->stats.collisions);
	if (can_compress)
	    printf(_("compressed:%lu "), ptr->stats.tx_compressed);
	if (ptr->tx_queue_len != -1)
	    printf(_("txqueuelen:%d "), ptr->tx_queue_len);
	printf("\n          ");
#ifndef EMBED
	printf(_("RX bytes:%llu (%lu.%lu %s)  TX bytes:%llu (%lu.%lu %s)\n"),
	       rx, (unsigned long)(short_rx / 10), 
	       (unsigned long)(short_rx % 10), Rext, 
	       tx, (unsigned long)(short_tx / 10), 
	       (unsigned long)(short_tx % 10), Text);
#endif
    }

    if ((ptr->map.irq || ptr->map.mem_start || ptr->map.dma ||
	 ptr->map.base_addr)) {
	printf("          ");
	if (ptr->map.irq)
	    printf(_("Interrupt:%d "), ptr->map.irq);
	if (ptr->map.base_addr >= 0x100)	/* Only print devices using it for 
						   I/O maps */
	    printf(_("Base address:0x%x "), ptr->map.base_addr);
	if (ptr->map.mem_start) {
	    printf(_("Memory:%lx-%lx "), ptr->map.mem_start, ptr->map.mem_end);
	}
	if (ptr->map.dma)
	    printf(_("DMA chan:%x "), ptr->map.dma);
	printf("\n");
    }
    printf("\n");
}

void ife_print(struct interface *i)
{
    if (ife_short)
	ife_print_short(i);
    else
	ife_print_long(i);
}




More information about the dslinux-commit mailing list