#include #include #include #include #ifndef USE_NETLIB #include #include #include #include #include #else #include #endif #include "pktlib.h" #include "pktbuf.h" #include "arplib.h" static char *make_srcmacaddr(in_addr_t ipaddr) { static char macaddr[ETHER_ADDR_LEN]; ipaddr = htonl(ipaddr); macaddr[0] = 0x00; macaddr[1] = 0x11; memcpy(&macaddr[2], &ipaddr, sizeof(in_addr_t)); return macaddr; } static in_addr_t proc_ip(pktbuf_t pktbuf, in_addr_t my_ipaddr) { char *p; struct ip iphdr; struct icmp *icmphdr; int hdrsize, cksum; p = pktbuf_get_header(pktbuf); /* アラインメントずれを考慮して,ローカル領域上で処理する */ memcpy(&iphdr, p, sizeof(iphdr)); hdrsize = iphdr.ip_hl << 2; if (iphdr.ip_p != IPPROTO_ICMP) return 0; if (ntohl(iphdr.ip_dst.s_addr) != my_ipaddr) return 0; icmphdr = (struct icmp *)(p + hdrsize); if (icmphdr->icmp_type != ICMP_ECHO) return 0; fprintf(stderr, "RECV ICMP Echo %-15s", inet_ntoa(iphdr.ip_src)); fprintf(stderr, " -> %-15s\n", inet_ntoa(iphdr.ip_dst)); icmphdr->icmp_type = ICMP_ECHOREPLY; cksum = ~ntohs(icmphdr->icmp_cksum) & 0xffff; cksum += ((ICMP_ECHOREPLY << 8) - (ICMP_ECHO << 8)); cksum = (cksum & 0xffff) + (cksum>> 16); icmphdr->icmp_cksum = htons(~cksum); iphdr.ip_dst.s_addr = iphdr.ip_src.s_addr; iphdr.ip_src.s_addr = htonl(my_ipaddr); iphdr.ip_sum = 0; iphdr.ip_sum = ~pktlib_ip_checksum(&iphdr, hdrsize); fprintf(stderr, "SEND ICMP Echo Reply %-15s", inet_ntoa(iphdr.ip_src)); fprintf(stderr, " -> %-15s\n", inet_ntoa(iphdr.ip_dst)); memcpy(p, &iphdr, sizeof(iphdr)); return ntohl(iphdr.ip_dst.s_addr); } int main(int argc, char *argv[]) { pktif_t pktif; pktbuf_t pktbuf, save; arptbl_t arptbl[254]; int i; struct in_addr inaddr; in_addr_t my_ipaddr, dstaddr; struct ether_header *ehdr; /* インターフェースをオープンする(自発パケットは受信しない) */ pktif = pktif_open(argv[1], PKTIF_OPEN_FLAG_RECV_NOTSENT, 0); inet_pton(AF_INET, argv[2], &inaddr); /* IPアドレス */ my_ipaddr = ntohl(inaddr.s_addr); for (i = 0; i < 254; i++) { dstaddr = (my_ipaddr & 0xffffff00) + (i + 1); arptbl[i] = arplib_table_create(dstaddr, make_srcmacaddr(dstaddr)); } while (1) { pktbuf = pktbuf_recv(pktif, 0); /* パケットを受信 */ if (pktbuf == NULL) continue; save = pktbuf; for (i = 0; i < 254; i++) { pktbuf = pktbuf_copy(save); pktbuf = arplib_packet_proc(arptbl[i], pktbuf); pktbuf = pktbuf_send_queue(pktif, pktbuf); /* 複数パケットの送信 */ pktbuf_destroy_queue(pktbuf); } pktbuf = save; ehdr = (struct ether_header *)pktbuf_get_header(pktbuf); if (ntohs(ehdr->ether_type) != ETHERTYPE_IP) goto discard; pktbuf_delete_header(pktbuf, ETHER_HDR_LEN); for (i = 0; i < 254; i++) { dstaddr = proc_ip(pktbuf, arplib_table_get_my_ipaddr(arptbl[i])); if (dstaddr) { pktbuf = arplib_packet_make(arptbl[i], pktbuf, ETHERTYPE_IP, dstaddr); pktbuf = pktbuf_send_queue(pktif, pktbuf); /* 複数パケットの送信 */ break; } } discard: pktbuf_destroy_queue(pktbuf); } return 0; }

AltStyle によって変換されたページ (->オリジナル) /