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