~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/um/drivers/slip_user.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 /*
  3  * Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
  4  */
  5 
  6 #include <stdio.h>
  7 #include <stdlib.h>
  8 #include <unistd.h>
  9 #include <errno.h>
 10 #include <fcntl.h>
 11 #include <string.h>
 12 #include <termios.h>
 13 #include <sys/wait.h>
 14 #include <net_user.h>
 15 #include <os.h>
 16 #include "slip.h"
 17 #include <um_malloc.h>
 18 
 19 static int slip_user_init(void *data, void *dev)
 20 {
 21         struct slip_data *pri = data;
 22 
 23         pri->dev = dev;
 24         return 0;
 25 }
 26 
 27 static int set_up_tty(int fd)
 28 {
 29         int i;
 30         struct termios tios;
 31 
 32         if (tcgetattr(fd, &tios) < 0) {
 33                 printk(UM_KERN_ERR "could not get initial terminal "
 34                        "attributes\n");
 35                 return -1;
 36         }
 37 
 38         tios.c_cflag = CS8 | CREAD | HUPCL | CLOCAL;
 39         tios.c_iflag = IGNBRK | IGNPAR;
 40         tios.c_oflag = 0;
 41         tios.c_lflag = 0;
 42         for (i = 0; i < NCCS; i++)
 43                 tios.c_cc[i] = 0;
 44         tios.c_cc[VMIN] = 1;
 45         tios.c_cc[VTIME] = 0;
 46 
 47         cfsetospeed(&tios, B38400);
 48         cfsetispeed(&tios, B38400);
 49 
 50         if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) {
 51                 printk(UM_KERN_ERR "failed to set terminal attributes\n");
 52                 return -1;
 53         }
 54         return 0;
 55 }
 56 
 57 struct slip_pre_exec_data {
 58         int stdin_fd;
 59         int stdout_fd;
 60         int close_me;
 61 };
 62 
 63 static void slip_pre_exec(void *arg)
 64 {
 65         struct slip_pre_exec_data *data = arg;
 66 
 67         if (data->stdin_fd >= 0)
 68                 dup2(data->stdin_fd, 0);
 69         dup2(data->stdout_fd, 1);
 70         if (data->close_me >= 0)
 71                 close(data->close_me);
 72 }
 73 
 74 static int slip_tramp(char **argv, int fd)
 75 {
 76         struct slip_pre_exec_data pe_data;
 77         char *output;
 78         int pid, fds[2], err, output_len;
 79 
 80         err = os_pipe(fds, 1, 0);
 81         if (err < 0) {
 82                 printk(UM_KERN_ERR "slip_tramp : pipe failed, err = %d\n",
 83                        -err);
 84                 goto out;
 85         }
 86 
 87         err = 0;
 88         pe_data.stdin_fd = fd;
 89         pe_data.stdout_fd = fds[1];
 90         pe_data.close_me = fds[0];
 91         err = run_helper(slip_pre_exec, &pe_data, argv);
 92         if (err < 0)
 93                 goto out_close;
 94         pid = err;
 95 
 96         output_len = UM_KERN_PAGE_SIZE;
 97         output = uml_kmalloc(output_len, UM_GFP_KERNEL);
 98         if (output == NULL) {
 99                 printk(UM_KERN_ERR "slip_tramp : failed to allocate output "
100                        "buffer\n");
101                 os_kill_process(pid, 1);
102                 err = -ENOMEM;
103                 goto out_close;
104         }
105 
106         close(fds[1]);
107         read_output(fds[0], output, output_len);
108         printk("%s", output);
109 
110         err = helper_wait(pid);
111         close(fds[0]);
112 
113         kfree(output);
114         return err;
115 
116 out_close:
117         close(fds[0]);
118         close(fds[1]);
119 out:
120         return err;
121 }
122 
123 static int slip_open(void *data)
124 {
125         struct slip_data *pri = data;
126         char version_buf[sizeof("nnnnn\0")];
127         char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")];
128         char *argv[] = { "uml_net", version_buf, "slip", "up", gate_buf,
129                          NULL };
130         int sfd, mfd, err;
131 
132         err = get_pty();
133         if (err < 0) {
134                 printk(UM_KERN_ERR "slip-open : Failed to open pty, err = %d\n",
135                        -err);
136                 goto out;
137         }
138         mfd = err;
139 
140         err = open(ptsname(mfd), O_RDWR, 0);
141         if (err < 0) {
142                 printk(UM_KERN_ERR "Couldn't open tty for slip line, "
143                        "err = %d\n", -err);
144                 goto out_close;
145         }
146         sfd = err;
147 
148         err = set_up_tty(sfd);
149         if (err)
150                 goto out_close2;
151 
152         pri->slave = sfd;
153         pri->slip.pos = 0;
154         pri->slip.esc = 0;
155         if (pri->gate_addr != NULL) {
156                 sprintf(version_buf, "%d", UML_NET_VERSION);
157                 strcpy(gate_buf, pri->gate_addr);
158 
159                 err = slip_tramp(argv, sfd);
160 
161                 if (err < 0) {
162                         printk(UM_KERN_ERR "slip_tramp failed - err = %d\n",
163                                -err);
164                         goto out_close2;
165                 }
166                 err = os_get_ifname(pri->slave, pri->name);
167                 if (err < 0) {
168                         printk(UM_KERN_ERR "get_ifname failed, err = %d\n",
169                                -err);
170                         goto out_close2;
171                 }
172                 iter_addresses(pri->dev, open_addr, pri->name);
173         }
174         else {
175                 err = os_set_slip(sfd);
176                 if (err < 0) {
177                         printk(UM_KERN_ERR "Failed to set slip discipline "
178                                "encapsulation - err = %d\n", -err);
179                         goto out_close2;
180                 }
181         }
182         return mfd;
183 out_close2:
184         close(sfd);
185 out_close:
186         close(mfd);
187 out:
188         return err;
189 }
190 
191 static void slip_close(int fd, void *data)
192 {
193         struct slip_data *pri = data;
194         char version_buf[sizeof("nnnnn\0")];
195         char *argv[] = { "uml_net", version_buf, "slip", "down", pri->name,
196                          NULL };
197         int err;
198 
199         if (pri->gate_addr != NULL)
200                 iter_addresses(pri->dev, close_addr, pri->name);
201 
202         sprintf(version_buf, "%d", UML_NET_VERSION);
203 
204         err = slip_tramp(argv, pri->slave);
205 
206         if (err != 0)
207                 printk(UM_KERN_ERR "slip_tramp failed - errno = %d\n", -err);
208         close(fd);
209         close(pri->slave);
210         pri->slave = -1;
211 }
212 
213 int slip_user_read(int fd, void *buf, int len, struct slip_data *pri)
214 {
215         return slip_proto_read(fd, buf, len, &pri->slip);
216 }
217 
218 int slip_user_write(int fd, void *buf, int len, struct slip_data *pri)
219 {
220         return slip_proto_write(fd, buf, len, &pri->slip);
221 }
222 
223 static void slip_add_addr(unsigned char *addr, unsigned char *netmask,
224                           void *data)
225 {
226         struct slip_data *pri = data;
227 
228         if (pri->slave < 0)
229                 return;
230         open_addr(addr, netmask, pri->name);
231 }
232 
233 static void slip_del_addr(unsigned char *addr, unsigned char *netmask,
234                             void *data)
235 {
236         struct slip_data *pri = data;
237 
238         if (pri->slave < 0)
239                 return;
240         close_addr(addr, netmask, pri->name);
241 }
242 
243 const struct net_user_info slip_user_info = {
244         .init           = slip_user_init,
245         .open           = slip_open,
246         .close          = slip_close,
247         .remove         = NULL,
248         .add_address    = slip_add_addr,
249         .delete_address = slip_del_addr,
250         .mtu            = BUF_SIZE,
251         .max_packet     = BUF_SIZE,
252 };
253 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php