Version:
~ [ 0.6-2.3.46 ] ~
Architecture:
~ [ um ] ~
** Warning: Cannot open xref database.
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <stdlib.h>
4 #include <fcntl.h>
5 #include <termios.h>
6 #include <wait.h>
7 #include <signal.h>
8 #include <sched.h>
9 #include <errno.h>
10 #include <sys/socket.h>
11 #include <sys/ioctl.h>
12 #include <sys/vfs.h>
13 #include "umn.h"
14 #include "user_util.h"
15 #include "kern_util.h"
16 #include "user.h"
17
18 extern char *ptsname(int);
19
20 char buff[3000];
21
22 /* SLIP protocol characters. */
23 #define END 0300 /* indicates end of frame */
24 #define ESC 0333 /* indicates byte stuffing */
25 #define ESC_END 0334 /* ESC ESC_END means END 'data' */
26 #define ESC_ESC 0335 /* ESC ESC_ESC means ESC 'data' */
27
28 static int slip_esc(unsigned char *s, unsigned char *d, int len)
29 {
30 unsigned char *ptr = d;
31 unsigned char c;
32
33 /*
34 * Send an initial END character to flush out any
35 * data that may have accumulated in the receiver
36 * due to line noise.
37 */
38
39 *ptr++ = END;
40
41 /*
42 * For each byte in the packet, send the appropriate
43 * character sequence, according to the SLIP protocol.
44 */
45
46 while (len-- > 0) {
47 switch(c = *s++) {
48 case END:
49 *ptr++ = ESC;
50 *ptr++ = ESC_END;
51 break;
52 case ESC:
53 *ptr++ = ESC;
54 *ptr++ = ESC_ESC;
55 break;
56 default:
57 *ptr++ = c;
58 break;
59 }
60 }
61 *ptr++ = END;
62 return (ptr - d);
63 }
64
65 int umn_send_packet(int fd, void *data, int len)
66 {
67 int actual, n;
68
69 actual = slip_esc(data, buff, len);
70 n = write(fd, buff, actual);
71 if(n == actual) return(0);
72 else return(1);
73 }
74
75 static void umn_read(int fd)
76 {
77 int i, n;
78
79 n = read(fd, buff, sizeof(buff)/sizeof(buff[0]));
80 if(n == 0) printk("umn_read hit EOF\n");
81 else if(n < 0){
82 if(errno == EIO){
83 close(fd);
84 return;
85 }
86 printk("umn_read had error, errno = %d\n", errno);
87 }
88 else {
89 for(i=0;i<n;i++)
90 slip_unesc(buff[i]);
91 }
92 }
93
94 static int set_up_tty(int fd)
95 {
96 int i;
97 struct termios tios;
98
99 if (tcgetattr(fd, &tios) < 0) {
100 printk("could not get initial terminal attributes\n");
101 return(-1);
102 }
103
104 tios.c_cflag = CS8 | CREAD | HUPCL | CLOCAL;
105 tios.c_iflag = IGNBRK | IGNPAR;
106 tios.c_oflag = 0;
107 tios.c_lflag = 0;
108 for (i = 0; i < NCCS; i++)
109 tios.c_cc[i] = 0;
110 tios.c_cc[VMIN] = 1;
111 tios.c_cc[VTIME] = 0;
112
113 cfsetospeed(&tios, B38400);
114 cfsetispeed(&tios, B38400);
115
116 if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) {
117 printk("failed to set terminal attributes\n");
118 return(-1);
119 }
120 return(0);
121 }
122
123 static int run_ifconfig(int (*proc)(void *), void *arg)
124 {
125 unsigned long stack;
126 int pid, status;
127
128 stack = alloc_stack();
129 pid = clone(proc, (void *) stack_sp(stack), SIGCHLD, arg);
130 if(pid < 0){
131 printk("clone of ifconfig failed\n");
132 return(-1);
133 }
134 pid = waitpid(pid, &status, 0);
135 if(pid < 0){
136 printk("wait for um_ifconfig failed\n");
137 return(-1);
138 }
139 if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){
140 printk("um_ifconfig failed\n");
141 return(-1);
142 }
143 free_stack(stack);
144 return(0);
145 }
146
147 int open_umn_tty(int *orig_disc_out, int *slave_out, int *slipno_out)
148 {
149 struct statfs buf;
150 int sfd, mfd, disc, sencap, n;
151 char slip_name[sizeof("slxxxx")];
152
153 if((mfd = open("/dev/ptmx", O_RDWR)) < 0){
154 printk("Couldn't open tty for slip line\n");
155 return(-1);
156 }
157 if(statfs(ptsname(mfd), &buf) < 0){
158 printk("statfs failed\n");
159 return(-1);
160 }
161 if(unlockpt(mfd) < 0){
162 printk("Couldn't open tty for slip line\n");
163 return(-1);
164 }
165 if((sfd = open(ptsname(mfd), O_RDWR)) < 0){
166 printk("Couldn't open tty for slip line\n");
167 return(-1);
168 }
169 if(set_up_tty(sfd)) return(-1);
170 disc = N_SLIP;
171 sencap = 0;
172 if((ioctl(sfd, TIOCGETD, &orig_disc_out) < 0) ||
173 ((n = ioctl(sfd, TIOCSETD, &disc)) < 0) ||
174 (ioctl(sfd, SIOCSIFENCAP, &sencap) < 0)){
175 printk("Couldn't set up slip\n");
176 return(-1);
177 }
178 sprintf(slip_name, "sl%d", n);
179 add_input_request(INPUT_NEW_FD, mfd, umn_read);
180 *slave_out = sfd;
181 *slipno_out = n;
182 return(mfd);
183 }
184
185 static int ifconfig_addr_tramp(void *arg)
186 {
187 char *args[] = { "um_ifconfig", "-n", NULL, "192.168.0.254",
188 "pointopoint", NULL, NULL };
189 char **more_args;
190
191 more_args = arg;
192 args[2] = more_args[0];
193 args[5] = more_args[1];
194 execvp("um_ifconfig", args);
195 return(-1);
196 }
197
198 int set_umn_addr(int slipno, char *addr)
199 {
200 char slip_name[sizeof("slxxxx")], *args[2];
201
202 sprintf(slip_name, "sl%d", slipno);
203 args[0] = slip_name;
204 args[1] = addr;
205 return(run_ifconfig(ifconfig_addr_tramp, args));
206 }
207
208 void close_umn_tty(int master, int slave, int orig_disc)
209 {
210 ioctl(slave, TIOCSETD, &orig_disc);
211 close(slave);
212 close(master);
213 }
214
215
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.