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