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