|
|
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.