Linux Audio

Check our new training course

Loading...
v3.5.6
  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 "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;
 59	int stdout;
 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 >= 0)
 68		dup2(data->stdin, 0);
 69	dup2(data->stdout, 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;
 89	pe_data.stdout = 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	if (set_up_tty(sfd))
149		goto out_close2;
150
151	pri->slave = sfd;
152	pri->slip.pos = 0;
153	pri->slip.esc = 0;
154	if (pri->gate_addr != NULL) {
155		sprintf(version_buf, "%d", UML_NET_VERSION);
156		strcpy(gate_buf, pri->gate_addr);
157
158		err = slip_tramp(argv, sfd);
159
160		if (err < 0) {
161			printk(UM_KERN_ERR "slip_tramp failed - err = %d\n",
162			       -err);
163			goto out_close2;
164		}
165		err = os_get_ifname(pri->slave, pri->name);
166		if (err < 0) {
167			printk(UM_KERN_ERR "get_ifname failed, err = %d\n",
168			       -err);
169			goto out_close2;
170		}
171		iter_addresses(pri->dev, open_addr, pri->name);
172	}
173	else {
174		err = os_set_slip(sfd);
175		if (err < 0) {
176			printk(UM_KERN_ERR "Failed to set slip discipline "
177			       "encapsulation - err = %d\n", -err);
178			goto out_close2;
179		}
180	}
181	return mfd;
182out_close2:
183	close(sfd);
184out_close:
185	close(mfd);
186out:
187	return err;
188}
189
190static void slip_close(int fd, void *data)
191{
192	struct slip_data *pri = data;
193	char version_buf[sizeof("nnnnn\0")];
194	char *argv[] = { "uml_net", version_buf, "slip", "down", pri->name,
195			 NULL };
196	int err;
197
198	if (pri->gate_addr != NULL)
199		iter_addresses(pri->dev, close_addr, pri->name);
200
201	sprintf(version_buf, "%d", UML_NET_VERSION);
202
203	err = slip_tramp(argv, pri->slave);
204
205	if (err != 0)
206		printk(UM_KERN_ERR "slip_tramp failed - errno = %d\n", -err);
207	close(fd);
208	close(pri->slave);
209	pri->slave = -1;
210}
211
212int slip_user_read(int fd, void *buf, int len, struct slip_data *pri)
213{
214	return slip_proto_read(fd, buf, len, &pri->slip);
215}
216
217int slip_user_write(int fd, void *buf, int len, struct slip_data *pri)
218{
219	return slip_proto_write(fd, buf, len, &pri->slip);
220}
221
222static void slip_add_addr(unsigned char *addr, unsigned char *netmask,
223			  void *data)
224{
225	struct slip_data *pri = data;
226
227	if (pri->slave < 0)
228		return;
229	open_addr(addr, netmask, pri->name);
230}
231
232static void slip_del_addr(unsigned char *addr, unsigned char *netmask,
233			    void *data)
234{
235	struct slip_data *pri = data;
236
237	if (pri->slave < 0)
238		return;
239	close_addr(addr, netmask, pri->name);
240}
241
242const struct net_user_info slip_user_info = {
243	.init		= slip_user_init,
244	.open		= slip_open,
245	.close	 	= slip_close,
246	.remove	 	= NULL,
247	.add_address	= slip_add_addr,
248	.delete_address = slip_del_addr,
249	.mtu		= BUF_SIZE,
250	.max_packet	= BUF_SIZE,
251};
v4.6
  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 <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	if (set_up_tty(sfd))
149		goto out_close2;
150
151	pri->slave = sfd;
152	pri->slip.pos = 0;
153	pri->slip.esc = 0;
154	if (pri->gate_addr != NULL) {
155		sprintf(version_buf, "%d", UML_NET_VERSION);
156		strcpy(gate_buf, pri->gate_addr);
157
158		err = slip_tramp(argv, sfd);
159
160		if (err < 0) {
161			printk(UM_KERN_ERR "slip_tramp failed - err = %d\n",
162			       -err);
163			goto out_close2;
164		}
165		err = os_get_ifname(pri->slave, pri->name);
166		if (err < 0) {
167			printk(UM_KERN_ERR "get_ifname failed, err = %d\n",
168			       -err);
169			goto out_close2;
170		}
171		iter_addresses(pri->dev, open_addr, pri->name);
172	}
173	else {
174		err = os_set_slip(sfd);
175		if (err < 0) {
176			printk(UM_KERN_ERR "Failed to set slip discipline "
177			       "encapsulation - err = %d\n", -err);
178			goto out_close2;
179		}
180	}
181	return mfd;
182out_close2:
183	close(sfd);
184out_close:
185	close(mfd);
186out:
187	return err;
188}
189
190static void slip_close(int fd, void *data)
191{
192	struct slip_data *pri = data;
193	char version_buf[sizeof("nnnnn\0")];
194	char *argv[] = { "uml_net", version_buf, "slip", "down", pri->name,
195			 NULL };
196	int err;
197
198	if (pri->gate_addr != NULL)
199		iter_addresses(pri->dev, close_addr, pri->name);
200
201	sprintf(version_buf, "%d", UML_NET_VERSION);
202
203	err = slip_tramp(argv, pri->slave);
204
205	if (err != 0)
206		printk(UM_KERN_ERR "slip_tramp failed - errno = %d\n", -err);
207	close(fd);
208	close(pri->slave);
209	pri->slave = -1;
210}
211
212int slip_user_read(int fd, void *buf, int len, struct slip_data *pri)
213{
214	return slip_proto_read(fd, buf, len, &pri->slip);
215}
216
217int slip_user_write(int fd, void *buf, int len, struct slip_data *pri)
218{
219	return slip_proto_write(fd, buf, len, &pri->slip);
220}
221
222static void slip_add_addr(unsigned char *addr, unsigned char *netmask,
223			  void *data)
224{
225	struct slip_data *pri = data;
226
227	if (pri->slave < 0)
228		return;
229	open_addr(addr, netmask, pri->name);
230}
231
232static void slip_del_addr(unsigned char *addr, unsigned char *netmask,
233			    void *data)
234{
235	struct slip_data *pri = data;
236
237	if (pri->slave < 0)
238		return;
239	close_addr(addr, netmask, pri->name);
240}
241
242const struct net_user_info slip_user_info = {
243	.init		= slip_user_init,
244	.open		= slip_open,
245	.close	 	= slip_close,
246	.remove	 	= NULL,
247	.add_address	= slip_add_addr,
248	.delete_address = slip_del_addr,
249	.mtu		= BUF_SIZE,
250	.max_packet	= BUF_SIZE,
251};