8 #include <sys/termios.h>
10 #include <sys/signal.h>
11 #include "user_util.h"
12 #include "kern_util.h"
16 #include "slip_proto.h"
20 void slip_user_init(void *data
, void *dev
)
22 struct slip_data
*pri
= data
;
27 static int set_up_tty(int fd
)
32 if (tcgetattr(fd
, &tios
) < 0) {
33 printk("could not get initial terminal attributes\n");
37 tios
.c_cflag
= CS8
| CREAD
| HUPCL
| CLOCAL
;
38 tios
.c_iflag
= IGNBRK
| IGNPAR
;
41 for (i
= 0; i
< NCCS
; i
++)
46 cfsetospeed(&tios
, B38400
);
47 cfsetispeed(&tios
, B38400
);
49 if (tcsetattr(fd
, TCSAFLUSH
, &tios
) < 0) {
50 printk("failed to set terminal attributes\n");
56 struct slip_pre_exec_data
{
62 static void slip_pre_exec(void *arg
)
64 struct slip_pre_exec_data
*data
= arg
;
66 if(data
->stdin
>= 0) dup2(data
->stdin
, 0);
67 dup2(data
->stdout
, 1);
68 if(data
->close_me
>= 0) os_close_file(data
->close_me
);
71 static int slip_tramp(char **argv
, int fd
)
73 struct slip_pre_exec_data pe_data
;
75 int status
, pid
, fds
[2], err
, output_len
;
77 err
= os_pipe(fds
, 1, 0);
79 printk("slip_tramp : pipe failed, err = %d\n", -err
);
85 pe_data
.stdout
= fds
[1];
86 pe_data
.close_me
= fds
[0];
87 pid
= run_helper(slip_pre_exec
, &pe_data
, argv
, NULL
);
89 if(pid
< 0) err
= pid
;
91 output_len
= page_size();
92 output
= um_kmalloc(output_len
);
94 printk("slip_tramp : failed to allocate output "
97 os_close_file(fds
[1]);
98 read_output(fds
[0], output
, output_len
);
100 printk("%s", output
);
103 CATCH_EINTR(err
= waitpid(pid
, &status
, 0));
106 else if(!WIFEXITED(status
) || (WEXITSTATUS(status
) != 0)){
107 printk("'%s' didn't exit with status 0\n", argv
[0]);
112 os_close_file(fds
[0]);
117 static int slip_open(void *data
)
119 struct slip_data
*pri
= data
;
120 char version_buf
[sizeof("nnnnn\0")];
121 char gate_buf
[sizeof("nnn.nnn.nnn.nnn\0")];
122 char *argv
[] = { "uml_net", version_buf
, "slip", "up", gate_buf
,
128 printk("umn : Failed to open pty, err = %d\n", -mfd
);
131 sfd
= os_open_file(ptsname(mfd
), of_rdwr(OPENFLAGS()), 0);
133 printk("Couldn't open tty for slip line, err = %d\n", -sfd
);
137 if(set_up_tty(sfd
)) return(-1);
141 if(pri
->gate_addr
!= NULL
){
142 sprintf(version_buf
, "%d", UML_NET_VERSION
);
143 strcpy(gate_buf
, pri
->gate_addr
);
145 err
= slip_tramp(argv
, sfd
);
148 printk("slip_tramp failed - err = %d\n", -err
);
151 err
= os_get_ifname(pri
->slave
, pri
->name
);
153 printk("get_ifname failed, err = %d\n", -err
);
156 iter_addresses(pri
->dev
, open_addr
, pri
->name
);
159 err
= os_set_slip(sfd
);
161 printk("Failed to set slip discipline encapsulation - "
169 static void slip_close(int fd
, void *data
)
171 struct slip_data
*pri
= data
;
172 char version_buf
[sizeof("nnnnn\0")];
173 char *argv
[] = { "uml_net", version_buf
, "slip", "down", pri
->name
,
177 if(pri
->gate_addr
!= NULL
)
178 iter_addresses(pri
->dev
, close_addr
, pri
->name
);
180 sprintf(version_buf
, "%d", UML_NET_VERSION
);
182 err
= slip_tramp(argv
, pri
->slave
);
185 printk("slip_tramp failed - errno = %d\n", -err
);
187 os_close_file(pri
->slave
);
191 int slip_user_read(int fd
, void *buf
, int len
, struct slip_data
*pri
)
193 int i
, n
, size
, start
;
197 while(i
< pri
->more
) {
198 size
= slip_unesc(pri
->ibuf
[i
++],
199 pri
->ibuf
, &pri
->pos
, &pri
->esc
);
201 memcpy(buf
, pri
->ibuf
, size
);
202 memmove(pri
->ibuf
, &pri
->ibuf
[i
], pri
->more
-i
);
203 pri
->more
=pri
->more
-i
;
210 n
= net_read(fd
, &pri
->ibuf
[pri
->pos
], sizeof(pri
->ibuf
) - pri
->pos
);
211 if(n
<= 0) return(n
);
214 for(i
= 0; i
< n
; i
++){
215 size
= slip_unesc(pri
->ibuf
[start
+ i
],
216 pri
->ibuf
, &pri
->pos
, &pri
->esc
);
218 memcpy(buf
, pri
->ibuf
, size
);
219 memmove(pri
->ibuf
, &pri
->ibuf
[start
+i
+1], n
-(i
+1));
227 int slip_user_write(int fd
, void *buf
, int len
, struct slip_data
*pri
)
231 actual
= slip_esc(buf
, pri
->obuf
, len
);
232 n
= net_write(fd
, pri
->obuf
, actual
);
237 static int slip_set_mtu(int mtu
, void *data
)
242 static void slip_add_addr(unsigned char *addr
, unsigned char *netmask
,
245 struct slip_data
*pri
= data
;
247 if(pri
->slave
< 0) return;
248 open_addr(addr
, netmask
, pri
->name
);
251 static void slip_del_addr(unsigned char *addr
, unsigned char *netmask
,
254 struct slip_data
*pri
= data
;
256 if(pri
->slave
< 0) return;
257 close_addr(addr
, netmask
, pri
->name
);
260 struct net_user_info slip_user_info
= {
261 .init
= slip_user_init
,
265 .set_mtu
= slip_set_mtu
,
266 .add_address
= slip_add_addr
,
267 .delete_address
= slip_del_addr
,
268 .max_packet
= BUF_SIZE
272 * Overrides for Emacs so that we follow Linus's tabbing style.
273 * Emacs will notice this stuff at the end of the file and automatically
274 * adjust the settings for this buffer only. This must remain at the end
276 * ---------------------------------------------------------------------------
278 * c-file-style: "linux"