📄 sniff.c
字号:
/* * sniff.c * * 2006 Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru> * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include <sys/poll.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/mman.h>#include <sys/ioctl.h>#include <fcntl.h>#include <stdio.h>#include <errno.h>#include <string.h>#include <unistd.h>#include <stdlib.h>#include <ctype.h>#include <net/ethernet.h>#include <netinet/ip.h>#include <netinet/tcp.h>#include <arpa/inet.h>#include "include/linux/types.h"#include "net/core/alloc/avl.h"#include "control.h"static void zc_usage(char *p){ fprintf(stderr, "Usage: %s -f sniffer_file -c nr_cpus -h\n", p);}static void zc_analyze_write(int out_fd, void *ptr, unsigned int size){ int err; err = write(out_fd, ptr, size); if (err != (signed)size) { fprintf(stderr, "Failed to write %u bytes: %s [%d].\n", size, strerror(errno), errno); return; }}#define NIPE(eth) \ (eth)->ether_shost[0], \ (eth)->ether_shost[1], \ (eth)->ether_shost[2], \ (eth)->ether_shost[3], \ (eth)->ether_shost[4], \ (eth)->ether_shost[5], \ (eth)->ether_dhost[0], \ (eth)->ether_dhost[1], \ (eth)->ether_dhost[2], \ (eth)->ether_dhost[3], \ (eth)->ether_dhost[4], \ (eth)->ether_dhost[5]#define NIPQUAD(addr) \ ((unsigned char *)&addr)[0], \ ((unsigned char *)&addr)[1], \ ((unsigned char *)&addr)[2], \ ((unsigned char *)&addr)[3]static void zc_analyze(int out_fd, void *ptr, unsigned int size){ struct ether_header *eth; struct iphdr *iph; struct tcphdr *th; unsigned char *p = ptr; __u16 sport, dport; eth = ptr + 18;#if 0 printf("%02x:%02x:%02x:%02x:%02x:%02x -> %02x:%02x:%02x:%02x:%02x:%02x, type: %04x, ", NIPE(eth), ntohs(eth->ether_type));#endif if (eth->ether_type == 0xabab) { eth = ptr + 190;#if 0 unsigned int i; p = ptr + 180; for (i=0; i<32; ++i) printf("%02x ", p[i]); printf("\n"); goto out_exit;#endif } if (eth->ether_type != ntohs(ETHERTYPE_IP)) goto out_exit; iph = (struct iphdr *)(eth + 1); sport = ((__u16 *)(((void *)iph) + (iph->ihl<<2)))[0]; dport = ((__u16 *)(((void *)iph) + (iph->ihl<<2)))[1]; if (iph->protocol != IPPROTO_TCP) goto out_exit;#if 1 printf("%u.%u.%u.%u:%u -> %u.%u.%u.%u:%u, proto: %u, ", NIPQUAD(iph->saddr), ntohs(sport), NIPQUAD(iph->daddr), ntohs(dport), iph->protocol);#endif th = (struct tcphdr *)(((void *)iph) + (iph->ihl<<2)); printf("seq: %u, ack: %u, ", ntohl(th->seq), ntohl(th->ack_seq)); printf("\n");out_exit: return;}int main(int argc, char *argv[]){ int ch, err, out_fd; unsigned int i, num, nr_cpus; char *ctl_file, *out_file; struct zc_data zcb[1024]; struct pollfd *pfd; struct zc_control *zc_ctl, *ctl; ctl_file = out_file = NULL; nr_cpus = 2; while ((ch = getopt(argc, argv, "f:o:c:h")) != -1) { switch (ch) { case 'c': nr_cpus = atoi(optarg); break; case 'o': out_file = optarg; break; case 'f': ctl_file = optarg; break; case 'h': default: zc_usage(argv[0]); return 0; } } if (nr_cpus > 1024) { fprintf(stderr, "Wrong number of CPUs %d.\n", nr_cpus); zc_usage(argv[0]); return -1; } if (!ctl_file || !out_file) { fprintf(stderr, "You must call %s with -f and -o parameters.\n", argv[0]); zc_usage(argv[0]); return -1; } out_fd = open(out_file, O_RDWR | O_CREAT | O_TRUNC, 0644); if (!out_fd) { fprintf(stderr, "Failed to open output file %s: %s [%d].\n", out_file, strerror(errno), errno); return -1; } pfd = malloc(sizeof(struct pollfd) * nr_cpus); if (!pfd) { fprintf(stderr, "Failed to allocate polling structures for %d cpus.\n", nr_cpus); return -ENOMEM; } memset(pfd, 0, sizeof(struct pollfd) * nr_cpus); zc_ctl = zc_ctl_init(nr_cpus, ctl_file); if (!zc_ctl) return -1; for (i=0; i<nr_cpus; ++i) { pfd[i].fd = zc_ctl[i].fd; pfd[i].events = POLLIN; pfd[i].revents = 0; } while (1) { int poll_ready, j; poll_ready = poll(pfd, nr_cpus, 1000); if (poll_ready == 0) continue; if (poll_ready < 0) break; for (j=0; j<poll_ready; ++j) { if ((!pfd[j].revents & POLLIN)) continue; pfd[j].events = POLLIN; pfd[j].revents = 0; err = read(zc_ctl[0].fd, zcb, sizeof(zcb)); if (err <= 0) { fprintf(stderr, "Failed to read data from control file %s: %s [%d].\n", ctl_file, strerror(errno), errno); break; } num = err/sizeof(struct zc_data); for (i=0; i<num; ++i) { struct zc_data *z; void *ptr; struct zc_data *e; z = &zcb[i]; if (z->entry >= ZC_MAX_ENTRY_NUM || z->cpu >= nr_cpus) continue; ctl = &zc_ctl[z->cpu]; if (zc_prepare(ctl, z->entry)) continue; e = &ctl->e[z->entry];#if 0 printf("dump %4d.%4d: ptr: %p, start: %p, size: %u, off: %u: entry: %u, cpu: %d: ", i, num, z->data.ptr, z->start.ptr, z->size, z->off, z->entry, z->cpu);#endif ptr = e->data.ptr + z->off; zc_analyze_write(out_fd, ptr, z->size); //zc_analyze(out_fd, ptr, z->size); } err = write(zc_ctl[0].fd, zcb, num*sizeof(struct zc_data)); if (err < 0) { fprintf(stderr, "Failed to write data to control file %s: %s [%d].\n", ctl_file, strerror(errno), errno); break; } else if (err == 0) { write(zc_ctl[0].fd, zcb, num*sizeof(struct zc_data)); } } } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -