slip_user.c revision 43f5b3085fdd27c4edf535d938b2cb0ccead4f75
1cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike/* 2cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike * Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) 3cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike * Licensed under the GPL. 4cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike */ 5cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <stdio.h> 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <stdlib.h> 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <unistd.h> 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <errno.h> 10cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike#include <fcntl.h> 11cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike#include <string.h> 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <sys/termios.h> 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <sys/wait.h> 14cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike#include "kern_constants.h" 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "net_user.h" 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "os.h" 17cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike#include "slip.h" 18c13e569073b89eb75216a2551e89ae93ad1f9951Paolo 'Blaisorblade' Giarrusso#include "um_malloc.h" 19cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike#include "user.h" 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21f34d9d2dcb7f17b64124841345b23adc0843e7a5Jeff Dikestatic int slip_user_init(void *data, void *dev) 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct slip_data *pri = data; 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pri->dev = dev; 26f34d9d2dcb7f17b64124841345b23adc0843e7a5Jeff Dike return 0; 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int set_up_tty(int fd) 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct termios tios; 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tcgetattr(fd, &tios) < 0) { 35cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike printk(UM_KERN_ERR "could not get initial terminal " 36cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike "attributes\n"); 37cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike return -1; 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tios.c_cflag = CS8 | CREAD | HUPCL | CLOCAL; 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tios.c_iflag = IGNBRK | IGNPAR; 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tios.c_oflag = 0; 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tios.c_lflag = 0; 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < NCCS; i++) 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tios.c_cc[i] = 0; 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tios.c_cc[VMIN] = 1; 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tios.c_cc[VTIME] = 0; 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cfsetospeed(&tios, B38400); 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cfsetispeed(&tios, B38400); 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) { 53cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike printk(UM_KERN_ERR "failed to set terminal attributes\n"); 54cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike return -1; 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 56cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike return 0; 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct slip_pre_exec_data { 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int stdin; 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int stdout; 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int close_me; 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void slip_pre_exec(void *arg) 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct slip_pre_exec_data *data = arg; 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 69cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike if (data->stdin >= 0) 70cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike dup2(data->stdin, 0); 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dup2(data->stdout, 1); 72cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike if (data->close_me >= 0) 73cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike close(data->close_me); 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int slip_tramp(char **argv, int fd) 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct slip_pre_exec_data pe_data; 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char *output; 804dbed85a35ed37d9608f4f32e5d69efa775d6223Stanislaw Gruszka int pid, fds[2], err, output_len; 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = os_pipe(fds, 1, 0); 83cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike if (err < 0) { 84cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike printk(UM_KERN_ERR "slip_tramp : pipe failed, err = %d\n", 85cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike -err); 86a3c77c67a443e631febf708bb0c376caede31657Jeff Dike goto out; 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = 0; 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pe_data.stdin = fd; 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pe_data.stdout = fds[1]; 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pe_data.close_me = fds[0]; 93c43990162fc7f9d2f15a12797fdc6f9c0905f704Jeff Dike err = run_helper(slip_pre_exec, &pe_data, argv); 94cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike if (err < 0) 95a3c77c67a443e631febf708bb0c376caede31657Jeff Dike goto out_close; 96a3c77c67a443e631febf708bb0c376caede31657Jeff Dike pid = err; 97a3c77c67a443e631febf708bb0c376caede31657Jeff Dike 981ffb9164f51094b7105ce9f81600b222ddf5b82cJeff Dike output_len = UM_KERN_PAGE_SIZE; 9943f5b3085fdd27c4edf535d938b2cb0ccead4f75Jeff Dike output = uml_kmalloc(output_len, UM_GFP_KERNEL); 100cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike if (output == NULL) { 101cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike printk(UM_KERN_ERR "slip_tramp : failed to allocate output " 102cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike "buffer\n"); 103a3c77c67a443e631febf708bb0c376caede31657Jeff Dike os_kill_process(pid, 1); 104a3c77c67a443e631febf708bb0c376caede31657Jeff Dike err = -ENOMEM; 105a3c77c67a443e631febf708bb0c376caede31657Jeff Dike goto out_free; 106a3c77c67a443e631febf708bb0c376caede31657Jeff Dike } 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 108cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike close(fds[1]); 109a3c77c67a443e631febf708bb0c376caede31657Jeff Dike read_output(fds[0], output, output_len); 110a3c77c67a443e631febf708bb0c376caede31657Jeff Dike printk("%s", output); 111a3c77c67a443e631febf708bb0c376caede31657Jeff Dike 1121aa351a308d2c3ddb92b6cc45083fc54271d0010Jeff Dike err = helper_wait(pid); 113cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike close(fds[0]); 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 115a3c77c67a443e631febf708bb0c376caede31657Jeff Dikeout_free: 116a3c77c67a443e631febf708bb0c376caede31657Jeff Dike kfree(output); 117a3c77c67a443e631febf708bb0c376caede31657Jeff Dike return err; 118a3c77c67a443e631febf708bb0c376caede31657Jeff Dike 119a3c77c67a443e631febf708bb0c376caede31657Jeff Dikeout_close: 120cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike close(fds[0]); 121cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike close(fds[1]); 122a3c77c67a443e631febf708bb0c376caede31657Jeff Dikeout: 123a3c77c67a443e631febf708bb0c376caede31657Jeff Dike return err; 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int slip_open(void *data) 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct slip_data *pri = data; 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char version_buf[sizeof("nnnnn\0")]; 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")]; 131cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike char *argv[] = { "uml_net", version_buf, "slip", "up", gate_buf, 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NULL }; 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int sfd, mfd, err; 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 135a3c77c67a443e631febf708bb0c376caede31657Jeff Dike err = get_pty(); 136cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike if (err < 0) { 137cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike printk(UM_KERN_ERR "slip-open : Failed to open pty, err = %d\n", 138cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike -err); 139a3c77c67a443e631febf708bb0c376caede31657Jeff Dike goto out; 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 141a3c77c67a443e631febf708bb0c376caede31657Jeff Dike mfd = err; 142a3c77c67a443e631febf708bb0c376caede31657Jeff Dike 143cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike err = open(ptsname(mfd), O_RDWR, 0); 144cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike if (err < 0) { 145cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike printk(UM_KERN_ERR "Couldn't open tty for slip line, " 146cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike "err = %d\n", -err); 147a3c77c67a443e631febf708bb0c376caede31657Jeff Dike goto out_close; 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 149a3c77c67a443e631febf708bb0c376caede31657Jeff Dike sfd = err; 150a3c77c67a443e631febf708bb0c376caede31657Jeff Dike 151cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff 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; 157cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike 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 163cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike if (err < 0) { 164cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike printk(UM_KERN_ERR "slip_tramp failed - err = %d\n", 165cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike -err); 166a3c77c67a443e631febf708bb0c376caede31657Jeff Dike goto out_close2; 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = os_get_ifname(pri->slave, pri->name); 169cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike if (err < 0) { 170cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike printk(UM_KERN_ERR "get_ifname failed, err = %d\n", 171cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike -err); 172a3c77c67a443e631febf708bb0c376caede31657Jeff Dike goto out_close2; 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iter_addresses(pri->dev, open_addr, pri->name); 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else { 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = os_set_slip(sfd); 178cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike if (err < 0) { 179cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike printk(UM_KERN_ERR "Failed to set slip discipline " 180cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike "encapsulation - err = %d\n", -err); 181a3c77c67a443e631febf708bb0c376caede31657Jeff Dike goto out_close2; 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 184cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike return mfd; 185a3c77c67a443e631febf708bb0c376caede31657Jeff Dikeout_close2: 186cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike close(sfd); 187a3c77c67a443e631febf708bb0c376caede31657Jeff Dikeout_close: 188cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike close(mfd); 189a3c77c67a443e631febf708bb0c376caede31657Jeff Dikeout: 190a3c77c67a443e631febf708bb0c376caede31657Jeff Dike return err; 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void slip_close(int fd, void *data) 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct slip_data *pri = data; 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char version_buf[sizeof("nnnnn\0")]; 197cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike char *argv[] = { "uml_net", version_buf, "slip", "down", pri->name, 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NULL }; 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 201cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike if (pri->gate_addr != NULL) 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iter_addresses(pri->dev, close_addr, pri->name); 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sprintf(version_buf, "%d", UML_NET_VERSION); 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = slip_tramp(argv, pri->slave); 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 208cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike if (err != 0) 209cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike printk(UM_KERN_ERR "slip_tramp failed - errno = %d\n", -err); 210cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike close(fd); 211cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike close(pri->slave); 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pri->slave = -1; 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint slip_user_read(int fd, void *buf, int len, struct slip_data *pri) 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 217a3c77c67a443e631febf708bb0c376caede31657Jeff Dike return slip_proto_read(fd, buf, len, &pri->slip); 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint slip_user_write(int fd, void *buf, int len, struct slip_data *pri) 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 222a3c77c67a443e631febf708bb0c376caede31657Jeff Dike return slip_proto_write(fd, buf, len, &pri->slip); 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void slip_add_addr(unsigned char *addr, unsigned char *netmask, 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void *data) 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct slip_data *pri = data; 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 230cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike if (pri->slave < 0) 231cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike return; 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds open_addr(addr, netmask, pri->name); 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void slip_del_addr(unsigned char *addr, unsigned char *netmask, 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void *data) 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct slip_data *pri = data; 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 240cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike if (pri->slave < 0) 241cd1ae0e49bdd814cfaa2e5ab28cff21a30e20085Jeff Dike return; 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds close_addr(addr, netmask, pri->name); 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2455e7672ec3f059f764fcc5c78216e24bb16c44dbaJeff Dikeconst struct net_user_info slip_user_info = { 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .init = slip_user_init, 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .open = slip_open, 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .close = slip_close, 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .remove = NULL, 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .add_address = slip_add_addr, 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .delete_address = slip_del_addr, 252b53f35a8093e6aed7e8e880eaa0b89a3d2fdfb0aJeff Dike .mtu = BUF_SIZE, 253b53f35a8093e6aed7e8e880eaa0b89a3d2fdfb0aJeff Dike .max_packet = BUF_SIZE, 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 255