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