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