//=============================== //I tried to do this same concept using LIBNET_RAW4 instead of LIBNET_LINK so //I wouldn't have to worry about the ethernet header. But something weird happens when I //try to do this. If there is already an established connection.. e.g. 70.116.23.2:3779 to //192.168.0.2:6112, if we send the packet using raw4, in tcpdump we get //70.116.23.2:1024 --> 192.168.0.2:6112. I am really not sure why it won't send the correct //source port if that connection is already established, but using LIBNET_LINK seems to not //have this problem. I believe it is a kernel related issue. void TcpKill::Execute(const wxString &sIp, u_int nPort) { char szErrBuf[LIBNET_ERRBUF_SIZE]; libnet_ptag_t ip; libnet_ptag_t tcp; wxString sSniffDevice = CONFIG(wxString, "Network/SniffDevice"); wxString sGameHost = CONFIG(wxString, "Network/GameHost"); int nGamePort = CONFIG(int, "Network/GamePort"); shared_ptr<NodeInfo> pNodeInfo = Info::Get()->GetNodeInfo(sIp, nPort); if (!pNodeInfo) { //Interface::Get()->Output(wxString::Format("Can't find %s:%d in net info map.", m_sIp.c_str(), m_nPort), OUTPUT_ERROR); return; } NetInfo &netInfo = Info::Get()->GetNetInfo(); //This is pretty inefficient since I constantly init libnet and destroy it. It would be better //if we could init once and just keep changing the sequence number and destination ip. for (u_int x = 0; x < m_nSeverity; x++) { u_int32_t seq_out = pNodeInfo->last_sentack; libnet_t *pLibnet = libnet_init(LIBNET_LINK, const_cast<char *>(sSniffDevice.c_str()), szErrBuf); libnet_seed_prand(pLibnet); tcp = libnet_build_tcp(nPort, nGamePort, seq_out, 0, TH_RST, 0, 0, 0, LIBNET_TCP_H, NULL, 0, pLibnet, 0); u_long src_ip = libnet_name2addr4(pLibnet, const_cast<char *>(sIp.c_str()), LIBNET_DONT_RESOLVE); u_long dst_ip = libnet_name2addr4(pLibnet, const_cast<char *>(sGameHost.c_str()), LIBNET_DONT_RESOLVE); ip = libnet_build_ipv4(sizeof(net_ip) + sizeof(net_tcp), 0, libnet_get_prand(LIBNET_PRu16), 0, 64, IPPROTO_TCP, 0, src_ip, dst_ip, NULL, 0, pLibnet, 0); libnet_autobuild_ethernet(netInfo.gamehost_ether, ETHERTYPE_IP, pLibnet); libnet_write(pLibnet); libnet_destroy(pLibnet); } }
libnet_ptag_t libnet_autobuild_link(u_int8_t *dst, u_int8_t *oui, u_int16_t type, libnet_t *l) { u_int8_t org[3] = {0x00, 0x00, 0x00}; switch (l->link_type) { /* add FDDI */ case DLT_EN10MB: return (libnet_autobuild_ethernet(dst, type, l)); case DLT_IEEE802: return (libnet_autobuild_token_ring(LIBNET_TOKEN_RING_FRAME, LIBNET_TOKEN_RING_LLC_FRAME, dst, LIBNET_SAP_SNAP, LIBNET_SAP_SNAP, 0x03, org, TOKEN_RING_TYPE_IP, l)); default: break; } snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): linktype %d not supported\n", __func__, l->link_type); return (-1); }
int main(int argc, char *argv[]) { int c, len; libnet_t *l; libnet_ptag_t t; u_char *dst; u_long ip; u_char dhost[5] = {0x01, 0x00, 0x0c, 0x00, 0x00}; u_char snap[6] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00}; char *device = NULL; char errbuf[LIBNET_ERRBUF_SIZE]; printf("libnet 1.1 packet shaping: [ISL]\n"); device = NULL; dst = NULL; while ((c = getopt(argc, argv, "i:d:")) != EOF) { switch (c) { case 'd': dst = libnet_hex_aton(optarg, &len); break; case 'i': device = optarg; break; } } if (dst == NULL) { fprintf(stderr, "usage %s -d dst [-i interface]\n", argv[0]); exit(EXIT_FAILURE); } /* * Initialize the library. Root priviledges are required. */ l = libnet_init( LIBNET_LINK, /* injection type */ device, /* network interface */ errbuf); /* errbuf */ if (l == NULL) { fprintf(stderr, "libnet_init() failed: %s", errbuf); exit(EXIT_FAILURE); } ip = libnet_get_ipaddr4(l); t = libnet_build_arp( ARPHRD_ETHER, /* hardware addr */ ETHERTYPE_IP, /* protocol addr */ 6, /* hardware addr size */ 4, /* protocol addr size */ ARPOP_REPLY, /* operation type */ enet_src, /* sender hardware addr */ (u_char *)&ip, /* sender protocol addr */ enet_dst, /* target hardware addr */ (u_char *)&ip, /* target protocol addr */ NULL, /* payload */ 0, /* payload size */ l, /* libnet handle */ 0); /* libnet id */ if (t == -1) { fprintf(stderr, "Can't build ARP header: %s\n", libnet_geterror(l)); goto bad; } t = libnet_autobuild_ethernet( dst, /* ethernet destination */ ETHERTYPE_ARP, /* protocol type */ l); /* libnet handle */ if (t == -1) { fprintf(stderr, "Can't build ethernet header: %s\n", libnet_geterror(l)); goto bad; } t = libnet_build_isl( dhost, 0x0, 0x0, enet_src, 10 + 42, snap, 10, 0x8000, 0, NULL, /* payload */ 0, /* payload size */ l, /* libnet handle */ 0); /* libnet id */ if (t == -1) { fprintf(stderr, "Can't build ISL header: %s\n", libnet_geterror(l)); goto bad; } /* * Write it to the wire. */ c = libnet_write(l); if (c == -1) { fprintf(stderr, "Write error: %s\n", libnet_geterror(l)); goto bad; } else { fprintf(stderr, "Wrote %d byte ISL packet; check the wire.\n", c); } free(dst); libnet_destroy(l); return (EXIT_SUCCESS); bad: free(dst); libnet_destroy(l); return (EXIT_FAILURE); }
static gboolean http_redirector( pcap_process_thread_param * param, gpointer user_data) { /******************************************************************* * here we use TCP * when we recv a SYN=1,ACK=0 packet, we just send a syn=1,ack=1 packet * that contains nothing * then we push a packet taht contains * HTTP/1.0 302 Found * Location: http://192.168.0.1/ * connection:close * * please visit http://192.168.0.1 * and then we reset the connection * ****************************************************************/ struct tcphdr * tcp_head; struct udphdr * udp_head; if(clientmgr_get_client_is_enable_by_mac(param->packet_linklayer_hdr+6)) { //继续交给后续代码处理 return FALSE ; } //非 enable 的客户端,现在要开始这般处理了,重定向到 ... 嘿嘿 struct iphdr * ip_head = (typeof(ip_head))(param->packet_ip_contents); if (ip_head->daddr == redirector_ip) { return TRUE; } if (ip_head->saddr == redirector_ip) { return TRUE; } //如果是在 white list .... if (whiteip && g_list_find(whiteip, GINT_TO_POINTER(ip_head->daddr))) return FALSE; if (whiteip && g_list_find(whiteip, GINT_TO_POINTER(ip_head->saddr))) return FALSE; // g_debug(_("thread %p is doing the redirect stuff"),g_thread_self()); //Retrive the tcp header and udp header tcp_head = (struct tcphdr*) ((char*) ip_head + ip_head->ihl * 4); udp_head = (struct udphdr*) ((char*) ip_head + ip_head->ihl * 4); #ifdef DEBUG_ONLY_HTTP_PORT if (tcp_head->dest != HTTP_PORT) return TRUE; #endif //初始化libnet,每个线程一个 libnet ;) init_thread_libnet(); // http 重定向 if(ip_head->protocol == IPPROTO_TCP && tcp_head->dest == HTTP_PORT) { u_int8_t tcp_flags = ((struct libnet_tcp_hdr *) tcp_head)->th_flags; if(tcp_flags == TH_SYN) { /******************************** * 对于这样的一个握手数据包 * 我们应该要建立连接了 * 回复一个syn ack 就是了 *********************************/ // here we just echo ack and syn. libnet_build_tcp(ntohs(tcp_head->dest), ntohs(tcp_head->source), tcp_head->seq, ntohl( tcp_head->seq) + 1, TH_ACK | TH_SYN, 4096, 0, 0, 20, 0, 0, libnet, 0); libnet_build_ipv4(40, 0, 0, 0x4000, 63/*ttl*/, IPPROTO_TCP, 0, ip_head->daddr, ip_head->saddr, 0, 0, libnet, 0); libnet_write(libnet); libnet_clear_packet(libnet); libnet_build_tcp(ntohs(tcp_head->dest), ntohs(tcp_head->source), tcp_head->seq, ntohl( tcp_head->seq) + 1, TH_ACK | TH_SYN, 4096, 0, 0, 20, 0, 0, libnet, 0); libnet_build_ipv4(40, 0, 0, 0x4000, 63/*ttl*/, IPPROTO_TCP, 0, ip_head->daddr, ip_head->saddr, 0, 0, libnet, 0); }else if (tcp_flags & (TH_ACK|TH_SYN) ) { /********************************************* *现在是发送页面的时候啦! *********************************************/ int SIZEHTTPHEAD = strlen((const char*) httphead); libnet_build_tcp(ntohs(tcp_head->dest), ntohs(tcp_head->source), ntohl(tcp_head->ack_seq), ntohl(tcp_head->seq) + ntohs(ip_head->tot_len) - 40, TH_ACK | TH_PUSH | TH_FIN, 4096, 0, 0, 20 + SIZEHTTPHEAD, httphead, SIZEHTTPHEAD, libnet, 0); libnet_build_ipv4(40 + SIZEHTTPHEAD, 0, 0, 0x4000, 63/*ttl*/, IPPROTO_TCP, 0, ip_head->daddr, ip_head->saddr, 0, 0, libnet, 0); } else if (tcp_flags & (TH_FIN|TH_RST)) { /********************************************************* *好,现在结束连接! ********************************************************/ libnet_build_tcp(ntohs(tcp_head->dest), ntohs(tcp_head->source), ntohl(tcp_head->ack_seq), ntohl(tcp_head->seq) + 1, TH_ACK|TH_RST, 4096, 0, 0, 20, 0, 0, libnet, 0); libnet_build_ipv4(40, 0, 0, 0x4000, 63/*ttl*/, IPPROTO_TCP, 0, ip_head->daddr, ip_head->saddr, 0, 0, libnet, 0); printf("------------------------------------------------------------------------link disconnect\n"); }else{ return FALSE; } }//其他 TCP 直接 RST else if( ip_head->protocol == IPPROTO_TCP) { libnet_build_tcp(ntohs(tcp_head->dest), ntohs(tcp_head->source), ntohl(tcp_head->ack_seq), ntohl(tcp_head->seq) + 1, TH_ACK|TH_RST, 4096, 0, 0, 20, 0, 0, libnet, 0); libnet_build_ipv4(40, 0, 0, 0x4000, 63/*ttl*/, IPPROTO_TCP, 0, ip_head->daddr, ip_head->saddr, 0, 0, libnet, 0); }else if(ip_head->protocol == IPPROTO_UDP && udp_head->dest != DNS_PORT) { //现在是 UDP 的时代了 libnet_build_udp(ntohs(udp_head->dest),ntohs(udp_head->source), sizeof(blank)+sizeof(struct udphdr),0,blank,sizeof(blank),libnet,0); libnet_build_ipv4(40, 0, 0, 0x4000, 63/*ttl*/, IPPROTO_UDP, 0, ip_head->daddr, ip_head->saddr, 0, 0, libnet, 0); }else return FALSE; // if(param->linklayer_len == 14) // libnet_build_ethernet( // ((struct libnet_ethernet_hdr *) param->packet_linklayer_hdr)->ether_shost, // /((struct libnet_ethernet_hdr *) param->packet_linklayer_hdr)->ether_dhost, // ETHERTYPE_IP, 0, 0, libnet, 0); libnet_autobuild_ethernet( ((struct libnet_ethernet_hdr *) param->packet_linklayer_hdr)->ether_shost, ETHERTYPE_IP,libnet ); libnet_write(libnet); libnet_clear_packet(libnet); return TRUE; }
int main(int argc, char **argv) { int ch, dhcp_payload_len; unsigned char *dhcp_payload; libnet_ptag_t ptag_dhcpv4, ptag_udp, ptag_ipv4, ptag_ethernet; char *arg_secs, *arg_cip, *arg_chaddr, *arg_sip, *arg_ifname; char *arg_operation, *arg_timeout, *arg_xid, *arg_flags, *arg_yip; char *arg_gip, *arg_sname, *arg_fname, *arg_ether_dst, *stmp; char *arg_ipv4_src, *arg_ipv4_dst, *arg_ipv4_tos, *arg_ipv4_ttl; char *arg_reply_count; if (argc < 2) usage("too few arguments"); srandom(time(NULL)); arg_secs = arg_cip = arg_chaddr = arg_sip = arg_ifname = NULL; arg_operation = arg_timeout = arg_xid = arg_flags = arg_yip = NULL; arg_gip = arg_sname = arg_fname = arg_ether_dst = arg_reply_count = NULL; arg_ipv4_src = arg_ipv4_dst = arg_ipv4_tos = arg_ipv4_ttl = NULL; verbosity = 1; while ((ch = getopt(argc, argv, "s:c:h:i:o:t:x:f:y:g:S:A:B:O:X:v:F:T:L:Q:E:w:n:m")) != -1) { switch (ch) { case 's': arg_secs = optarg; break; case 'c': arg_cip = optarg; break; case 'h': arg_chaddr = optarg; break; case 'S': arg_sip = optarg; break; case 'i': arg_ifname = optarg; break; case 'o': arg_operation = optarg; break; case 't': arg_timeout = optarg; break; case 'x': arg_xid = optarg; break; case 'f': arg_flags = optarg; break; case 'y': arg_yip = optarg; break; case 'B': arg_fname = optarg; break; case 'A': arg_sname = optarg; break; case 'g': arg_gip = optarg; break; case 'F': arg_ipv4_src = optarg; break; case 'T': arg_ipv4_dst = optarg; break; case 'L': arg_ipv4_ttl = optarg; break; case 'Q': arg_ipv4_tos = optarg; break; case 'n': arg_reply_count = optarg; break; case 'E': arg_ether_dst = optarg; break; case 'v': verbosity = atoi(optarg); break; case 'm': no_double_options = 0; break; case 'O': add_option(optarg); break; case 'X': add_hexoption(optarg); break; case 'w': option_lookup(optarg); break; case '?': default: usage("unknown argument"); } } argc -= optind; argv += optind; /* Set some basic defaults */ set_defaults(); /* Make sure network interface was specified with -i option */ if (arg_ifname == NULL) { usage("Error: network interface (-i option) not specified."); } strncpy(ifname, arg_ifname, 99); /* Try to have pcap and libnet use the interface */ pcp = pcap_open_live(ifname, SNAPLEN, 1, 1, pcap_errbuf); if (pcp == NULL) { printf("pcap_open_live(%s) failed! Did you give the right interface name " "and are you root?\n", ifname); printf("pcap said: %s\n", pcap_errbuf); exit(1); } lnp = libnet_init(LIBNET_LINK, ifname, libnet_errbuf); if (lnp == NULL) { printf("libnet_init(%s) failed!\n", ifname); printf("libnet said: %s\n", libnet_errbuf); exit(1); } /* Set chaddr MAC address */ if (arg_chaddr != NULL) { int len = ETHER_ADDR_LEN; /*chaddr = libnet_hex_aton((int8_t *)arg_chaddr, &len);*/ chaddr = libnet_hex_aton(arg_chaddr, &len); if (chaddr == NULL) { if (verbosity > 0) printf("Invalid chaddr MAC address specified (%s)\n", arg_chaddr); exit(1); } } else { /* Try to retrieve MAC address using libnet */ chaddr = (u_int8_t *)libnet_get_hwaddr(lnp); if (chaddr == NULL) { if (verbosity > 1) { printf("Failed to retrieve MAC address for interface %s, using 0:0:0:0:0:0\n" "Libnet said: %s\n", ifname, libnet_errbuf); } memset(chaddr, 0, ETHER_ADDR_LEN); } } /* Set cip address */ if (arg_cip != NULL) { cip = inet_addr(arg_cip); if (cip == INADDR_NONE) { if (verbosity > 0) printf("Invalid cip address specified (%s)\n", arg_cip); exit(1); } cip = ntohl(cip); } else { /* Try to retrieve IP address using libnet */ cip = libnet_get_ipaddr4(lnp); if ((int)cip == -1) { if (verbosity > 1) { printf("Failed to retrieve IPv4 address for interface %s, using cip 0.0.0.0\n" "Libnet said: %s\n", ifname, libnet_errbuf); } cip = inet_addr("0.0.0.0"); } else cip = htonl(cip); } /**************************/ /* Set various parameters */ /**************************/ if (arg_operation != NULL) { if (option_added(LIBNET_DHCP_MESSAGETYPE) && no_double_options) { if (verbosity > 0) { printf("Error: DHCP messagetype specified twice (don't use -o option if\n" " you also intend to use -O to set option 53 (messagetype))\n"); } exit(1); } if (strcasecmp(arg_operation, "discover") == 0) { operation = LIBNET_DHCP_MSGDISCOVER; if (arg_timeout == NULL) timeout = 5; } else if (strcasecmp(arg_operation, "request") == 0) { operation = LIBNET_DHCP_MSGREQUEST; if (arg_timeout == NULL) timeout = 5; } else if (strcasecmp(arg_operation, "inform") == 0) { operation = LIBNET_DHCP_MSGINFORM; if (timeout == 0) timeout = 5; } else if (strcasecmp(arg_operation, "release") == 0) operation = LIBNET_DHCP_MSGRELEASE; else if (strcasecmp(arg_operation, "decline") == 0) operation = LIBNET_DHCP_MSGDECLINE; else { if (verbosity > 0) usage("Invalid DHCP operation type"); else exit(1); } /* Add MESSAGETYPE DHCP option */ num_options++; options = (struct dhcp_option *) realloc(options, num_options * sizeof(struct dhcp_option)); options[num_options-1].opnum = LIBNET_DHCP_MESSAGETYPE; options[num_options-1].oplen = 1; options[num_options-1].opdata[0] = operation; } else { /* no "-o operation" argument given */ if (option_added(LIBNET_DHCP_MESSAGETYPE) == 0) { /* Add MESSAGETYPE DHCP option */ num_options++; options = (struct dhcp_option *) realloc(options, num_options * sizeof(struct dhcp_option)); options[num_options-1].opnum = LIBNET_DHCP_MESSAGETYPE; options[num_options-1].oplen = 1; options[num_options-1].opdata[0] = operation; } } if (arg_secs != NULL) { unsigned long ultmp; ultmp = strtoul(arg_secs, &stmp, 0); if (*stmp != '\0' || ultmp > 65535) { if (verbosity > 0) printf("Error: secs must be 0-65535 (was: %s)\n", arg_secs); exit(1); } secs = (u_int16_t)ultmp; } if (arg_timeout != NULL) { timeout = strtoul(arg_timeout, &stmp, 0); if (*stmp != '\0') { if (verbosity > 0) printf("Error: timeout value must be 0 or a positive integer (was: %s)\n", arg_timeout); exit(1); } } if (arg_reply_count != NULL) { reply_count = strtoul(arg_reply_count, &stmp, 0); if (*stmp != '\0') { if (verbosity > 0) printf("Error: reply_count value must be 0 or a positive integer (was: %s)\n", arg_reply_count); exit(1); } } if (arg_xid != NULL) { xid = strtoul(arg_xid, &stmp, 0); if (*stmp != '\0') { if (verbosity > 0) printf("Error: xid value must be 0 or a positive integer (was: %s)\n", arg_xid); exit(1); } } if (arg_flags != NULL) { unsigned long ultmp; ultmp = strtoul(arg_flags, &stmp, 0); if (*stmp != '\0' || ultmp > 65535) { if (verbosity > 0) printf("Error: flags value must be 0-65535 (was: %s)\n", arg_flags); exit(1); } flags = (u_int16_t)ultmp; } if (arg_sip != NULL) { sip = inet_addr(arg_sip); if (sip == INADDR_NONE) { if (verbosity > 0) printf("Error: specified sip value is not a valid IPv4 address (was: %s)\n", arg_sip); exit(1); } } if (arg_yip != NULL) { yip = inet_addr(arg_yip); if (yip == INADDR_NONE) { if (verbosity > 0) printf("Error: specified yip value is not a valid IPv4 address (was: %s)\n", arg_yip); exit(1); } } if (arg_gip != NULL) { gip = inet_addr(arg_gip); if (gip == INADDR_NONE) { if (verbosity > 0) printf("Error: specified gip value is not a valid IPv4 address (was: %s)\n", arg_gip); exit(1); } } if (arg_fname != NULL) { fname = (char *)malloc(strlen(fname)+1); strcpy(fname, arg_fname); } if (arg_sname != NULL) { sname = (char *)malloc(strlen(sname)+1); strcpy(sname, arg_sname); } if (arg_ipv4_src != NULL) { ipv4_src = inet_addr(arg_ipv4_src); if (ipv4_src == INADDR_NONE) { if (verbosity > 0) printf("Error: specified ipv4_src value is not a valid IPv4 address (was: %s)\n", arg_ipv4_src); exit(1); } } if (arg_ipv4_dst != NULL) { ipv4_dst = inet_addr(arg_ipv4_dst); if (ipv4_dst == INADDR_NONE) { if (verbosity > 0) printf("Error: specified ipv4_dst value is not a valid IPv4 address (was: %s)\n", arg_ipv4_dst); exit(1); } } if (arg_ipv4_ttl != NULL) { unsigned long ultmp; ultmp = strtoul(arg_ipv4_ttl, &stmp, 0); if (*stmp != '\0' || ultmp > 255) { if (verbosity > 0) printf("Error: ipv4_ttl value must be 0-255 (was: %s)\n", arg_xid); exit(1); } ipv4_ttl = (u_int8_t)ultmp; } if (arg_ipv4_tos != NULL) { unsigned long ultmp; ultmp = strtoul(arg_ipv4_tos, &stmp, 0); if (*stmp != '\0' || ultmp > 255) { if (verbosity > 0) printf("Error: ipv4_tos value must be 0-255 (was: %s)\n", arg_ipv4_tos); exit(1); } ipv4_tos = (u_int8_t)ultmp; } if (arg_ether_dst != NULL) { int l = ETHER_ADDR_LEN; /*ether_dst = libnet_hex_aton((int8_t *)arg_ether_dst, &l);*/ ether_dst = libnet_hex_aton(arg_ether_dst, &l); if (ether_dst == NULL) { if (verbosity > 0) printf("Error: invalid ethernet destination MAC specified (was: %s)\n", arg_ether_dst); exit(1); } } /****************************** * Done setting parameters. * * Start building DHCP packet * ******************************/ libnet_clear_packet(lnp); /* Build DHCP payload (DHCP options section) */ dhcp_payload = build_payload(&dhcp_payload_len); /* Create DHCP message */ ptag_dhcpv4 = libnet_build_dhcpv4(LIBNET_DHCP_REQUEST, BOOTP_HTYPE_ETHER, ETHER_ADDR_LEN, BOOTP_HOPCOUNT, xid, secs, flags, cip, yip, sip, gip, chaddr, sname, fname, dhcp_payload, dhcp_payload_len, lnp, 0); if (ptag_dhcpv4 == -1) { printf("Failed to build bootp packet: %s\n", libnet_errbuf); exit(1); } /* libnet_ptag_t libnet_build_udp(u_int16_t sp, u_int16_t dp, u_int16_t len, u_int16_t sum, u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag); */ /* Create UDP datagram */ ptag_udp = libnet_build_udp(UDP_SRCPORT, UDP_DSTPORT, dhcp_payload_len + LIBNET_DHCPV4_H + LIBNET_UDP_H, 0, NULL, 0, lnp, 0); if (ptag_udp == -1) { printf("Failed to build udp packet: %s\n", libnet_errbuf); exit(1); } /* libnet_ptag_t libnet_build_ipv4(u_int16_t len, u_int8_t tos, u_int16_t id, u_int16_t frag, u_int8_t ttl, u_int8_t prot, u_int16_t sum, u_int32_t src, u_int32_t dst, u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag); */ /* Create IPv4 datagram */ ptag_ipv4 = libnet_build_ipv4(dhcp_payload_len + LIBNET_DHCPV4_H + LIBNET_UDP_H + LIBNET_IPV4_H, ipv4_tos, ipv4_id++, 0, ipv4_ttl, IPPROTO_UDP, 0, ipv4_src, ipv4_dst, NULL, 0, lnp, 0); if (ptag_ipv4 == -1) { printf("Failed to build ipv4 packet: %s\n", libnet_errbuf); exit(1); } /* Create ethernet packet */ ptag_ethernet = libnet_autobuild_ethernet(ether_dst, ETHERTYPE_IP, lnp); if (ptag_ethernet == -1) { printf("Failed to build ethernet packet: %s\n", libnet_errbuf); exit(1); } /* Write packet to network */ if (libnet_write(lnp) == -1) { printf("Failed to write ethernet packet to network: %s\n", libnet_errbuf); exit(1); } /* If we have to wait and listen for server replies, we use a timer and a signal handler to quit. We do this as libpcap doesn't support non-blocking packet capture on some (many?) platforms. We could have launched another thread also, but using timers and signals is simpler. */ if (timeout > 0) { struct itimerval itv; itv.it_interval.tv_sec = itv.it_value.tv_sec = timeout; itv.it_interval.tv_usec = itv.it_value.tv_usec = 0; setitimer(ITIMER_REAL, &itv, NULL); signal(SIGALRM, sighandler); pcap_loop(pcp, -1, pcap_callback, NULL); } libnet_destroy(lnp); pcap_close(pcp); exit(0); }
/* ======================================================================================================================= 在windows平台下必须包含此文件,文件libnet.h是libnet开发包的头文件 ======================================================================================================================= */ void main() { int packet_size; /* 存放数据包长度的变量 */ libnet_t *l; /* libnet句柄 */ libnet_ptag_t protocol_tag; /* 协议块标记 */ int num; char *device = NULL; /* 设备名字,此时为NULL */ char error_information[LIBNET_ERRBUF_SIZE]; /* 用来存放错误信息 */ char *destination_ip_str = "192.168.1.1"; /* 目的IP地址字符串变量,可以指定任意一个合法的IP地址 */ char *source_ip_str = "192.168.1.102"; /* 源IP地址字符串变量,可以指定任意一个合法的IP地址 */ u_char hardware_source[6] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; /* 源MAC地址,可以是任意指定 */ u_char hardware_destination[6] = { 0x00, 0x14, 0x78, 0xA7, 0xC8, 0x44 }; /* 目的MAC地址,可以是任意指定 */ u_long destination_ip; /* 目的IP地址 */ u_long source_ip; /* 源IP地址 */ destination_ip = libnet_name2addr4(l, destination_ip_str, LIBNET_RESOLVE); /* 把目的IP地址字符串形式转化成网络顺序字节形式的数据 */ source_ip = libnet_name2addr4(l, source_ip_str, LIBNET_RESOLVE); /* 把源IP地址字符串形式转化成网络顺序字节形式的数据 */ l = libnet_init( /* 初始化libnet */ LIBNET_LINK_ADV, /* libnet类型 */ device, /* 网络设备 */ error_information); /* 错误信息 * */ protocol_tag = libnet_build_arp( /* 构造ARP协议块,函数的返回值是代表新生成的ARP协议块的一个协议块标记, */ ARPHRD_ETHER, /* 硬件地址类型,在这里是以太网 */ ETHERTYPE_IP, /* 协议地址类型,在这里是IP协议 */ 6, /* 硬件地址长度,MAC地址的长度为6 */ 4, /* 协议地址长度,IP地址的长度为4 */ ARPOP_REPLY, /* 操作类型,在这里是ARP应答类型 */ hardware_source, /* 源硬件地址 */ (u_int8_t*) &source_ip, /* 源IP地址 */ hardware_destination, /* 目标硬件地址 */ (u_int8_t*) &destination_ip, /* 目标协议地址 */ NULL, /* 负载,此时为NULL */ 0, /* 负载的长度,此时为0 */ l, /* libnet句柄,此句柄由libnet_init()函数生成 */ 0 /* 协议块标记,此时为0,表示构造一个新的ARP协议块,而不是修改已经存在的协议块 * */ ); protocol_tag = libnet_autobuild_ethernet( /* 构造一个以太网协议块,返回一个指向此协议块的标记 */ hardware_destination, /* 目的硬件地址 */ ETHERTYPE_ARP, /* 以太网上层协议类型,此时为ARP类型 */ l /* libnet句柄 */ ); while(1) { Sleep(100); packet_size = libnet_write(l); /* * 发送已经构造的ARP数据包,注意此数据包应该包括两部分,一部分是ARP协议块,另外一部分是以太网协议块 */ printf("发送一个%d字节长度的ARP应答数据包\n", packet_size); /* 输出发送的ARP数据包的字节数 */ } libnet_destroy(l); /* 销毁libnet */ }
int main(int argc, char *argv[]) { char *intf; u_long src_ip, options_len, orig_len; int i; libnet_t *l; libnet_ptag_t t; libnet_ptag_t ip; libnet_ptag_t udp; libnet_ptag_t dhcp; struct libnet_ether_addr *ethaddr; struct libnet_stats ls; char errbuf[LIBNET_ERRBUF_SIZE]; u_char options_req[] = { LIBNET_DHCP_SUBNETMASK , LIBNET_DHCP_BROADCASTADDR , LIBNET_DHCP_TIMEOFFSET , LIBNET_DHCP_ROUTER , LIBNET_DHCP_DOMAINNAME , LIBNET_DHCP_DNS , LIBNET_DHCP_HOSTNAME }; u_char *options; u_char enet_dst[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; u_char *tmp; // have to specify interface if (argc != 2) usage(argv[0]); intf = argv[1]; l = libnet_init( LIBNET_LINK, // injection type intf, // network interface errbuf); // errbuf if (!l) { fprintf(stderr, "libnet_init: %s", errbuf); exit(EXIT_FAILURE); } else { src_ip = libnet_get_ipaddr4(l);; if ((ethaddr = libnet_get_hwaddr(l)) == NULL) { fprintf(stderr, "libnet_get_hwaddr: %s\n", libnet_geterror(l)); exit(EXIT_FAILURE); } printf("ip addr : %s\n", libnet_addr2name4(src_ip, LIBNET_DONT_RESOLVE)); printf("eth addr : "); for (i = 0; i < 6; i++) { printf("%x", ethaddr->ether_addr_octet[i]); if (i != 5) { printf(":"); } } printf("\n"); // build options packet i = 0; options_len = 3; // update total payload size // we are a discover packet options = malloc(3); options[i++] = LIBNET_DHCP_MESSAGETYPE; // type options[i++] = 1; // len options[i++] = LIBNET_DHCP_MSGDISCOVER; // data orig_len = options_len; options_len += sizeof(options_req) + 2; // update total payload size // workaround for realloc on old machines // options = realloc(options, options_len); // resize options buffer tmp = malloc(options_len); memcpy(tmp, options, orig_len); free(options); options = tmp; // we are going to request some parameters options[i++] = LIBNET_DHCP_PARAMREQUEST; // type options[i++] = sizeof(options_req); // len memcpy(options + i, options_req, sizeof(options_req)); // data i += sizeof(options_req); // if we have an ip already, let's request it. if (src_ip) { orig_len = options_len; options_len += 2 + sizeof(src_ip); // workaround for realloc on old machines // options = realloc(options, options_len); tmp = malloc(options_len); memcpy(tmp, options, orig_len); free(options); options = tmp; options[i++] = LIBNET_DHCP_DISCOVERADDR; // type options[i++] = sizeof(src_ip); // len memcpy(options + i, (char *)&src_ip, sizeof(src_ip));// data i += sizeof(src_ip); } // end our options packet options[i] = LIBNET_DHCP_END; // make sure we are at least the minimum length, if not fill // this could go in libnet, but we will leave it in the app for now if (options_len + LIBNET_DHCPV4_H < LIBNET_BOOTP_MIN_LEN) { orig_len = options_len; options_len = LIBNET_BOOTP_MIN_LEN - LIBNET_DHCPV4_H; // workaround for realloc on old machines // options = realloc(options, options_len); tmp = malloc(options_len); memcpy(tmp, options, orig_len); free(options); options = tmp; memset(options + i, 0, options_len - i); } // the goodies are here dhcp = libnet_build_dhcpv4( LIBNET_DHCP_REQUEST, // opcode 1, // hardware type 6, // hardware address length 0, // hop count 0xdeadbeef, // transaction id 0, // seconds since bootstrap 0x8000, // flags 0, // client ip 0, // your ip 0, // server ip 0, // gateway ip ethaddr->ether_addr_octet, // client hardware addr NULL, // server host name NULL, // boot file options, // dhcp options stuck in payload since it is dynamic options_len, // length of options l, // libnet handle 0); // libnet id // wrap it udp = libnet_build_udp( 68, // source port 67, // destination port LIBNET_UDP_H + LIBNET_DHCPV4_H + options_len, // packet size 0, // checksum NULL, // payload 0, // payload size l, // libnet handle 0); // libnet id // hook me up with some ipv4 ip = libnet_build_ipv4( LIBNET_IPV4_H + LIBNET_UDP_H + LIBNET_DHCPV4_H + options_len, // length 0x10, // TOS 0, // IP ID 0, // IP Frag 16, // TTL IPPROTO_UDP, // protocol 0, // checksum src_ip, // src ip inet_addr("255.255.255.255"), // destination ip NULL, // payload 0, // payload size l, // libnet handle 0); // libnet id // we can just autobuild since we arent doing anything tricky t = libnet_autobuild_ethernet( enet_dst, // ethernet destination ETHERTYPE_IP, // protocol type l); // libnet handle // write to the wire if (libnet_write(l) == -1) { fprintf(stderr, " %s: libnet_write: %s\n", argv[0], strerror(errno)); exit(EXIT_FAILURE); } // fill and print stats libnet_stats(l, &ls); fprintf(stderr, "Packets sent: %ld\n" "Packet errors: %ld\n" "Bytes written: %ld\n", ls.packets_sent, ls.packet_errors, ls.bytes_written); libnet_destroy(l); // free mem free(options); exit(0); } exit(0); }
u_int16_t get_sum(u_int8_t *payload, u_int32_t total_pload_size, u_int16_t id, u_int16_t seq) { /* Builds the ICMP header with the whole payload, gets * the checksum from it and returns it (in host order). */ char errbuf[LIBNET_ERRBUF_SIZE]; libnet_ptag_t icmp_tag; u_int8_t *packet; u_int32_t packet_size; u_int16_t *sum_p, sum; u_int8_t dummy_dst[6] = {0, 0, 0, 0, 0, 0}; icmp_tag = LIBNET_PTAG_INITIALIZER; /* Switching to advanced link mode */ /* Nothing should be built yet and all random numbers * * should be already generated. */ libnet_destroy(l); l = libnet_init(LIBNET_LINK_ADV, "eth0", errbuf); if (l == NULL) { fprintf(stderr, "libnet_init() failed (link_adv): %s\n", errbuf); exit(EXIT_FAILURE); } /* Building the header */ icmp_tag = libnet_build_icmpv4_echo(ICMP_ECHO, 0, 0, id, seq, payload, total_pload_size, l, icmp_tag); if (icmp_tag == -1) { fprintf(stderr, "Error building ICMP header: %s\n", libnet_geterror(l)); libnet_destroy(l); exit(EXIT_FAILURE); } /* Building dummy IP header */ if (libnet_autobuild_ipv4( (LIBNET_IPV4_H + LIBNET_ICMPV4_ECHO_H + total_pload_size), IPPROTO_ICMP, 0, l) == -1) { fprintf(stderr, "Error building dummy IP header: %s\n", libnet_geterror(l)); libnet_destroy(l); exit(EXIT_FAILURE); } /* Building dummy Ethernet header */ if (libnet_autobuild_ethernet(dummy_dst, ETHERTYPE_IP, l) == -1) { fprintf(stderr, "Error building dummy Ethernet header: %s\n", libnet_geterror(l)); libnet_destroy(l); exit(EXIT_FAILURE); } /* Pulling the packet */ if (libnet_adv_cull_packet(l, &packet, &packet_size) == -1) { fprintf(stderr, "Error pulling the packet: %s\n", libnet_geterror(l)); libnet_destroy(l); exit(EXIT_FAILURE); } /* Grabbing the checksum */ /* We want the 37th and 38th bytes: eth header (14) + ip * * header (20) + icmp type and code (2) = 36 */ sum_p = (u_int16_t *)(packet + 36); sum = ntohs(*sum_p); /* Freeing memory */ libnet_adv_free_packet(l, packet); /* Clearing the header */ libnet_clear_packet(l); /* Switching back to IPv4 raw socket mode */ libnet_destroy(l); l = libnet_init(LIBNET_RAW4, "eth0", errbuf); if (l == NULL) { fprintf(stderr, "libnet_init() failed (raw4, 2nd call): %s\n", errbuf); exit(EXIT_FAILURE); } return sum; }
static int http_redirector(const char *packet_content) { /******************************************************************* * here we use TCP * when we recv a SYN=1,ACK=0 packet, we just send a syn=1,ack=1 packet * that contains nothing * then we push a packet taht contains * HTTP/1.0 302 Found * Location: http://192.168.0.1/ * connection:close * * please visit http://192.168.0.1 * and then we reset the connection * ****************************************************************/ struct tcphdr * tcp_head; struct udphdr * udp_head; struct ether_header *eptr; //以太网帧 struct iphdr *ip_head; if (packet_content == NULL) { return 1; } eptr = (struct ether_header *) packet_content; ip_head = (struct iphdr *) (packet_content + sizeof(struct ether_header)); //获得ip数据报的内存地址 //非 enable 的客户端,现在要开始这般处理了,重定向到 ... 嘿嘿 redirector_ip = inet_addr(conf.portal_server_ip); portal_dev = inet_addr(conf.portal_dev); if (ip_head->daddr == redirector_ip || ip_head->daddr == portal_dev) { return 1; } if (ip_head->saddr == redirector_ip || ip_head->saddr == portal_dev) { return 1; } struct in_addr tmp; tmp.s_addr = ip_head->daddr; if (search(ip_head->daddr) == 1) { printf("dip:%sok\n", inet_ntoa(tmp)); return 1; } tmp.s_addr = ip_head->saddr; if (search(ip_head->saddr) == 1) { // printf("sip:%sok\n", inet_ntoa(tmp)); return 1; } memset(httphead, 0, sizeof(httphead)); sprintf(httphead, "HTTP/1.0 302 Found\n" "Location: http://%s:5246/test/auth.jsp?sip=%s&portal_dev=%s&smac=%s\n" "Connection:close\n\n" "<html>\n\t<head>\n\t\t<meta http-equiv=\"Refresh\"content=\"0 ; " "url=http://%s:5246/test/auth.jsp?sip=%s&portal_dev=%s&smac=%s\">\n\t</head>\n</html>\n", conf.portal_server_ip, inet_ntoa(tmp), conf.portal_dev, smac, conf.portal_server_ip, inet_ntoa(tmp), conf.portal_dev, smac); // conf.authserver, inet_ntoa(tmp), conf.gateway, smac, // conf.authserver, inet_ntoa(tmp), conf.gateway, smac); printf("httphead:%s\n", httphead); //Retrive the tcp header and udp header tcp_head = (struct tcphdr*) ((char*) ip_head + ip_head->ihl * 4); udp_head = (struct udphdr*) ((char*) ip_head + ip_head->ihl * 4); //初始化libnet,每个线程一个 libnet ;) init_thread_libnet(); // http 重定向 if (ip_head->protocol == IPPROTO_TCP && ntohs(tcp_head->dest) == 80) { u_int8_t tcp_flags = ((struct libnet_tcp_hdr *) tcp_head)->th_flags; if (tcp_flags == TH_SYN) { /******************************** * 对于这样的一个握手数据包 * 我们应该要建立连接了 * 回复一个syn ack 就是了 *********************************/ // here we just echo ack and syn. libnet_build_tcp(ntohs(tcp_head->dest), ntohs(tcp_head->source), tcp_head->seq, ntohl(tcp_head->seq) + 1, TH_ACK | TH_SYN, 4096, 0, 0, 20, 0, 0, libnet, 0); libnet_build_ipv4(40, 0, 0, 0x4000, 63/*ttl*/, IPPROTO_TCP, 0, ip_head->daddr, ip_head->saddr, 0, 0, libnet, 0); libnet_write(libnet); libnet_clear_packet(libnet); libnet_build_tcp(ntohs(tcp_head->dest), ntohs(tcp_head->source), tcp_head->seq, ntohl(tcp_head->seq) + 1, TH_ACK | TH_SYN, 4096, 0, 0, 20, 0, 0, libnet, 0); libnet_build_ipv4(40, 0, 0, 0x4000, 63/*ttl*/, IPPROTO_TCP, 0, ip_head->daddr, ip_head->saddr, 0, 0, libnet, 0); } else if (tcp_flags & (TH_ACK | TH_SYN)) { /********************************************* *现在是发送页面的时候啦! *********************************************/ int SIZEHTTPHEAD = strlen((const char*) httphead); libnet_build_tcp(ntohs(tcp_head->dest), ntohs(tcp_head->source), ntohl(tcp_head->ack_seq), ntohl(tcp_head->seq) + ntohs(ip_head->tot_len) - 40, TH_ACK | TH_PUSH | TH_FIN, 4096, 0, 0, 20 + SIZEHTTPHEAD, httphead, SIZEHTTPHEAD, libnet, 0); libnet_build_ipv4(40 + SIZEHTTPHEAD, 0, 0, 0x4000, 63/*ttl*/, IPPROTO_TCP, 0, ip_head->daddr, ip_head->saddr, 0, 0, libnet, 0); } else if (tcp_flags & (TH_FIN | TH_RST)) { /********************************************************* *好,现在结束连接! ********************************************************/ libnet_build_tcp(ntohs(tcp_head->dest), ntohs(tcp_head->source), ntohl(tcp_head->ack_seq), ntohl(tcp_head->seq) + 1, TH_ACK | TH_RST, 4096, 0, 0, 20, 0, 0, libnet, 0); libnet_build_ipv4(40, 0, 0, 0x4000, 63/*ttl*/, IPPROTO_TCP, 0, ip_head->daddr, ip_head->saddr, 0, 0, libnet, 0); printf( "------------------------------------------------------------------------link disconnect\n"); printf("smac:%s\n", smac); printf("sip:%sok\n", inet_ntoa(tmp)); } else { return 0; } } //其他 TCP 直接 RST else if (ip_head->protocol == IPPROTO_TCP) { libnet_build_tcp(ntohs(tcp_head->dest), ntohs(tcp_head->source), ntohl(tcp_head->ack_seq), ntohl(tcp_head->seq) + 1, TH_ACK | TH_RST, 4096, 0, 0, 20, 0, 0, libnet, 0); libnet_build_ipv4(40, 0, 0, 0x4000, 63/*ttl*/, IPPROTO_TCP, 0, ip_head->daddr, ip_head->saddr, 0, 0, libnet, 0); } else if (ip_head->protocol == IPPROTO_UDP && udp_head->dest != 53) { //现在是 UDP 的时代了 libnet_build_udp(ntohs(udp_head->dest), ntohs(udp_head->source), sizeof(blank) + sizeof(struct udphdr), 0, blank, sizeof(blank), libnet, 0); libnet_build_ipv4(40, 0, 0, 0x4000, 63/*ttl*/, IPPROTO_UDP, 0, ip_head->daddr, ip_head->saddr, 0, 0, libnet, 0); } else return 0; libnet_autobuild_ethernet(eptr->ether_shost, ETHERTYPE_IP, libnet); libnet_write(libnet); libnet_clear_packet(libnet); return 1; }
int main(int argc, char *argv[]) { int c; uint32_t i; libnet_t *l; libnet_ptag_t t; char *device = NULL; uint8_t *packet; uint32_t packet_s; char errbuf[LIBNET_ERRBUF_SIZE]; printf("libnet 1.1 packet shaping: ARP[link -- autobuilding ethernet]\n"); if (argc > 1) { device = argv[1]; } l = libnet_init( LIBNET_LINK_ADV, /* injection type */ device, /* network interface */ errbuf); /* errbuf */ if (l == NULL) { fprintf(stderr, "%s", errbuf); exit(EXIT_FAILURE); } else /* * Build the packet, remmebering that order IS important. We must * build the packet from lowest protocol type on up as it would * appear on the wire. So for our ARP packet: * * ------------------------------------------- * | Ethernet | ARP | * ------------------------------------------- * ^ ^ * |------------------ | * libnet_build_ethernet()--| | * | * libnet_build_arp()-----------| */ i = libnet_get_ipaddr4(l); t = libnet_autobuild_arp( ARPOP_REPLY, /* operation type */ enet_src, /* sender hardware addr */ (uint8_t *)&i, /* sender protocol addr */ enet_dst, /* target hardware addr */ (uint8_t *)&i, /* target protocol addr */ l); /* libnet context */ if (t == -1) { fprintf(stderr, "Can't build ARP header: %s\n", libnet_geterror(l)); goto bad; } t = libnet_autobuild_ethernet( enet_dst, /* ethernet destination */ ETHERTYPE_ARP, /* protocol type */ l); /* libnet handle */ if (t == -1) { fprintf(stderr, "Can't build ethernet header: %s\n", libnet_geterror(l)); goto bad; } if (libnet_adv_cull_packet(l, &packet, &packet_s) == -1) { fprintf(stderr, "%s", libnet_geterror(l)); } else { fprintf(stderr, "packet size: %d\n", packet_s); libnet_adv_free_packet(l, packet); } c = libnet_write(l); if (c == -1) { fprintf(stderr, "Write error: %s\n", libnet_geterror(l)); goto bad; } else { fprintf(stderr, "Wrote %d byte ARP packet from context \"%s\"; " "check the wire.\n", c, libnet_cq_getlabel(l)); } libnet_destroy(l); return (EXIT_SUCCESS); bad: libnet_destroy(l); return (EXIT_FAILURE); }
int main(int argc, char *argv[]){ int c; uint32_t i; libnet_t *l; libnet_ptag_t t; char *device =NULL; uint8_t *packet; uint32_t packet_s; char errbuf[LIBNET_ERRBUF_SIZE]; u_char enet_src[6] = {0x08,0x00,0x27,0x92,0x07,0xb6}; u_char enet_dst[6] = {0x94,0xB8,0X6D,0xFC,0xDA,0xA0}; u_char ip_dst[4] ={0xc0,0xa8,0x2b,0x92}; u_char ip_src[4] ={0xc0,0xa8,0x2b,0x01}; printf("libnet 1.1 packet shaping : ARP [link --autobuilding ethernet]\n"); if(argc >1){ device = argv[1]; } l =libnet_init(LIBNET_LINK_ADV, device,errbuf); if(l ==NULL){ fprintf(stderr,"libnet_init() failed :%s",errbuf); exit(EXIT_FAILURE); }else i =libnet_get_ipaddr4(l); t=libnet_autobuild_arp(ARPOP_REPLY,enet_src,ip_src,enet_dst,ip_dst,l); if(t ==-1) { fprintf(stderr, "can't build ARP header:%s\n",libnet_geterror(l)); goto bad; } t=libnet_autobuild_ethernet(enet_dst,ETHERTYPE_ARP, l); if(libnet_adv_cull_packet(l,&packet,&packet_s)==-1){ fprintf(stderr, "%s",libnet_geterror(l)); }else{ fprintf(stderr, "packet size : %d\n", packet_s); libnet_adv_free_packet(l,packet); } c=libnet_write(l); if(c==-1){ fprintf(stderr,"Write error : %s \n",libnet_geterror(l)); goto bad; }else{ fprintf(stderr,"Wrote %d byte ARP packet from context \ %s\";""check the wire\n",c,libnet_cq_getlabel(l)); } libnet_destroy(l); return (EXIT_SUCCESS); bad : libnet_destroy(l); return(EXIT_SUCCESS); }