⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bnpcap.c

📁 打魔兽战网的都知道他是什么
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 2001  Marco Ziech (mmz@gmx.net) * * 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 "common/setup_before.h"#include <stdio.h>#include <pcap.h>#include <errno.h>#include <netinet/in.h>#include <string.h>#include <stdlib.h>#include "compat/strerror.h"#include "compat/getopt.h"#include "common/init_protocol.h"#include "common/bnet_protocol.h"#include "common/udp_protocol.h"#include "common/packet.h"#include "common/eventlog.h"#include "common/hexdump.h"#include "common/list.h"#include "common/version.h"#include "common/util.h"#include "common/setup_after.h"/* FIXME: everywhere: add checks for NULL pointers */char *filename = NULL;pcap_t *pc;char ebuf[PCAP_ERRBUF_SIZE];int bnpcap_dodebug = 0;int bnpcap_beverbose = 0;unsigned int listen_port = 6112;/********************* CONNECTIONS ********************/typedef enum {   tcp_state_none,     tcp_state_syn,     tcp_state_ack,     tcp_state_ok} t_tcp_state;typedef struct {   /* It's IPV4 */   unsigned int ip;   unsigned short port;} t_bnpcap_addr;/* To track connections ... */typedef struct {   t_bnpcap_addr client;   t_bnpcap_addr server;   t_packet_class class;   t_tcp_state tcpstate;   int incomplete;   int clientoff;   t_packet *clientpkt;   int serveroff;   t_packet *serverpkt;   t_list * packets;} t_bnpcap_conn;typedef struct {   t_packet_dir dir;   struct timeval tv;   unsigned int id;   t_packet *p;} t_bnpcap_packet;t_list * conns;t_list * udppackets;struct timeval packettime;static unsigned int current_packet_id = 1;/*********************** HEADERS **********************//* FIXME: don't assume that's always true */typedef unsigned char u8;typedef unsigned short u16;typedef unsigned int u32;/************************** TCP ***********************/typedef struct {   u16 sport;   u16 dport;   u32 seqno;   u32 ackno;   u16 stuff; /* Data offset, various flags */   u16 window;   u16 checksum;   u16 urgp;  /* Urgent Pointer (if URG flag set) */   /* options */} t_tcp_header_raw;typedef struct {   unsigned short sport;   unsigned short dport;   unsigned int seqno;   unsigned int ackno;   unsigned char doffset;   unsigned short flags;#define TCP_URG 0x20 /* Urgent pointer field significant */#define TCP_ACK 0x10 /* Acknowlegdement field significant */#define TCP_PSH 0x08 /* Push function */#define TCP_RST 0x04 /* Reset connection */#define TCP_SYN 0x02 /* Synchronize sequence numbers */#define TCP_FIN 0x01 /* No more data from sender (finish) */   unsigned short window;   unsigned short checksum;   unsigned short urgp;   /* options */} t_tcp_header;/******************************** UDP ************************/typedef struct {   u16 sport;   u16 dport;   u16 len;   u16 checksum;} t_ip_udp_header_raw;typedef struct {   unsigned short sport;   unsigned short dport;   unsigned short len;   unsigned short checksum;} t_ip_udp_header;/******************************** IP *************************/typedef struct {   u8 versionihl;   u8 tos;   u16 len;   u16 id;   u16 flagsoffset;   u8 ttl;   u8 protocol;   u16 checksum;   u32 src;   u32 dst;   /* options */} t_ip_header_raw;typedef struct {   unsigned char version;   unsigned char ihl;   unsigned char tos;   unsigned short len;   unsigned short id;   unsigned char flags;#define IP_DF 0x02 /* 1 == Don't fragment */#define IP_MF 0x01 /* 1 == More fragments */   unsigned short offset;   unsigned char ttl;   unsigned char protocol;   unsigned short checksum;   unsigned int src;   unsigned int dst;   /* options */} t_ip_header;/******************************* ETHERNET *****************************/typedef struct {   u8 dst[6]; /* Ethernet hardware address */   u8 src[6]; /* Ethernet hardware address */   u16 type;  /* Ethernet_II: protocol type */       /* FIXME: Ethernet [802.2|802.3|SNAP]: maybe something else (eg. length) */} t_ether_raw;/************************************************************************//************************* CONNECTION FUNCTIONS *************************/static t_bnpcap_conn * bnpcap_conn_new(t_bnpcap_addr const *s, t_bnpcap_addr const *d){   t_bnpcap_conn * c;      c = (t_bnpcap_conn *) malloc(sizeof(t_bnpcap_conn)); /* avoid warning */   if (!c) {      eventlog(eventlog_level_error,__FUNCTION__,"malloc failed: %s",pstrerror(errno));      return NULL;   }   if (d->port==listen_port || d->port==6200) { /* FIXME: That's dirty: We assume the server is on port 6112 */      memcpy(&c->client,s,sizeof(t_bnpcap_addr));      memcpy(&c->server,d,sizeof(t_bnpcap_addr));   } else {      memcpy(&c->client,d,sizeof(t_bnpcap_addr));      memcpy(&c->server,s,sizeof(t_bnpcap_addr));   }   c->class = packet_class_init;   c->packets = list_create();   c->incomplete = 0;   c->tcpstate = tcp_state_none;   c->clientoff = 0;   c->clientpkt = NULL;   c->serveroff = 0;   c->serverpkt = NULL;   return c;}static void bnpcap_conn_set_class(t_bnpcap_conn *c, t_packet_class class){   c->class = class;}static t_packet_class bnpcap_conn_get_class(t_bnpcap_conn *c){   return c->class;}static t_bnpcap_conn * bnpcap_conn_find(t_bnpcap_addr const *s, t_bnpcap_addr const *d){   t_elem * curr;   LIST_TRAVERSE(conns,curr) {      t_bnpcap_conn *c;            c = elem_get_data(curr);      if (((c->client.ip==s->ip)&&(c->client.port==s->port))&&	  ((c->server.ip==d->ip)&&(c->server.port==d->port))) {	 return c;      } else if (((c->client.ip==d->ip)&&(c->client.port==d->port))&&		 ((c->server.ip==s->ip)&&(c->server.port==s->port))) {	 return c;      }   }   return NULL;}static t_packet_dir bnpcap_conn_get_dir(t_bnpcap_conn const * c, t_bnpcap_addr const *s, t_bnpcap_addr const *d){   if (((c->client.ip==s->ip)&&(c->client.port==s->port))&&       ((c->server.ip==d->ip)&&(c->server.port==d->port)))     return packet_dir_from_client;   else     return packet_dir_from_server;}static int bnpcap_conn_add_packet(t_bnpcap_conn *c, t_bnpcap_packet *bp) {   eventlog(eventlog_level_debug,__FUNCTION__,"id=%u ",bp->id);   list_append_data(c->packets,bp);   packet_add_ref(bp->p);   return 0;}static int bnpcap_conn_packet(unsigned int sip, unsigned short sport, unsigned int dip, unsigned short dport, unsigned char const * data, unsigned int len){   t_bnpcap_addr s;   t_bnpcap_addr d;   t_bnpcap_conn *c;   t_bnpcap_packet *bp;      s.ip = sip;   s.port = sport;   d.ip = dip;   d.port = dport;     if ((c = bnpcap_conn_find(&s,&d))) {      eventlog(eventlog_level_debug,__FUNCTION__,"adding packet to existing connection");      if (c->tcpstate==tcp_state_ack) {	 c->tcpstate = tcp_state_ok;      } else if (c->tcpstate==tcp_state_syn) {	 c->incomplete = 1; /* ACK missing */	 c->tcpstate = tcp_state_ok;      }   } else {      eventlog(eventlog_level_debug,__FUNCTION__,"adding packet to incomplete connection");      c = bnpcap_conn_new(&s,&d);      bnpcap_conn_set_class(c,packet_class_raw); /* we don't know the init sequence */      c->incomplete = 1;      c->tcpstate = tcp_state_ok;       list_append_data(conns,c);   }   if (c->tcpstate!=tcp_state_ok) {      eventlog(eventlog_level_warn,__FUNCTION__,"connection got packet in wrong state!");   }   if (bnpcap_conn_get_class(c) == packet_class_init) {       if (len>1) {	 eventlog(eventlog_level_warn,__FUNCTION__,"init packet larger than 1 byte");      }      switch (data[0]) {       case CLIENT_INITCONN_CLASS_BNET:	 bnpcap_conn_set_class(c,packet_class_bnet);	 break;       case CLIENT_INITCONN_CLASS_FILE:	 bnpcap_conn_set_class(c,packet_class_file);	 break;       case 0xf7: // W3 matchmaking hack	 eventlog(eventlog_level_info,__FUNCTION__,"matchmaking packet");	   bnpcap_conn_set_class(c,packet_class_bnet);	   break;       default:	 bnpcap_conn_set_class(c,packet_class_raw);      }   } else {      t_packet *p;      unsigned int off;      unsigned char const *datap = data;      int always_complete = 0;            if (bnpcap_conn_get_class(c) == packet_class_raw)	always_complete = 1; /* There is no size field */      if (bnpcap_conn_get_class(c) == packet_class_file)	always_complete = 1; /* Size field isn't always there */      if (always_complete) {	 /* packet is always complete */	 eventlog(eventlog_level_debug,__FUNCTION__,"packet is always complete (class=%d)",bnpcap_conn_get_class(c));	 bp = (t_bnpcap_packet *) malloc(sizeof(t_bnpcap_packet)); /* avoid warning */	 if (!bp) {	    eventlog(eventlog_level_error,__FUNCTION__,"malloc failed: %s",pstrerror(errno));	    return -1;	 }	 bp->dir = bnpcap_conn_get_dir(c,&s,&d);	 bp->p = packet_create(bnpcap_conn_get_class(c));	 bp->id = current_packet_id++;	 if (!bp->p) {	    eventlog(eventlog_level_error,__FUNCTION__,"packet_create failed");	    return -1;	 }	 memcpy(&bp->tv,&packettime,sizeof(struct timeval));	 packet_set_size(bp->p,len);	 memcpy(packet_get_raw_data(bp->p,0),data,len);	 bnpcap_conn_add_packet(c,bp);	 if ((packet_get_class(bp->p)==packet_class_file)&&(packet_get_type(bp->p)==SERVER_FILE_REPLY)) {	    eventlog(eventlog_level_debug,__FUNCTION__,"file transfer initiated (setting to raw)");	    bnpcap_conn_set_class(c,packet_class_raw);	 }      } else {	 /* read out saved state */	 if (bnpcap_conn_get_dir(c,&s,&d)==packet_dir_from_client) {	    p = c->clientpkt;	    off = c->clientoff;	 } else {	    p = c->serverpkt;	    off = c->serveroff;	 }	 while ((datap-data)<(signed)len) {	    if (!p) {	       eventlog(eventlog_level_debug,__FUNCTION__,"creating new packet");	       p = packet_create(bnpcap_conn_get_class(c));	       if (!p) {		  eventlog(eventlog_level_error,__FUNCTION__,"packet_create failed");		  return -1;	       }	       packet_set_size(p,packet_get_header_size(p)); /* set it to the minimum for now */	       off = 0;	    }	    if (off < packet_get_header_size(p)) {	       unsigned int l = (packet_get_header_size(p)-off);	       /* (len-(datap-data)) : remaining bytes in buffer */	       if ((len-(datap-data)) < l)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -