xref: /csrg-svn/sbin/slattach/slattach.c (revision 26206)
1*26206Skarels #include <stdio.h>
2*26206Skarels #include <sys/types.h>
3*26206Skarels #include <sgtty.h>
4*26206Skarels #include <sys/socket.h>
5*26206Skarels #include <netinet/in.h>
6*26206Skarels #include <net/if.h>
7*26206Skarels #include <netdb.h>
8*26206Skarels #include <fcntl.h>
9*26206Skarels 
10*26206Skarels #ifndef lint
11*26206Skarels static char rcsid[] = "$Header: slattach.c,v 1.1 84/10/04 12:57:12 rick Exp $";
12*26206Skarels #endif
13*26206Skarels 
14*26206Skarels struct	ifreq ifr;
15*26206Skarels struct	sockaddr_in sin = {AF_INET};
16*26206Skarels 
17*26206Skarels #define DEFAULT_BAUD	9600
18*26206Skarels int	speed;
19*26206Skarels int	slipdisc = SLIPDISC;
20*26206Skarels 
21*26206Skarels char	devname[32];
22*26206Skarels char	hostname[32];
23*26206Skarels 
24*26206Skarels extern int errno;
25*26206Skarels 
26*26206Skarels main(argc, argv)
27*26206Skarels 	int argc;
28*26206Skarels 	char *argv[];
29*26206Skarels {
30*26206Skarels 	register FILE *fp;
31*26206Skarels 	register int fd;
32*26206Skarels 	register char *dev = argv[1];
33*26206Skarels 	struct sgttyb sgtty;
34*26206Skarels 	int n;
35*26206Skarels 
36*26206Skarels 	if (argc < 4 || argc > 5)
37*26206Skarels 		error(1, 0, "usage: %s ttyname srcaddr dstaddr [baud]\n",
38*26206Skarels 		      argv[0]);
39*26206Skarels 	speed = argc == 5 ? findspeed(atoi(argv[4])) : findspeed(DEFAULT_BAUD);
40*26206Skarels 	if (speed == 0)
41*26206Skarels 		error(1, errno, "unknown speed %s", argv[4]);
42*26206Skarels 	if (strncmp("/dev/", dev, 5)) {
43*26206Skarels 		sprintf(devname, "/dev/%s", dev);
44*26206Skarels 		dev = devname;
45*26206Skarels 	}
46*26206Skarels 	if ((fd = open(dev, O_RDWR | O_NDELAY)) < 0)
47*26206Skarels 		error(1, errno, "%s: cannot open", dev);
48*26206Skarels 	sgtty.sg_flags = RAW | ANYP;
49*26206Skarels 	sgtty.sg_ispeed = sgtty.sg_ospeed = speed;
50*26206Skarels 	if (ioctl(fd, TIOCSETP, &sgtty) < 0)
51*26206Skarels 		error(1, errno, "ioctl(TIOCSETP) on %s", dev);
52*26206Skarels 	if (ioctl(fd, TIOCSETD, &slipdisc) < 0)
53*26206Skarels 		error(1, errno, "ioctl(TIOCSETD)");
54*26206Skarels 	if (ioctl(fd, TIOCGETD, &n) < 0)
55*26206Skarels 		error(1, errno, "ioctl(TIOCGETD)");
56*26206Skarels 
57*26206Skarels 	fd = socket(AF_INET, SOCK_DGRAM, 0);
58*26206Skarels 	if (fd < 0)
59*26206Skarels 		error(1, errno, "socket(AF_INET, SOCK_DGRAM)");
60*26206Skarels 	sprintf(ifr.ifr_name, "sl%d", n);
61*26206Skarels 
62*26206Skarels #ifdef sun
63*26206Skarels 	/*
64*26206Skarels 	 * This crap is necessary because sun changed the ioctl handling so
65*26206Skarels 	 * that SIOCSIFDSTADDR ONLY gets handed the value of ifr_data, not
66*26206Skarels 	 * the whole ifr structure like any sane implementation would. This
67*26206Skarels 	 * is clearly a mistake on their part. Fortunately, sizeof (caddr_t)
68*26206Skarels 	 * == sizeof(sin.sin_addr.s_addr) if it's not on your machine, you
69*26206Skarels 	 * lose.
70*26206Skarels 	 */
71*26206Skarels 	getaddr(argv[3], &sin);
72*26206Skarels 	ifr.ifr_data = (caddr_t) sin.sin_addr.s_addr;
73*26206Skarels #else vax
74*26206Skarels 	getaddr(argv[3], (struct sockaddr_in *)&ifr.ifr_dstaddr);
75*26206Skarels #endif vax
76*26206Skarels 	if (ioctl(fd, SIOCSIFDSTADDR, (caddr_t)&ifr) < 0)
77*26206Skarels 		error(1, errno, "ioctl(SIOCSIFDSTADDR)");
78*26206Skarels 	getaddr(argv[2], (struct sockaddr_in *)&ifr.ifr_addr);
79*26206Skarels 	if (ioctl(fd, SIOCSIFADDR, (caddr_t)&ifr) < 0)
80*26206Skarels 		error(1, errno, "ioctl(SIOCSIFADDR)");
81*26206Skarels 	for (;;)
82*26206Skarels 		sigpause(0);
83*26206Skarels }
84*26206Skarels 
85*26206Skarels struct sg_spds {
86*26206Skarels 	int sp_val, sp_name;
87*26206Skarels }       spds[] = {
88*26206Skarels #ifdef B50
89*26206Skarels 	{ 50, B50 },
90*26206Skarels #endif
91*26206Skarels #ifdef B75
92*26206Skarels 	{ 75, B75 },
93*26206Skarels #endif
94*26206Skarels #ifdef B110
95*26206Skarels 	{ 110, B110 },
96*26206Skarels #endif
97*26206Skarels #ifdef B150
98*26206Skarels 	{ 150, B150 },
99*26206Skarels #endif
100*26206Skarels #ifdef B200
101*26206Skarels 	{ 200, B200 },
102*26206Skarels #endif
103*26206Skarels #ifdef B300
104*26206Skarels 	{ 300, B300 },
105*26206Skarels #endif
106*26206Skarels #ifdef B600
107*26206Skarels 	{ 600, B600 },
108*26206Skarels #endif
109*26206Skarels #ifdef B1200
110*26206Skarels 	{ 1200, B1200 },
111*26206Skarels #endif
112*26206Skarels #ifdef B1800
113*26206Skarels 	{ 1800, B1800 },
114*26206Skarels #endif
115*26206Skarels #ifdef B2000
116*26206Skarels 	{ 2000, B2000 },
117*26206Skarels #endif
118*26206Skarels #ifdef B2400
119*26206Skarels 	{ 2400, B2400 },
120*26206Skarels #endif
121*26206Skarels #ifdef B3600
122*26206Skarels 	{ 3600, B3600 },
123*26206Skarels #endif
124*26206Skarels #ifdef B4800
125*26206Skarels 	{ 4800, B4800 },
126*26206Skarels #endif
127*26206Skarels #ifdef B7200
128*26206Skarels 	{ 7200, B7200 },
129*26206Skarels #endif
130*26206Skarels #ifdef B9600
131*26206Skarels 	{ 9600, B9600 },
132*26206Skarels #endif
133*26206Skarels #ifdef EXTA
134*26206Skarels 	{ 19200, EXTA },
135*26206Skarels #endif
136*26206Skarels #ifdef EXTB
137*26206Skarels 	{ 38400, EXTB },
138*26206Skarels #endif
139*26206Skarels 	{ 0, 0 }
140*26206Skarels };
141*26206Skarels 
142*26206Skarels findspeed(speed)
143*26206Skarels 	register int speed;
144*26206Skarels {
145*26206Skarels 	register struct sg_spds *sp;
146*26206Skarels 
147*26206Skarels 	sp = spds;
148*26206Skarels 	while (sp->sp_val && sp->sp_val != speed)
149*26206Skarels 		sp++;
150*26206Skarels 	return (sp->sp_name);
151*26206Skarels }
152*26206Skarels 
153*26206Skarels struct in_addr inet_makeaddr();
154*26206Skarels 
155*26206Skarels getaddr(s, sin)
156*26206Skarels 	char *s;
157*26206Skarels 	register struct sockaddr_in *sin;
158*26206Skarels {
159*26206Skarels 	register struct hostent *hp;
160*26206Skarels 	register struct netent *np;
161*26206Skarels 	int val;
162*26206Skarels 
163*26206Skarels 	bzero(sin, sizeof(struct sockaddr_in));
164*26206Skarels 	hp = gethostbyname(s);
165*26206Skarels 	if (hp) {
166*26206Skarels 		sin->sin_family = hp->h_addrtype;
167*26206Skarels 		bcopy(hp->h_addr, (char *) &sin->sin_addr, hp->h_length);
168*26206Skarels 		return;
169*26206Skarels 	}
170*26206Skarels 	np = getnetbyname(s);
171*26206Skarels 	if (np) {
172*26206Skarels 		sin->sin_family = np->n_addrtype;
173*26206Skarels 		sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY);
174*26206Skarels 		return;
175*26206Skarels 	}
176*26206Skarels 	sin->sin_family = AF_INET;
177*26206Skarels 	val = inet_addr(s);
178*26206Skarels 	if (val != -1) {
179*26206Skarels 		sin->sin_addr.s_addr = val;
180*26206Skarels 		return;
181*26206Skarels 	}
182*26206Skarels 	val = inet_network(s);
183*26206Skarels 	if (val != -1) {
184*26206Skarels 		sin->sin_addr = inet_makeaddr(val, INADDR_ANY);
185*26206Skarels 		return;
186*26206Skarels 	}
187*26206Skarels 	error(1, 0, "%s: bad value\n", s);
188*26206Skarels }
189