slip_user.c revision f34d9d2dcb7f17b64124841345b23adc0843e7a5
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <stdio.h>
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <stdlib.h>
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <unistd.h>
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <stddef.h>
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <sched.h>
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <string.h>
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <errno.h>
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <sys/termios.h>
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <sys/wait.h>
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <sys/signal.h>
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "user_util.h"
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "kern_util.h"
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "user.h"
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "net_user.h"
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "slip.h"
16a3c77c67a443e631febf708bb0c376caede31657Jeff Dike#include "slip_common.h"
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "os.h"
18c13e569073b89eb75216a2551e89ae93ad1f9951Paolo 'Blaisorblade' Giarrusso#include "um_malloc.h"
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
20f34d9d2dcb7f17b64124841345b23adc0843e7a5Jeff Dikestatic int slip_user_init(void *data, void *dev)
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct slip_data *pri = data;
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pri->dev = dev;
25f34d9d2dcb7f17b64124841345b23adc0843e7a5Jeff Dike	return 0;
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int set_up_tty(int fd)
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i;
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct termios tios;
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (tcgetattr(fd, &tios) < 0) {
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printk("could not get initial terminal attributes\n");
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return(-1);
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	tios.c_cflag = CS8 | CREAD | HUPCL | CLOCAL;
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	tios.c_iflag = IGNBRK | IGNPAR;
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	tios.c_oflag = 0;
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	tios.c_lflag = 0;
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = 0; i < NCCS; i++)
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		tios.c_cc[i] = 0;
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	tios.c_cc[VMIN] = 1;
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	tios.c_cc[VTIME] = 0;
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	cfsetospeed(&tios, B38400);
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	cfsetispeed(&tios, B38400);
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) {
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printk("failed to set terminal attributes\n");
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return(-1);
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return(0);
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct slip_pre_exec_data {
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int stdin;
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int stdout;
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int close_me;
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void slip_pre_exec(void *arg)
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct slip_pre_exec_data *data = arg;
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if(data->stdin >= 0) dup2(data->stdin, 0);
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dup2(data->stdout, 1);
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if(data->close_me >= 0) os_close_file(data->close_me);
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int slip_tramp(char **argv, int fd)
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct slip_pre_exec_data pe_data;
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char *output;
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int status, pid, fds[2], err, output_len;
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	err = os_pipe(fds, 1, 0);
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if(err < 0){
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printk("slip_tramp : pipe failed, err = %d\n", -err);
81a3c77c67a443e631febf708bb0c376caede31657Jeff Dike		goto out;
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	err = 0;
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pe_data.stdin = fd;
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pe_data.stdout = fds[1];
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pe_data.close_me = fds[0];
88a3c77c67a443e631febf708bb0c376caede31657Jeff Dike	err = run_helper(slip_pre_exec, &pe_data, argv, NULL);
89a3c77c67a443e631febf708bb0c376caede31657Jeff Dike	if(err < 0)
90a3c77c67a443e631febf708bb0c376caede31657Jeff Dike		goto out_close;
91a3c77c67a443e631febf708bb0c376caede31657Jeff Dike	pid = err;
92a3c77c67a443e631febf708bb0c376caede31657Jeff Dike
93a3c77c67a443e631febf708bb0c376caede31657Jeff Dike	output_len = page_size();
94a3c77c67a443e631febf708bb0c376caede31657Jeff Dike	output = um_kmalloc(output_len);
95a3c77c67a443e631febf708bb0c376caede31657Jeff Dike	if(output == NULL){
96a3c77c67a443e631febf708bb0c376caede31657Jeff Dike		printk("slip_tramp : failed to allocate output buffer\n");
97a3c77c67a443e631febf708bb0c376caede31657Jeff Dike		os_kill_process(pid, 1);
98a3c77c67a443e631febf708bb0c376caede31657Jeff Dike		err = -ENOMEM;
99a3c77c67a443e631febf708bb0c376caede31657Jeff Dike		goto out_free;
100a3c77c67a443e631febf708bb0c376caede31657Jeff Dike	}
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
102a3c77c67a443e631febf708bb0c376caede31657Jeff Dike	os_close_file(fds[1]);
103a3c77c67a443e631febf708bb0c376caede31657Jeff Dike	read_output(fds[0], output, output_len);
104a3c77c67a443e631febf708bb0c376caede31657Jeff Dike	printk("%s", output);
105a3c77c67a443e631febf708bb0c376caede31657Jeff Dike
106a3c77c67a443e631febf708bb0c376caede31657Jeff Dike	CATCH_EINTR(err = waitpid(pid, &status, 0));
107a3c77c67a443e631febf708bb0c376caede31657Jeff Dike	if(err < 0)
108a3c77c67a443e631febf708bb0c376caede31657Jeff Dike		err = errno;
109a3c77c67a443e631febf708bb0c376caede31657Jeff Dike	else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){
110a3c77c67a443e631febf708bb0c376caede31657Jeff Dike		printk("'%s' didn't exit with status 0\n", argv[0]);
111a3c77c67a443e631febf708bb0c376caede31657Jeff Dike		err = -EINVAL;
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
113a3c77c67a443e631febf708bb0c376caede31657Jeff Dike	else err = 0;
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	os_close_file(fds[0]);
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
117a3c77c67a443e631febf708bb0c376caede31657Jeff Dikeout_free:
118a3c77c67a443e631febf708bb0c376caede31657Jeff Dike	kfree(output);
119a3c77c67a443e631febf708bb0c376caede31657Jeff Dike	return err;
120a3c77c67a443e631febf708bb0c376caede31657Jeff Dike
121a3c77c67a443e631febf708bb0c376caede31657Jeff Dikeout_close:
122a3c77c67a443e631febf708bb0c376caede31657Jeff Dike	os_close_file(fds[0]);
123a3c77c67a443e631febf708bb0c376caede31657Jeff Dike	os_close_file(fds[1]);
124a3c77c67a443e631febf708bb0c376caede31657Jeff Dikeout:
125a3c77c67a443e631febf708bb0c376caede31657Jeff Dike	return err;
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int slip_open(void *data)
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct slip_data *pri = data;
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char version_buf[sizeof("nnnnn\0")];
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")];
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char *argv[] = { "uml_net", version_buf, "slip", "up", gate_buf,
1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 NULL };
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int sfd, mfd, err;
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
137a3c77c67a443e631febf708bb0c376caede31657Jeff Dike	err = get_pty();
138a3c77c67a443e631febf708bb0c376caede31657Jeff Dike	if(err < 0){
139a3c77c67a443e631febf708bb0c376caede31657Jeff Dike		printk("slip-open : Failed to open pty, err = %d\n", -err);
140a3c77c67a443e631febf708bb0c376caede31657Jeff Dike		goto out;
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
142a3c77c67a443e631febf708bb0c376caede31657Jeff Dike	mfd = err;
143a3c77c67a443e631febf708bb0c376caede31657Jeff Dike
144a3c77c67a443e631febf708bb0c376caede31657Jeff Dike	err = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0);
145a3c77c67a443e631febf708bb0c376caede31657Jeff Dike	if(err < 0){
146a3c77c67a443e631febf708bb0c376caede31657Jeff Dike		printk("Couldn't open tty for slip line, err = %d\n", -err);
147a3c77c67a443e631febf708bb0c376caede31657Jeff Dike		goto out_close;
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
149a3c77c67a443e631febf708bb0c376caede31657Jeff Dike	sfd = err;
150a3c77c67a443e631febf708bb0c376caede31657Jeff Dike
151a3c77c67a443e631febf708bb0c376caede31657Jeff Dike	if(set_up_tty(sfd))
152a3c77c67a443e631febf708bb0c376caede31657Jeff Dike		goto out_close2;
153a3c77c67a443e631febf708bb0c376caede31657Jeff Dike
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pri->slave = sfd;
155a3c77c67a443e631febf708bb0c376caede31657Jeff Dike	pri->slip.pos = 0;
156a3c77c67a443e631febf708bb0c376caede31657Jeff Dike	pri->slip.esc = 0;
1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if(pri->gate_addr != NULL){
1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		sprintf(version_buf, "%d", UML_NET_VERSION);
1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		strcpy(gate_buf, pri->gate_addr);
1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		err = slip_tramp(argv, sfd);
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if(err < 0){
1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			printk("slip_tramp failed - err = %d\n", -err);
165a3c77c67a443e631febf708bb0c376caede31657Jeff Dike			goto out_close2;
1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		err = os_get_ifname(pri->slave, pri->name);
1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if(err < 0){
1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			printk("get_ifname failed, err = %d\n", -err);
170a3c77c67a443e631febf708bb0c376caede31657Jeff Dike			goto out_close2;
1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		iter_addresses(pri->dev, open_addr, pri->name);
1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else {
1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		err = os_set_slip(sfd);
1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if(err < 0){
1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			printk("Failed to set slip discipline encapsulation - "
1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			       "err = %d\n", -err);
179a3c77c67a443e631febf708bb0c376caede31657Jeff Dike			goto out_close2;
1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return(mfd);
183a3c77c67a443e631febf708bb0c376caede31657Jeff Dikeout_close2:
184a3c77c67a443e631febf708bb0c376caede31657Jeff Dike	os_close_file(sfd);
185a3c77c67a443e631febf708bb0c376caede31657Jeff Dikeout_close:
186a3c77c67a443e631febf708bb0c376caede31657Jeff Dike	os_close_file(mfd);
187a3c77c67a443e631febf708bb0c376caede31657Jeff Dikeout:
188a3c77c67a443e631febf708bb0c376caede31657Jeff Dike	return err;
1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void slip_close(int fd, void *data)
1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct slip_data *pri = data;
1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char version_buf[sizeof("nnnnn\0")];
1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char *argv[] = { "uml_net", version_buf, "slip", "down", pri->name,
1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 NULL };
1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int err;
1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if(pri->gate_addr != NULL)
2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		iter_addresses(pri->dev, close_addr, pri->name);
2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sprintf(version_buf, "%d", UML_NET_VERSION);
2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	err = slip_tramp(argv, pri->slave);
2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if(err != 0)
2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printk("slip_tramp failed - errno = %d\n", -err);
2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	os_close_file(fd);
2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	os_close_file(pri->slave);
2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pri->slave = -1;
2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint slip_user_read(int fd, void *buf, int len, struct slip_data *pri)
2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
215a3c77c67a443e631febf708bb0c376caede31657Jeff Dike	return slip_proto_read(fd, buf, len, &pri->slip);
2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint slip_user_write(int fd, void *buf, int len, struct slip_data *pri)
2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
220a3c77c67a443e631febf708bb0c376caede31657Jeff Dike	return slip_proto_write(fd, buf, len, &pri->slip);
2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int slip_set_mtu(int mtu, void *data)
2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return(mtu);
2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void slip_add_addr(unsigned char *addr, unsigned char *netmask,
2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			  void *data)
2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct slip_data *pri = data;
2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if(pri->slave < 0) return;
2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	open_addr(addr, netmask, pri->name);
2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void slip_del_addr(unsigned char *addr, unsigned char *netmask,
2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			    void *data)
2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct slip_data *pri = data;
2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if(pri->slave < 0) return;
2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	close_addr(addr, netmask, pri->name);
2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2465e7672ec3f059f764fcc5c78216e24bb16c44dbaJeff Dikeconst struct net_user_info slip_user_info = {
2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.init		= slip_user_init,
2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.open		= slip_open,
2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.close	 	= slip_close,
2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.remove	 	= NULL,
2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.set_mtu	= slip_set_mtu,
2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.add_address	= slip_add_addr,
2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.delete_address = slip_del_addr,
2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.max_packet	= BUF_SIZE
2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
256