1 /* slattach.c: Bind a SLIP interface, in the same manner as pppd
3 * Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com>,
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.
16 #include <sys/types.h>
24 #include <linux/sockios.h>
25 #include <linux/socket.h>
27 #include <linux/if_eql.h>
29 #include <linux/icmp.h>
30 #include <linux/route.h>
32 #include <netinet/in.h>
33 #include <arpa/inet.h>
41 static char * program;
44 static void sigh(int signo)
50 static void slattach(int fd, const char * me, const char * them, const char * netmask, int timeout)
54 struct sockaddr_in*in;
57 printf("%s: attaching SLIP\n", program);
63 tcsetattr(fd, TCSANOW, &tty);
69 i = ioctl(fd, TIOCSETD, &i);
71 printf("TIOCSETD returned %d, errno = %d\n", i, errno);
77 i = ioctl(fd, SIOCSIFENCAP, &i);
79 printf("SIOCSIFENCAP returned %d, errno = %d\n", i, errno);
81 memset(&ifr, '\0', sizeof(ifr));
83 strcpy(ifr.ifr_name, "<none>");
85 i = ioctl(fd, SIOCGIFNAME, &ifr.ifr_name[0]);
87 printf("SIOCGIFNAME returned %d and '%s', errno = %d\n", i, (char*)&ifr.ifr_name[0], errno);
96 setifaddr(ifr.ifr_name, me);
100 setifflags(ifr.ifr_name, IFF_UP | IFF_RUNNING | IFF_POINTOPOINT);
102 setifdstaddr(ifr.ifr_name, them);
103 setifnetmask(ifr.ifr_name, "255.255.255.255");
105 addroute(ifr.ifr_name, RTF_UP | RTF_HOST, them,
110 unsigned long mask_in = inet_addr(netmask);
111 unsigned long me_in = inet_addr(me);
115 in_a.s_addr = me_in & mask_in;
116 maskedme = inet_ntoa(in_a);
118 printf("my address masked by %s is %s\n",
121 /* masked, perhaps generic route (if netmask is 0.0.0.0)*/
124 maskedme /* destination */,
125 netmask /* netmask */,
132 /* sleep till we get killed, one way or another */
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));
144 static void usage(void) {
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",
155 int main(int argc, char *argv[])
173 while ((argc>3) && (argv[1][0] == '-')) {
176 switch (argv[1][1]) {
183 timeout = atoi(argv[2]);
215 if (!inet_aton(me, &in))
218 if (!inet_aton(them, &in))
225 fd = open(port, O_RDWR|O_NONBLOCK);
229 setserial(fd, settings);
230 fcntl(fd, F_SETFL, 0);
237 /* Print the IP addresses out to the port, in case somebody
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));
245 signal(SIGHUP, sigh);
246 signal(SIGTERM, SIG_IGN); /* so we don't get shut down easily */
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);
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);
264 /* if arp was set up, tear it down */
265 cifproxyarp(0, in.s_addr);