182 lines
4.6 KiB
C
182 lines
4.6 KiB
C
//#include <stdio.h>
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
# include "config.h"
|
|
#endif
|
|
|
|
#include <stdint.h>
|
|
#include <epan/prefs.h>
|
|
#include <epan/packet.h>
|
|
#include <epan/column-info.h>
|
|
#include <epan/dissectors/packet-tcp.h>
|
|
#include <ws_version.h>
|
|
|
|
#ifndef ENABLE_STATIC
|
|
WS_DLL_PUBLIC_DEF const gchar plugin_version[] = "0.0.2-pre-b1";
|
|
WS_DLL_PUBLIC_DEF const gchar plugin_release[] = "3.2"; //VERSION_RELEASE
|
|
WS_DLL_PUBLIC_DEF const int plugin_want_major = WIRESHARK_VERSION_MAJOR;
|
|
WS_DLL_PUBLIC_DEF const int plugin_want_minor = WIRESHARK_VERSION_MINOR;
|
|
#endif
|
|
|
|
#define PROTO_PORT 25565
|
|
#define PROTO_TAG "MCPC"
|
|
#define PROTO_TAG_PARTIAL "MCPC partial"
|
|
|
|
//#include "VarUtils.h"
|
|
#include <stdio.h>
|
|
|
|
static int proto_mcpc=-1;
|
|
static dissector_handle_t mcpc_handle;
|
|
|
|
int8_t VarIntToUint(const guint8 *varint, uint32_t *result, uint_fast8_t maxlen){
|
|
int8_t i=0;
|
|
*result=0;
|
|
do{
|
|
if(i>5)
|
|
break;
|
|
*result |= (varint[i]&0x7F) << (i*7);
|
|
if(i>maxlen)
|
|
return -1;
|
|
}while((varint[i++]&0x80) != 0);
|
|
return i;
|
|
}
|
|
|
|
static guint getlen(packet_info *pinfo, tvbuff_t *tvb, int offset _U_, void *data _U_){
|
|
int8_t ret;
|
|
uint32_t len;
|
|
guint8 packet_length;
|
|
packet_length=tvb_reported_length(tvb);//To read
|
|
if(packet_length==0)
|
|
return 0;
|
|
// return tvb_captured_length(tvb);
|
|
|
|
const guint8 *dt;
|
|
dt=tvb_get_ptr(tvb, pinfo->desegment_offset, packet_length);
|
|
ret=VarIntToUint(dt, &len, packet_length);
|
|
if(ret==-1)
|
|
return 0;
|
|
else if(ret==0){
|
|
return 1;
|
|
}else
|
|
return len+ret;
|
|
}
|
|
|
|
static int subdissect_mcpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void *data _U_){
|
|
col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG);//Set MCPC protocol tag
|
|
|
|
uint32_t protocol_length, varint;
|
|
guint8 packet_length, readed;
|
|
int8_t varlen;
|
|
const guint8 *dt;
|
|
|
|
packet_length=tvb_reported_length(tvb);//To read
|
|
|
|
dt=tvb_get_ptr(tvb, pinfo->desegment_offset, packet_length);
|
|
|
|
readed=VarIntToUint(dt, &protocol_length, packet_length);
|
|
if(readed<0)
|
|
return -1;
|
|
else if(packet_length<protocol_length)
|
|
return packet_length-protocol_length;
|
|
|
|
if(protocol_length<=pinfo->fd->pkt_len){
|
|
varlen=VarIntToUint(dt+readed, &varint, packet_length-readed);
|
|
if(varlen>0)
|
|
readed+=varlen;
|
|
else
|
|
return -1;
|
|
if(varlen>5)
|
|
return 0;
|
|
}
|
|
|
|
static char buf[32];
|
|
// if(u>10000)
|
|
// __asm("int $3");
|
|
if(pinfo->destport==25565)
|
|
sprintf(buf, "Result: [C->S] %u bytes, 0x%X", packet_length, varint);
|
|
else
|
|
sprintf(buf, "Result: [S->C] %u bytes, 0x%X"/*Length: %u*/, packet_length, varint);
|
|
col_set_str(pinfo->cinfo, COL_INFO, buf);
|
|
|
|
return tvb_captured_length(tvb);
|
|
}
|
|
static int dissect_mcpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data){
|
|
tcp_dissect_pdus(tvb, pinfo, tree, TRUE, 0,
|
|
getlen, subdissect_mcpc, data);
|
|
return tvb_captured_length(tvb);
|
|
}
|
|
|
|
/*static int dissect_mcpc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, void *data _U_){
|
|
col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG);//Set MCPC protocol tag
|
|
|
|
uint32_t protocol_length, varint;
|
|
guint8 packet_length, readed;
|
|
int8_t varlen;
|
|
|
|
packet_length=tvb_reported_length(tvb);//To read
|
|
if(packet_length==0)
|
|
return tvb_captured_length(tvb);
|
|
|
|
const guint8 *dt;
|
|
dt=tvb_get_ptr(tvb, pinfo->desegment_offset, packet_length);
|
|
|
|
readed=VarIntToUint(dt, &protocol_length, packet_length);
|
|
if(readed<0)
|
|
return -1;
|
|
else if(packet_length<protocol_length)
|
|
return packet_length-protocol_length;
|
|
|
|
if(protocol_length<=pinfo->fd->pkt_len){
|
|
varlen=VarIntToUint(dt, &varint, packet_length-readed);
|
|
if(varlen>0)
|
|
readed+=varlen;
|
|
else
|
|
return -1;
|
|
if(varlen>5)
|
|
return 0;
|
|
}
|
|
|
|
static char buf[32];
|
|
if(varlen>5)
|
|
col_set_str(pinfo->cinfo, COL_INFO, "varint parse error");
|
|
else{
|
|
// if(u>10000)
|
|
// __asm("int $3");
|
|
if(pinfo->destport==25565)
|
|
sprintf(buf, "[C->S] Length: %u", packet_length);
|
|
else
|
|
sprintf(buf, "[S->C] Length: %u", packet_length);
|
|
col_set_str(pinfo->cinfo, COL_INFO, buf);
|
|
}
|
|
return tvb_captured_length(tvb);
|
|
}*/
|
|
|
|
|
|
//Protocol register functions
|
|
static void proto_reg_handoff_mcpc(void)
|
|
{
|
|
mcpc_handle = create_dissector_handle(dissect_mcpc, proto_mcpc);
|
|
dissector_add_uint("tcp.port", PROTO_PORT, mcpc_handle);
|
|
}
|
|
static void proto_register_mcpc(){
|
|
/* name */ /* short name */ /* abbrev */
|
|
proto_mcpc = proto_register_protocol ("Minecraft PC version",
|
|
"Minecraft",
|
|
"mcpc");
|
|
}
|
|
|
|
|
|
//Plugin register function
|
|
#ifndef ENABLE_STATIC
|
|
//#if 0
|
|
WS_DLL_PUBLIC void plugin_register(){
|
|
/* register the new protocol, protocol fields, and subtrees */
|
|
if (proto_mcpc == -1) { /* execute protocol initialization only once */
|
|
static proto_plugin plug;
|
|
plug.register_handoff=proto_reg_handoff_mcpc;
|
|
plug.register_protoinfo=proto_register_mcpc;
|
|
proto_register_plugin(&plug);
|
|
}
|
|
}
|
|
#endif
|