SLIP problem on Ultrix 3.0

David Herron -- One of the vertebrae david at ms.uky.edu
Tue Jul 11 11:33:16 AEST 1989


Yes that's the case.  (That having multiple sl devices doesn't work).

The code for if_sl.c appears to have compiled to only support 1 sl device.
Or rather, I don't know how it'd have >1 ...  Weeerll ... it almost does.

[ I've since gone and set up a machine with two sl devices ... ]

The way this is set up in memory is that sl_softc points to the first
in a linked list of sl_softc's, each following one has a "next" pointer
which points to the next.  The second in the list does claim that
it's unit 1 and everything else appears to be normal.  Doing a ping
towards the machine which has two sl's does increment the Opkt count
on the pinging machine and the Ipkt count on the target machine.  But
no packets are going back ... sigh

BTW, I verified this by modifying the MTU on the second sl device
using adb ...

If it matters any ... all of my SLIP links are in net 223.163.130.0.
Perhaps this would work if the links were in different nets?




As an added special one-time bonus, attached is a program which'll
change the MTU on sl0.  It doesn't, yet, track down that linked list
to change other MTU's... 

Why do I want to change the MTU???   Weeeerll, that's a looong story...


(Oh, compile with cc -o slmtu slmtu.c)



/* slmtu.c -- set mtu for a SLIP device. This is known to work with Ultrix v3 */

/* Written by David S. Herron.  Date: Mon Jul 10 20:42:44 EDT 1989
 *
 * I disclaim all sorts of things about this program and declare it
 * completely and totally in the public domain.  Possibly the only
 * use for this code is to use the printout as kitty litter.  But
 * be careful to not use chemical soaked paper....
 */

/*
 * THEORY OF OPERATION
 *
 * The MTU (Maxinum Transfer Unit) governs the size of the biggest packet
 * which can be sent over an interface.  The value is stored in the 
 * (struct ifnet) for the interface which, for the slip code at least,
 * is stored in the per-interface soft characteristics structure.
 *
 * In the routine which forms up a packet and inserts it into the outgoing
 * packet queue (ip_output()) there's a check to see if the packet is larger
 * than the MTU for the interface.  If it is, and the packet isn't a broadcast
 * packet, it's fragmented.  If it is a broadcast packet, an error is returned.
 *
 * My belief is that simply setting the MTU in the (struct ifnet) will
 * simply cause ip_output() to do the right thing...  This is verified
 * by inspecting the 4.3-tahoe ip_output() and the dynix code in net/if.c
 * which handles SIOCGIFMTU and SIOCSIFMTU ioctl()'s.  These ioctl()'s
 * Get and Set the MTU on an interface, the relavent code simply assigns
 * the passed MTU into the (struct ifnet) mtu tag.
 *
 *	[Interesting ... Sun OS v4's /usr/include/sys/sockio.h has
 *	 definitions for those ioctl()'s, but the ifconfig doesn't
 * 	 claim to be able to set MTU.]
 *
 * This code is rather specific to the SLIP driver.  It finds sl_softc,
 * reads that in, modifies the incore MTU to the command-line argument,
 * and then writes out the first couple parts of the (struct ifnet).
 * These are a (char *) pointing to the name, a (short) containing
 * the unit number, and a (short) containing the MTU.  Which you can
 * see for yourself by looking at the structure definition below, and
 * inspecting /usr/include/net/if.h.
 *
 * It appears that somewhere there's a linked list of (struct ifnet)'s
 * for all the gen'd devices.  This program could become more general
 * by finding that list and working down it until it finds the right
 * entry.  But that's more than I want to figure out right now.
 *
 * Note:  The PD net/if_sl.c has an array of (struct sl_softc)'s declared
 *	as: "struct sl_softc { ... } sl_softc[NSL];".  I expected this
 *	to mean that the (struct sl_softc)'s were "right there".  Instead
 *	I found a pointer to the right place.  So "find sl_softc" really
 *	means:
 *
 *		read in that pointer
 *		lseek there
 *		read in the sl_softc
 *
 * Perhaps this works differently with other if_sl.c's?  But I don't have
 * the time to investigate that right at this moment.  
 *
 * Is Ultrix different in this regard so that the number of units can be
 * changed dynamically?
 */

#include <stdio.h>
#include <nlist.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <net/netisr.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/in_var.h>
#include <netinet/ip.h>




struct nlist slsoftc[] = {
	{ "_sl_softc",'\0','\0',0,0 	},
	{ "",'\0','\0',0,0 	}
};

#ifdef sequent
#define NAMELIST "/dynix"
#else
#define NAMELIST "/vmunix"
#endif


struct sl_softc {
	struct  ifnet sc_if;    /* network-visible interface */
	short   sc_flags;       /* see below */
	short   sc_ilen;        /* length of input-packet-so-far */
	struct  tty *sc_ttyp;   /* pointer to tty structure */
	char    *sc_mp;         /* pointer to next available buf char */
	char    *sc_buf;        /* input buffer */
} sl_softc;

char ifname[20];

int interface;
int newmtu;

main(argc,argv)
int argc;
char *argv[];
{
	int kmem;
	int onflag;
	char *slsoftloc;

	if (argc != 3 && argc != 2) {
		fprintf(stderr, "USAGE: slmtu interface [ mtu ]\n");
		exit(1);
	}
	if (argv[1][0] != 's' || argv[1][1] != 'l') {
		fprintf(stderr, "USAGE: slmtu interface [ mtu ]\n");
		exit(1);
	}
	interface = atoi(&(argv[1][2]));
	if (argc == 3) {
		newmtu = atoi(argv[2]);
	}
	printf("sl%d -- newmtu: %d\n", interface, newmtu);

	if ((kmem = open("/dev/kmem", 2)) < 0) {
		perror("[SLMTU] Can't open /dev/kmem");
		exit(1);
	}
	nlist(NAMELIST, &slsoftc[0]);
	printf("name: %s, type: %x, other: %x, desc: %d, value: %lx\n",
		slsoftc[0].n_name, slsoftc[0].n_type, slsoftc[0].n_other,
		slsoftc[0].n_desc, slsoftc[0].n_value);
	if (slsoftc[0].n_type == 0) {
		fprintf(stderr,"[SLMTU] Can't find slsoftc entry");
		exit(1);
	}
	if(lseek(kmem, (long) slsoftc[0].n_value, 0) == -1) {
		perror("[SLMTU] lseek before read failed");
		exit(1);
	}
	if(read(kmem, (char *) &slsoftloc, sizeof slsoftloc) == -1) {
		perror("[SLMTU] read failed");
		exit(1);
	}

	printf("sl_softc offset at %lx\n", slsoftloc);

	if(lseek(kmem, (long) slsoftloc, 0) == -1) {
		perror("[SLMTU] lseek before read failed");
		exit(1);
	}
	if(read(kmem, (char *) &sl_softc, sizeof sl_softc) == -1) {
		perror("[SLMTU] read failed");
		exit(1);
	}

	if(lseek(kmem, (long) sl_softc.sc_if.if_name, 0) == -1) {
		perror("[SLMTU] lseek before read failed");
		exit(1);
	}
	if(read(kmem, (char *) &ifname[0], sizeof ifname) == -1) {
		perror("[SLMTU] read failed");
		exit(1);
	}

#ifdef DEBUG
	{
		char *p;
		int i;

		p = (char *)&sl_softc;
		for (i=0; i < sizeof sl_softc; i++) {
			printf("offset: %d, value: %x\n", i, p[i]);
		}
	}
#endif


	printf("if_name: %x, if_name:  %s, if_unit: %d\n",
		sl_softc.sc_if.if_name, ifname, sl_softc.sc_if.if_unit);
	printf("if_mtu: %d\n", sl_softc.sc_if.if_mtu);
	printf("if_flags: %x\n", sl_softc.sc_if.if_flags);
	printf("if_metric: %d\n", sl_softc.sc_if.if_metric);
	printf("sc_flags: %x\n", sl_softc.sc_flags);
	printf("sc_ilen: %d\n", sl_softc.sc_ilen);

	if (argc == 3) {
		sl_softc.sc_if.if_mtu = newmtu;

		if(lseek(kmem, (long) slsoftloc, 0) == -1) {
			perror("[SLMTU] lseek before write failed");
			exit(1);
		}
		if(write(kmem, (char *) &sl_softc,
		    sizeof(char *) + sizeof(short) + sizeof(short)) == -1) {
			perror("[SLMTU] write failed");
			exit(1);
		}
	}
	close(kmem);
}
-- 
<- David Herron; an MMDF guy                              <david at ms.uky.edu>
<- ska: David le casse\*'      {rutgers,uunet}!ukma!david, david at UKMA.BITNET
<-
<- New word for the day: Obnoxity -- an act of obnoxiousness



More information about the Comp.unix.ultrix mailing list