|
|
1.1 root 1: #include <stdio.h>
2: #include <errno.h>
3: #include <signal.h>
4: #include <sys/param.h>
5: #include <sys/types.h>
6: #include <sgtty.h>
7: #include <sys/ethernet.h>
8: #include <sys/inet/in.h>
9: #include "config.h"
10:
11: extern errno;
12:
13: #if vax
14: extern unsigned short htons();
15: #endif
16: extern int ip_ld;
17:
18: main(argc, argv)
19: char *argv[];
20: {
21: char *dev, *me, *it, *arp;
22: unsigned long myaddr, hisaddr, inaddr;
23: int ipfd, enfd, x, ld;
24:
25: if(argc < 4){
26: fprintf(stderr, "Usage: %s device my-addr his-addr [arp-device]\n",
27: argv[0]);
28: exit(1);
29: }
30: dev = argv[1];
31: me = argv[2];
32: it = argv[3];
33: if(argc > 4)
34: arp = argv[4];
35: else
36: arp = 0;
37:
38: myaddr = in_address(me);
39: if(myaddr == 0){
40: fprintf(stderr, "ipconfig: unknown host %s\n", me);
41: exit(1);
42: }
43: hisaddr = in_address(it);
44: if(hisaddr == 0){
45: fprintf(stderr, "ipconfig: unknown host/net %s\n", it);
46: exit(1);
47: }
48: signal(SIGHUP, SIG_IGN);
49: ipfd = open(dev, 2);
50: if(ipfd < 0){
51: perror(dev);
52: exit(1);
53: }
54:
55: if(arp){
56: x = htons((unsigned short)ETHERPUP_IPTYPE);
57: if(ioctl(ipfd, ENIOTYPE, &x) < 0){
58: perror("ENIOTYPE");
59: exit(1);
60: }
61: }
62: if(ioctl(ipfd, FIOPUSHLD, &ip_ld) < 0){
63: perror("PUSHLD");
64: exit(1);
65: }
66: if(ioctl(ipfd, IPIOLOCAL, &myaddr) < 0){
67: perror("IPIOLOCAL");
68: exit(1);
69: }
70: if(hisaddr & 0xff){
71: ioctl(ipfd, IPIOHOST, &hisaddr);
72: } else {
73: ioctl(ipfd, IPIONET, &hisaddr);
74: }
75: if(arp == 0){
76: pause(); /* forever, hopefully */
77: exit(0);
78: }
79:
80: if(ioctl(ipfd, IPIOARP, 0) < 0){
81: perror("IPIOARP");
82: exit(1);
83: }
84: enfd = open(arp, 2);
85: if(enfd < 0){
86: perror(arp);
87: exit(1);
88: }
89: doarp(ipfd, enfd, myaddr);
90: }
91:
92:
93: /*
94: * Address resolution
95: */
96:
97: struct ether_arp{
98: /* driver goo */
99: struct etherpup arp_ether;
100:
101: /* arp stuff */
102: u_short arp_hrd;
103: #define ARPHRD_ETHER 1
104: u_short arp_pro;
105: u_char arp_hln;
106: u_char arp_pln;
107: u_short arp_op;
108: #define ARPOP_REQUEST 1
109: #define ARPOP_REPLY 2
110: u_char arp_sha[6]; /* sender ether addr */
111: u_char arp_spa[4]; /* sender internet addr */
112: u_char arp_tha[6]; /* target ether addr */
113: u_char arp_tpa[4]; /* target internet addr */
114: };
115:
116: u_char broadaddr[6] = {
117: 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
118: };
119:
120: /* wait for ARP requests and answers */
121: doarp(ipfd, enfd, myinaddr)
122: int ipfd;
123: int enfd;
124: in_addr myinaddr;
125: {
126: u_char myenaddr[6];
127: fd_set rdfds;
128: int x;
129: char buf[2000];
130: struct goo{
131: in_addr inaddr;
132: u_char enaddr[6];
133: } goo;
134: in_addr tpa;
135:
136: x = htons((u_short)ETHERPUP_ARPTYPE);
137: if(ioctl(enfd, ENIOTYPE, &x) < 0){
138: perror("ENIOTYPE");
139: exit(1);
140: }
141: if(ioctl(enfd, ENIOADDR, myenaddr) < 0){
142: perror("ENIOADDR");
143: exit(1);
144: }
145:
146: FD_ZERO(rdfds);
147: while(1){
148: FD_SET(ipfd, rdfds);
149: FD_SET(enfd, rdfds);
150:
151: if(select(20, &rdfds, 0, 2000) < 0){
152: if(errno == EINTR)
153: continue;
154: perror("select");
155: exit(1);
156: }
157: if(FD_ISSET(ipfd, rdfds)){
158: if(read(ipfd, &tpa, sizeof(tpa)) != sizeof(tpa))
159: perror("in read");
160: arpwhohas(enfd, ipfd, myenaddr, myinaddr, tpa);
161: }
162: if(FD_ISSET(enfd, rdfds)){
163: if(read(enfd, buf, sizeof(buf)) <= 0)
164: perror("en read");
165: arpinput(ipfd, enfd, myenaddr, myinaddr, buf);
166: }
167: }
168: }
169:
170: /* broadcast an arp request */
171: arpwhohas(enfd, ipfd, myenaddr, myinaddr, addr)
172: u_char myenaddr[6];
173: in_addr addr, myinaddr;
174: {
175: struct goo{
176: in_addr inaddr;
177: u_char enaddr[6];
178: } goo;
179: struct ether_arp a;
180:
181: if(addr == (myinaddr & 0xffffff00)){
182: goo.inaddr = addr;
183: bcopy(broadaddr, goo.enaddr, sizeof(goo.enaddr));
184: ioctl(ipfd, IPIORESOLVE, &goo);
185: return;
186: }
187: if(addr == myinaddr){
188: goo.inaddr = addr;
189: bcopy(myenaddr, goo.enaddr, sizeof(goo.enaddr));
190: ioctl(ipfd, IPIORESOLVE, &goo);
191: return;
192: }
193: bcopy(broadaddr, a.arp_ether.dhost, sizeof(a.arp_ether.dhost));
194: a.arp_ether.type = htons(ETHERPUP_ARPTYPE);
195:
196: a.arp_hrd = htons(ARPHRD_ETHER);
197: a.arp_pro = htons(ETHERPUP_IPTYPE);
198: a.arp_hln = sizeof(goo.enaddr);
199: a.arp_pln = sizeof(in_addr);
200: a.arp_op = htons(ARPOP_REQUEST);
201:
202: bcopy(myenaddr, a.arp_sha, sizeof(a.arp_sha));
203: myinaddr = htonl(myinaddr);
204: bcopy(&myinaddr, a.arp_spa, sizeof(a.arp_spa));
205: addr = htonl(addr);
206: bcopy(&addr, a.arp_tpa, sizeof(a.arp_tpa));
207:
208: write(enfd, &a, sizeof(a));
209: }
210:
211: /* process an arp request */
212: arpinput(ipfd, enfd, myenaddr, myinaddr, ap)
213: u_char myenaddr[6];
214: in_addr myinaddr;
215: struct ether_arp *ap;
216: {
217: struct goo{
218: in_addr inaddr;
219: u_char enaddr[6];
220: } goo;
221: in_addr spa, tpa;
222:
223: bcopy(ap->arp_spa, &spa, sizeof(spa));
224: bcopy(ap->arp_tpa, &tpa, sizeof(tpa));
225: spa = ntohl(spa);
226: tpa = ntohl(tpa);
227:
228: if(ntohs(ap->arp_pro) != ETHERPUP_IPTYPE)
229: return;
230:
231: /* make sure noone's trying to be me */
232: if(memcmp(ap->arp_sha, myenaddr, sizeof(myenaddr)) != 0){
233: if(spa == myinaddr){
234: printf("ipconfig: forgery from me!!!\n");
235: printf("ipconfig: enaddr = ");
236: enpr(ap->arp_ether.shost);
237: return;
238: }
239: }
240:
241: /* incorporate sender's address */
242: goo.inaddr = spa;
243: bcopy(ap->arp_sha, goo.enaddr, sizeof(goo.enaddr));
244: if(ioctl(ipfd, IPIORESOLVE, &goo) < 0)
245: perror("IPIORESOLVE");
246:
247: /* send reply to a request */
248: if(ap->arp_op != ntohs(ARPOP_REQUEST))
249: return;
250: if(tpa != myinaddr)
251: return;
252: ap->arp_hrd = htons(ARPHRD_ETHER);
253: ap->arp_pro = htons(ETHERPUP_IPTYPE);
254: ap->arp_op = htons(ARPOP_REPLY);
255: tpa = htonl(spa);
256: spa = htonl(myinaddr);
257: bcopy(&tpa, ap->arp_tpa, sizeof(ap->arp_tpa));
258: bcopy(&spa, ap->arp_spa, sizeof(ap->arp_spa));
259: bcopy(ap->arp_sha, ap->arp_tha, sizeof(ap->arp_tha));
260: bcopy(myenaddr, ap->arp_sha, sizeof(ap->arp_sha));
261: bcopy(broadaddr, ap->arp_ether.dhost, sizeof(ap->arp_ether.dhost));
262: ap->arp_ether.type = htons(ETHERPUP_ARPTYPE);
263:
264: write(enfd, ap, sizeof(struct ether_arp));
265: }
266:
267: arppr(a)
268: struct ether_arp a;
269: {
270: in_addr spa, tpa;
271:
272: printf("dhost "); enpr(a.arp_ether.dhost);
273: printf("shost "); enpr(a.arp_ether.shost);
274: printf("type %x\n", ntohs(a.arp_ether.type));
275: a.arp_hrd = ntohs(a.arp_hrd);
276: a.arp_pro = ntohs(a.arp_pro);
277: a.arp_op = ntohs(a.arp_op);
278:
279: bcopy(a.arp_spa, &spa, sizeof(spa));
280: bcopy(a.arp_tpa, &tpa, sizeof(tpa));
281: tpa = ntohl(tpa);
282: spa = ntohl(spa);
283:
284: printf("hrd %d pro %x op %d spa %x tpa %x\n",
285: a.arp_hrd, a.arp_pro, a.arp_op, spa, tpa);
286: printf("sha "); enpr(a.arp_sha);
287: printf("tha "); enpr(a.arp_tha);
288: }
289:
290: enpr(en)
291: u_char *en;
292: {
293: int i;
294:
295: for(i = 0; i < 6; i++)
296: printf("%02x ", (en[i])&0xff);
297: printf("\n");
298: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.