Linux Audio

Check our new training course

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