📄 hunt.c
字号:
unsigned int key; fill_uci(&uci, p); key = uci_generate_key(&uci); hash_lock(&conn_table); if ((ci = hash_get(&conn_table, key, &uci)) && ht_eq(key, ci, &uci) == 1) { conn_add_update(p);#if 0 ci = hash_remove(&conn_table, key, &uci); hash_unlock(&conn_table); conn_free(ci); hash_lock(&conn_table);#endif } else { __conn_add(p, key); } hash_unlock(&conn_table);}static void conn_update_table(struct packet *p, struct ethhdr *ethh, struct iphdr *iph){ struct tcphdr *tcph = p->p_hdr.p_tcph; if (tcph->syn && !tcph->ack) { if (conn_add_policy(iph, tcph)) { conn_add(p); } } else if (tcph->rst || tcph->fin) { #if 0 if (conn_add_policy(iph, tcph)) #endif conn_del(p); } else { #if 0 if (conn_add_policy(iph, tcph)) #endif conn_add_update(p); }}/* * * function lists * */static void process_tcp(struct packet *p){ struct ifunc_item *li; struct list_iterator iter; list_iter_set(&iter, &l_ifunc_tcp); while ((li = list_iter_get(&iter))) li->func(p, li->arg); list_iter_end(&iter);}static void process_udp(struct packet *p){ struct ifunc_item *li; struct list_iterator iter; list_iter_set(&iter, &l_ifunc_udp); while ((li = list_iter_get(&iter))) li->func(p, li->arg); list_iter_end(&iter);}static void process_icmp(struct packet *p){ struct ifunc_item *li; struct list_iterator iter; list_iter_set(&iter, &l_ifunc_icmp); while ((li = list_iter_get(&iter))) li->func(p, li->arg); list_iter_end(&iter);}static void process_arp(struct packet *p){ struct ifunc_item *li; struct list_iterator iter; list_iter_set(&iter, &l_ifunc_arp); while ((li = list_iter_get(&iter))) li->func(p, li->arg); list_iter_end(&iter);}static void process_ip(struct packet *p){ struct ifunc_item *li; struct list_iterator iter; list_iter_set(&iter, &l_ifunc_ip); while ((li = list_iter_get(&iter))) li->func(p, li->arg); list_iter_end(&iter);}/* * sample of ifunc */#if 0struct list m_packet_list = LIST_INIT(struct packet, p_next[MODULE_NR]);void m_func_tcp(struct packet *p){ if (want_it) { packet_want(p); list_produce(&m_packet_list, p); }}#endifstatic inline void fast_tcp_process(struct packet *p){ struct list_iterator iter; struct ifunc_item *li; list_lock(&l_ifunc_fast_tcp); list_iter_set(&iter, &l_ifunc_fast_tcp); while ((li = list_iter_get(&iter))) li->func(p, li->arg); list_iter_end(&iter); list_unlock(&l_ifunc_fast_tcp);}static void mac_table_update(unsigned int ip, char *mac){ struct mac_info *mi; hash_lock(&mac_table); if ((mi = hash_get(&mac_table, ip, NULL))) { if (memcmp(mi->mac, mac, sizeof(mi->mac))) { pthread_mutex_lock(&mi->mutex); memcpy(mi->mac, mac, sizeof(mi->mac)); pthread_mutex_unlock(&mi->mutex); } } else { mi = malloc(sizeof(struct mac_info)); assert(mi); memcpy(mi->mac, mac, sizeof(mi->mac)); pthread_mutex_init(&mi->mutex, NULL); hash_put(&mac_table, ip, mi); } hash_unlock(&mac_table);}struct mac_info *mac_info_get(unsigned int ip){ struct mac_info *mi; hash_lock(&mac_table); if ((mi = hash_get(&mac_table, ip, NULL))) { pthread_mutex_lock(&mi->mutex); } hash_unlock(&mac_table); return mi;}void mac_info_release(struct mac_info *mi){ pthread_mutex_unlock(&mi->mutex);}static void mac_arp_learn(struct packet *p){ unsigned int ip; char *mac; struct arpeth_hdr *arpethh; arpethh = (struct arpeth_hdr *)(p->p_arph + 1); if (p->p_arph->ar_op == htons(ARPOP_REPLY) || p->p_arph->ar_op == htons(ARPOP_REQUEST)) { ip = *(unsigned int *) arpethh->ar_sip; mac = arpethh->ar_sha; if (memcmp(mac, p->p_ethh->h_source, ETH_ALEN) == 0) mac_table_update(ip, mac); else fprintf(stderr, "ARP: MAC src != ARP src for host %s\n", host_lookup(ip, hl_mode)); }}static void mac_ip_learn(struct packet *p){ unsigned int ip; char *mac; ip = p->p_iph->saddr; mac = p->p_ethh->h_source; mac_table_update(ip, mac); /* * well, don't learn mac addresses from dst as they can be spoofed * (even though check can be made) */}/* * * hunt * */unsigned int pkts_received = 0;unsigned int pkts_dropped = 0;unsigned int pkts_unhandled = 0;unsigned int bytes_received = 0;void *hunt(void *arg){ struct packet *p; struct ethhdr *ethh; struct iphdr *iph;#ifdef WITH_RECVMSG struct msghdr msg; struct sockaddr_pkt spkt; struct iovec iov;#endif pthread_sigmask(SIG_BLOCK, &intr_mask, NULL); if (verbose) printf("hunt pid %d\n", getpid()); add_telnet_rlogin_policy(); if (hash_init(&conn_table, 100, (hash_equal_func)ht_eq)) { /* Initialize hash table of connections */ perror("hash_init"); exit(1); } if (hash_init(&mac_table, 100, NULL)) { perror("hash init"); exit(1); } linksock = tap(eth_device, 1); /* Setup link socket */ if (linksock < 0) { perror("linksock"); exit(1); } packet_preallocate(64); printf("starting hunt\n"); setpriority(PRIO_PROCESS, getpid(), -20); pthread_mutex_lock(&mutex_hunt_ready); hunt_ready = 1; pthread_cond_signal(&cond_hunt_ready); pthread_mutex_unlock(&mutex_hunt_ready); while(1) { if (!(p = packet_new())) { fprintf(stderr, "can't get free packet - out of memory\n"); exit(1); }#ifdef WITH_RECVMSG memset(&msg, 0, sizeof(msg)); msg.msg_name = &spkt; msg.msg_namelen = sizeof(spkt); msg.msg_iovlen = 1; msg.msg_iov = &iov; iov.iov_base = p->p_raw; iov.iov_len = sizeof(p->p_raw); if ((p->p_raw_len = recvmsg(linksock, &msg, 0)) >= 0)#else if ((p->p_raw_len = recv(linksock, p->p_raw, sizeof(p->p_raw), 0)) > 0)#endif { pkts_received++; bytes_received += p->p_raw_len; /* * don't do continue or break without packet_free !! */ if (p->p_raw_len < 14) { pkts_dropped++; goto cont; } ALIGNPOINTERS_ETH(p, ethh); p->p_ethh = ethh; /* * in order to speed thinks as mutch as posible for arp stuff * the timestamp is moved to swtich p->p_timestamp = time(NULL); */ p->p_timestamp = 0; switch (ntohs(ethh->h_proto)) { case ETH_P_IP: p->p_timestamp = time(NULL); if (p->p_raw_len < 14 + 20) { pkts_dropped++; goto cont; } ALIGNPOINTERS_IP(ethh, iph); p->p_iph = iph; if (in_cksum((unsigned short *) iph, IP_HDR_LENGTH(iph)) == 0) { if (mac_learn_from_ip) mac_ip_learn(p); process_ip(p); /* drop IP fragments and ip packet len > p_raw_len */ if ((ntohs(iph->frag_off) & IP_OFFMASK) != 0 || (ntohs(iph->frag_off) & IP_MF) || (IP_HDR_LENGTH(iph) + IP_DATA_LENGTH(iph)) > p->p_raw_len) { pkts_dropped++; goto cont; } switch (iph->protocol) { case IPPROTO_TCP: if (p->p_raw_len < 14 + IP_HDR_LENGTH(iph) + 20) { pkts_dropped++; goto cont; } p->p_type = PACKET_TCP; ALIGNPOINTERS_TCP(iph, p->p_hdr.p_tcph, p->p_data); p->p_data_len = TCP_DATA_LENGTH(iph, p->p_hdr.p_tcph); if (ip_in_cksum(iph, (unsigned short *) p->p_hdr.p_tcph, IP_DATA_LENGTH(iph)) == 0) { conn_update_table(p, ethh, iph); fast_tcp_process(p); process_tcp(p); } else pkts_dropped++; break; case IPPROTO_UDP: if (p->p_raw_len < 14 + IP_HDR_LENGTH(iph) + 8) { pkts_dropped++; goto cont; } p->p_type = PACKET_UDP; ALIGNPOINTERS_UDP(iph, p->p_hdr.p_udph, p->p_data); /* check the UDP checksum */ process_udp(p); break; case IPPROTO_ICMP: if (p->p_raw_len < 14 + IP_HDR_LENGTH(iph) + 8) { pkts_dropped++; goto cont; } p->p_type = PACKET_ICMP; ALIGNPOINTERS_ICMP(iph, p->p_hdr.p_icmph, p->p_data); if (in_cksum((unsigned short *) p->p_hdr.p_icmph, IP_DATA_LENGTH(iph)) == 0) { process_icmp(p); } else pkts_dropped++; break; default: pkts_unhandled++; break; } } else pkts_dropped++; /* bad IP checksum */ break; case ETH_P_ARP: if (p->p_raw_len < 14 + 28) { pkts_dropped++; goto cont; } p->p_type = PACKET_ARP; ALIGNPOINTERS_ARP(ethh, p->p_arph); /* do process arp first - in order to do it as fast as posible arpspoof needs it */ process_arp(p); p->p_timestamp = time(NULL); /* well, the process_arp does not get timestamp */ mac_arp_learn(p); break; default: pkts_unhandled++; break; } }cont: packet_free(p); } return NULL;}/* * * helper functions * */void print_tcp(struct packet *p, struct iphdr *ip, struct tcphdr *tcp){ fprintf(stdout, "%s [%d] seq=(%u) ack=(%u)\t--->\t%s [%d] len=%d/%d\n", host_lookup(ip->saddr, hl_mode), ntohs(tcp->source), (unsigned int) ntohl(tcp->seq), tcp->ack ? (unsigned int) ntohl(tcp->ack_seq) : 0, host_lookup(ip->daddr, hl_mode), ntohs(tcp->dest), p->p_raw_len, p->p_data_len);}static int fill_space_to(char *b, int pos, int where){ if (pos >= 0 && pos < where) { return sprintf(b, "%*s", where - pos, ""); } else return 0;}int conn_list(struct user_conn_info **ruci, char **rbuf, int with_mac, int with_seq){ struct hash_iterator iter; struct conn_info *ci; struct user_conn_info *uci; int i, count; char *b, *b_old, *buf; hash_lock(&conn_table); count = hash_count(&conn_table); if (!count) { hash_unlock(&conn_table); if (ruci) *ruci = NULL; if (rbuf) *rbuf = NULL; return 0; } if (rbuf) { buf = malloc(count * 512); assert(buf); b = buf; } else b = buf = NULL; if (ruci) { uci = malloc(count * sizeof(struct user_conn_info)); assert(uci); } else uci = NULL; i = 0; hash_iter_set(&iter, &conn_table); while ((ci = hash_iter_get(&iter, NULL)) && i < count) { if (b) { b_old = b; b += sprintf(b, "%d) %s [%s]", i, host_lookup(ci->src_addr, hl_mode), port_lookup(ci->src_port, hl_mode)); b += fill_space_to(b, b - b_old, 30); b += sprintf(b, " --> "); b += sprintf(b, "%s [%s]\n", host_lookup(ci->dst_addr, hl_mode), port_lookup(ci->dst_port, hl_mode)); if (with_seq) { b_old = b; b += sprintf(b, " seq=(%u) ack=(%u)", (unsigned int) ntohl(ci->src.next_seq), (unsigned int) ntohl(ci->src.next_d_seq)); b += fill_space_to(b, b - b_old, 45); b += sprintf(b, " seq=(%u) ack=(%u)\n", (unsigned int) ntohl(ci->dst.next_seq), (unsigned int) ntohl(ci->dst.next_d_seq)); } if (with_mac) { b_old = b; b += sprintf(b, " src mac="); b += sprintf_eth_mac(b, ci->src.src_mac); b += fill_space_to(b, b - b_old, 45); b += sprintf(b, " src mac="); b += sprintf_eth_mac(b, ci->dst.src_mac); b += sprintf(b, "\n"); b_old = b; b += sprintf(b, " dst mac="); b += sprintf_eth_mac(b, ci->src.dst_mac); b += fill_space_to(b, b - b_old, 45); b += sprintf(b, " dst mac="); b += sprintf_eth_mac(b, ci->dst.dst_mac); b += sprintf(b, "\n"); } } if (uci) { uci[i].src_addr = ci->src_addr; uci[i].dst_addr = ci->dst_addr; uci[i].src_port = ci->src_port; uci[i].dst_port = ci->dst_port; } i++; } hash_iter_end(&iter); hash_unlock(&conn_table); if (ruci) *ruci = uci; if (rbuf) *rbuf = buf; return count;}void print_mac_table(void){ struct hash_iterator hi; char buf[BUFSIZE]; unsigned int key; struct mac_info *mi; int i = 0; printf("--- mac table ---\n"); hash_iter_set(&hi, &mac_table); while ((mi = hash_iter_get(&hi, &key))) { sprintf_eth_mac(buf, mi->mac); printf("%-24s %s\n", host_lookup(key, hl_mode), buf); if (++i % lines_o == 0) lines_o_press_key(); } hash_iter_end(&hi);}void print_user_conn_info(struct user_conn_info *uci, int count){ int i, ret; for (i = 0; i < count; i++) { ret = printf("%d) %s [%s]", i, host_lookup(uci->src_addr, hl_mode), port_lookup(uci->src_port, hl_mode)); printf("%*s", 25 - ret > 0 ? 20 - ret : 0, ""); printf(" --> "); printf("%s [%s]\n", host_lookup(uci->dst_addr, hl_mode), port_lookup(uci->dst_port, hl_mode)); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -