📄 hunt.c
字号:
if (!conn_skip_update(ci, p)) { if (p->p_iph->saddr == ci->src_addr && p->p_iph->daddr == ci->dst_addr && p->p_hdr.p_tcph->source == ci->src_port && p->p_hdr.p_tcph->dest == ci->dst_port) { /* from source to dest */ if (p->p_hdr.p_tcph->seq == ci->dst.next_d_seq) remove_it = 1; } else { /* from dest to source */ if (p->p_hdr.p_tcph->seq == ci->src.next_d_seq) remove_it = 1; } } } if (remove_it) { if (ci == hash_remove(&conn_table, key, &uci)) conn_free(ci); hash_unlock(&conn_table); } else { hash_unlock(&conn_table); conn_add_update(p); }}static void conn_add(struct packet *p){ struct conn_info *ci; struct user_conn_info uci; 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)) { ip = *(unsigned int *) arpethh->ar_sip; mac = arpethh->ar_sha; } else { ip = *(unsigned int *) arpethh->ar_tip; mac = arpethh->ar_tha; } mac_table_update(ip, mac);}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 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_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(), -10); 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 !! */ ALIGNPOINTERS_ETH(p, ethh); p->p_ethh = ethh; p->p_timestamp = time(NULL); switch (ntohs(ethh->h_proto)) { case ETH_P_IP: ALIGNPOINTERS_IP(ethh, iph); p->p_iph = iph; if (mac_learn_from_ip) mac_ip_learn(p); process_ip(p); switch (iph->protocol) { case IPPROTO_TCP: 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); conn_update_table(p, ethh, iph); fast_tcp_process(p); process_tcp(p); break; case IPPROTO_UDP: p->p_type = PACKET_UDP; ALIGNPOINTERS_UDP(iph, p->p_hdr.p_udph, p->p_data); process_udp(p); break; case IPPROTO_ICMP: p->p_type = PACKET_ICMP; ALIGNPOINTERS_ICMP(iph, p->p_hdr.p_icmph, p->p_data); process_icmp(p); break; } break; case ETH_P_ARP: p->p_type = PACKET_ARP; ALIGNPOINTERS_ARP(ethh, p->p_arph); mac_arp_learn(p); process_arp(p); break; } } packet_free(p); } return NULL;}/* * * helper functions * */void print_tcp(struct iphdr *ip, struct tcphdr *tcp){ fprintf(stdout, "%s [%d] seq=(%u) ack=(%u)\t--->\t%s [%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));}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) { assert(buf = malloc(count * 512)); b = buf; } else b = buf = NULL; if (ruci) assert(uci = malloc(count * sizeof(struct user_conn_info))); 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 + -