OSDN Git Service

Fix no pic
[uclinux-h8/uClinux-dist.git] / user / slattach / slattach.c
1 /* slattach.c: Bind a SLIP interface, in the same manner as pppd
2  *
3  * Copyright (C) 1998  Kenneth Albanowski <kjahds@kjahds.com>,
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  */
10
11
12 #include <stdio.h>
13 #include <unistd.h>
14 #include <stdlib.h>
15 #include <sys/stat.h>
16 #include <sys/types.h>
17 #include <sys/wait.h>
18 #include <sys/time.h>
19 #include <dirent.h>
20 #include <errno.h>
21 #include <termios.h>
22
23 #include <fcntl.h>
24 #include <linux/sockios.h>
25 #include <linux/socket.h>
26 #include <linux/if.h>
27 #include <linux/if_eql.h>
28 #include <linux/in.h>
29 #include <linux/icmp.h>
30 #include <linux/route.h>
31
32 #include <netinet/in.h>
33 #include <arpa/inet.h>
34 #include <termios.h>
35 #include <signal.h>
36 #include <sys/time.h>
37 #include <serial.h>
38
39 #include "route.h"
40
41 static char * program;
42
43 int done = 0;
44 static void sigh(int signo)
45 {
46         signal(signo, sigh);
47         done = 1;
48 }
49
50 static void slattach(int fd, const char * me, const char * them, const char * netmask, int timeout)
51 {
52         int i;
53         struct ifreq ifr;
54         struct sockaddr_in*in;
55         struct termios tty;
56
57         printf("%s: attaching SLIP\n", program);
58
59         printf("slat6\n");
60         
61         tcgetattr(fd, &tty);
62         make_raw_tty(&tty);
63         tcsetattr(fd, TCSANOW, &tty);
64
65         printf("slat7\n");
66
67         alarm(1);
68         i = N_SLIP;
69         i = ioctl(fd, TIOCSETD, &i);
70         if (i)
71                 printf("TIOCSETD returned %d, errno = %d\n", i, errno); 
72         alarm(0);
73         
74         printf("slat8\n");
75
76         i = 0;
77         i = ioctl(fd, SIOCSIFENCAP, &i);
78         if (i)
79                 printf("SIOCSIFENCAP returned %d, errno = %d\n", i, errno);     
80
81         memset(&ifr, '\0', sizeof(ifr));
82
83         strcpy(ifr.ifr_name, "<none>");
84         
85         i = ioctl(fd, SIOCGIFNAME, &ifr.ifr_name[0]);
86         if (i)
87                 printf("SIOCGIFNAME returned %d and '%s', errno = %d\n", i, (char*)&ifr.ifr_name[0], errno);
88
89         printf("slat9\n");
90         
91         /* Open raw socket */
92         open_raw_socket();
93
94         printf("slat10\n");
95         
96         setifaddr(ifr.ifr_name, me);
97
98         printf("slat11\n");
99
100         setifflags(ifr.ifr_name, IFF_UP | IFF_RUNNING | IFF_POINTOPOINT);
101         
102         setifdstaddr(ifr.ifr_name, them);
103         setifnetmask(ifr.ifr_name, "255.255.255.255");
104
105         addroute(ifr.ifr_name, RTF_UP | RTF_HOST, them, 
106                                                 0 /* no netmask */, 
107                                                 0 /* no gateway */); 
108
109         if (netmask) {
110                 unsigned long mask_in = inet_addr(netmask);
111                 unsigned long me_in = inet_addr(me);
112                 struct in_addr in_a;
113                 char * maskedme;
114                 
115                 in_a.s_addr = me_in & mask_in;
116                 maskedme = inet_ntoa(in_a);
117                 
118                 printf("my address masked by %s is %s\n",
119                         netmask, maskedme);
120                 
121                 /* masked, perhaps generic route (if netmask is 0.0.0.0)*/
122                 addroute(0, 
123                         RTF_UP, 
124                         maskedme /* destination */,
125                         netmask /* netmask */,
126                         them /* gateway */);
127         }
128         
129         close_raw_socket();
130
131         if (timeout < 0) {
132                 /* sleep till we get killed, one way or another */
133                 while(!done)
134                         pause();
135         } else {
136                 struct sockaddr_in sa;
137                 memset(&sa, 0, sizeof(sa));
138                 sa.sin_family = AF_INET;
139                 sa.sin_addr.s_addr = inet_addr(them);
140                 pinger(fd, timeout, (struct sockaddr*)&sa, sizeof(sa));
141         }
142 }
143
144 static void usage(void) {
145         fprintf(stderr, 
146   "Usage: %s [-a] [-p <port>] [-s <port-settings>] [-t <timeout>] [-m <netmask>] <my-ip> <their-ip>\n"
147   "Timeout is time in seconds before link will shut down if other side\n"
148   "does not respond to pings.\n"
149   "The -a switch adds a proxy-arp entry for this device.\n", 
150   program);
151         exit(0);
152 }
153
154 char msg[64];
155 int main(int argc, char *argv[])
156 {
157         char * port = 0;
158         char * settings = 0;
159         char * netmask = 0;
160         int timeout = -1;
161         int arp = 0;
162         int fd;
163         struct in_addr in;
164         char * me;
165         char * them;
166         
167         program = argv[0];
168         
169         if (argc<3) {
170                 usage();
171         }
172         
173         while ((argc>3) && (argv[1][0] == '-')) {
174                 if (argc < 4)
175                         usage();
176                 switch (argv[1][1]) {
177                 case 'p':
178                         port = argv[2];
179                         argc-=2;
180                         argv+=2;
181                         break;
182                 case 't':
183                         timeout = atoi(argv[2]);
184                         argc-=2;
185                         argv+=2;
186                         break;
187                 case 's':
188                         settings = argv[2];
189                         argc-=2;
190                         argv+=2;
191                         break;
192                 case 'm':
193                         netmask = argv[2];
194                         argc-=2;
195                         argv+=2;
196                         break;
197                 case 'a':
198                         arp = 1;
199                         argc--;
200                         argv++;
201                         break;
202                 default:
203                         usage();
204                 }
205         }
206         
207         if (argc != 3)
208                 usage();
209         
210         printf("slat1\n");
211         
212         me = argv[1];
213         them = argv[2];
214                 
215         if (!inet_aton(me, &in))
216                 usage();
217
218         if (!inet_aton(them, &in))
219                 usage();
220         
221
222         printf("slat2\n");
223         
224         if (port) {
225                 fd = open(port, O_RDWR|O_NONBLOCK);
226                 if (fd == -1)
227                         exit(0);
228                 if (settings)
229                         setserial(fd, settings);
230                 fcntl(fd, F_SETFL, 0);
231         } else {
232                 fd = 0;
233         }
234
235         printf("slat3\n");
236         
237         /* Print the IP addresses out to the port, in case somebody
238            needs them. */
239         
240         sprintf(msg, "Client address is %s\n", them);
241         write(fd, msg, strlen(msg));
242         sprintf(msg, "Server address is %s\n", me);
243         write(fd, msg, strlen(msg));
244         
245         signal(SIGHUP, sigh);
246         signal(SIGTERM, SIG_IGN); /* so we don't get shut down easily */
247
248         printf("slat4\n");
249         
250         if (arp)
251                 /* add arp entry so that the remote host is reachable
252                    via the local net. This only works if there is
253                    a local ethernet, and the remote IP address
254                    is within its range */
255                 arp = sifproxyarp(0, in.s_addr);
256
257         printf("slat5\n");
258
259         /* stay attached until we die, due to a signal, the control
260            lines terminating us, or timing out due to a bad connection */
261         slattach(fd, me, them, netmask, timeout);
262
263         if (arp)
264                 /* if arp was set up, tear it down */
265                 cifproxyarp(0, in.s_addr);
266         
267         close(fd);
268         return 0;
269 }
270