8 #include <sys/termios.h>
10 #include <sys/signal.h>
11 #include "kern_util.h"
15 #include "slip_common.h"
17 #include "um_malloc.h"
18 #include "kern_constants.h"
20 static int slip_user_init(void *data
, void *dev
)
22 struct slip_data
*pri
= data
;
28 static int set_up_tty(int fd
)
33 if (tcgetattr(fd
, &tios
) < 0) {
34 printk("could not get initial terminal attributes\n");
38 tios
.c_cflag
= CS8
| CREAD
| HUPCL
| CLOCAL
;
39 tios
.c_iflag
= IGNBRK
| IGNPAR
;
42 for (i
= 0; i
< NCCS
; i
++)
47 cfsetospeed(&tios
, B38400
);
48 cfsetispeed(&tios
, B38400
);
50 if (tcsetattr(fd
, TCSAFLUSH
, &tios
) < 0) {
51 printk("failed to set terminal attributes\n");
57 struct slip_pre_exec_data
{
63 static void slip_pre_exec(void *arg
)
65 struct slip_pre_exec_data
*data
= arg
;
67 if(data
->stdin
>= 0) dup2(data
->stdin
, 0);
68 dup2(data
->stdout
, 1);
69 if(data
->close_me
>= 0) os_close_file(data
->close_me
);
72 static int slip_tramp(char **argv
, int fd
)
74 struct slip_pre_exec_data pe_data
;
76 int status
, pid
, fds
[2], err
, output_len
;
78 err
= os_pipe(fds
, 1, 0);
80 printk("slip_tramp : pipe failed, err = %d\n", -err
);
86 pe_data
.stdout
= fds
[1];
87 pe_data
.close_me
= fds
[0];
88 err
= run_helper(slip_pre_exec
, &pe_data
, argv
, NULL
);
93 output_len
= UM_KERN_PAGE_SIZE
;
94 output
= um_kmalloc(output_len
);
96 printk("slip_tramp : failed to allocate output buffer\n");
97 os_kill_process(pid
, 1);
102 os_close_file(fds
[1]);
103 read_output(fds
[0], output
, output_len
);
104 printk("%s", output
);
106 CATCH_EINTR(err
= waitpid(pid
, &status
, 0));
109 else if(!WIFEXITED(status
) || (WEXITSTATUS(status
) != 0)){
110 printk("'%s' didn't exit with status 0\n", argv
[0]);
115 os_close_file(fds
[0]);
122 os_close_file(fds
[0]);
123 os_close_file(fds
[1]);
128 static int slip_open(void *data
)
130 struct slip_data
*pri
= data
;
131 char version_buf
[sizeof("nnnnn\0")];
132 char gate_buf
[sizeof("nnn.nnn.nnn.nnn\0")];
133 char *argv
[] = { "uml_net", version_buf
, "slip", "up", gate_buf
,
139 printk("slip-open : Failed to open pty, err = %d\n", -err
);
144 err
= os_open_file(ptsname(mfd
), of_rdwr(OPENFLAGS()), 0);
146 printk("Couldn't open tty for slip line, err = %d\n", -err
);
157 if(pri
->gate_addr
!= NULL
){
158 sprintf(version_buf
, "%d", UML_NET_VERSION
);
159 strcpy(gate_buf
, pri
->gate_addr
);
161 err
= slip_tramp(argv
, sfd
);
164 printk("slip_tramp failed - err = %d\n", -err
);
167 err
= os_get_ifname(pri
->slave
, pri
->name
);
169 printk("get_ifname failed, err = %d\n", -err
);
172 iter_addresses(pri
->dev
, open_addr
, pri
->name
);
175 err
= os_set_slip(sfd
);
177 printk("Failed to set slip discipline encapsulation - "
191 static void slip_close(int fd
, void *data
)
193 struct slip_data
*pri
= data
;
194 char version_buf
[sizeof("nnnnn\0")];
195 char *argv
[] = { "uml_net", version_buf
, "slip", "down", pri
->name
,
199 if(pri
->gate_addr
!= NULL
)
200 iter_addresses(pri
->dev
, close_addr
, pri
->name
);
202 sprintf(version_buf
, "%d", UML_NET_VERSION
);
204 err
= slip_tramp(argv
, pri
->slave
);
207 printk("slip_tramp failed - errno = %d\n", -err
);
209 os_close_file(pri
->slave
);
213 int slip_user_read(int fd
, void *buf
, int len
, struct slip_data
*pri
)
215 return slip_proto_read(fd
, buf
, len
, &pri
->slip
);
218 int slip_user_write(int fd
, void *buf
, int len
, struct slip_data
*pri
)
220 return slip_proto_write(fd
, buf
, len
, &pri
->slip
);
223 static int slip_set_mtu(int mtu
, void *data
)
228 static void slip_add_addr(unsigned char *addr
, unsigned char *netmask
,
231 struct slip_data
*pri
= data
;
233 if(pri
->slave
< 0) return;
234 open_addr(addr
, netmask
, pri
->name
);
237 static void slip_del_addr(unsigned char *addr
, unsigned char *netmask
,
240 struct slip_data
*pri
= data
;
242 if(pri
->slave
< 0) return;
243 close_addr(addr
, netmask
, pri
->name
);
246 const struct net_user_info slip_user_info
= {
247 .init
= slip_user_init
,
251 .set_mtu
= slip_set_mtu
,
252 .add_address
= slip_add_addr
,
253 .delete_address
= slip_del_addr
,
254 .max_packet
= BUF_SIZE