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