13
0
Fork 1
dedected/com-on-air_cs-linux/tools/pcap2cchan.c

247 lines
4.5 KiB
C

/*
* pcap2cchan dumps C-channel information from pcap files
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* authors:
* (C) 2008 Andreas Schuler <krater at badterrorist dot com>
* (C) 2008 Matthias Wenzel <dect at mazzoo dot de>
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dect_c_channel.h"
int main(int argc, char* argv[])
{
struct cfrag frag;
struct cpacket cpacket;
struct cdevice phone,station;
phone.type=station.type=0;
phone.cdata=station.cdata=0;
phone.found=station.found=0;
phone.cnt=station.cnt=0;
unsigned char packet[135];
unsigned int length;
FILE *pcap=fopen(argv[1],"rb");
fseek(pcap,0x18,SEEK_SET);
while(!feof(pcap))
{
fseek(pcap,12,SEEK_CUR);
fread(&length,4,1,pcap);
if(length>135)
{
printf("error , packet size too big\n");
exit(-1);
}
fread(packet,length,1,pcap);
frag=getcfrag(packet+23,packet[17]);
if(frag.valid)
{
if(packet[23]==0x16)
{
cpacket=getcpacket(frag,&phone);
//printf("Frag : %u -> %u:%.2x %.2x %.2x %.2x %.2x\n",frag.slot,frag.cttype,frag.data[0],frag.data[1],frag.data[2],frag.data[3],frag.data[4]);
if(cpacket.valid)
{
printcpacket(cpacket,"phone ");
}
}
else if(packet[23]==0xe9)
{
cpacket=getcpacket(frag,&station);
//printf("Frag : %u -> %u:%.2x %.2x %.2x %.2x %.2x\n",frag.slot,frag.cttype,frag.data[0],frag.data[1],frag.data[2],frag.data[3],frag.data[4]);
if(cpacket.valid)
printcpacket(cpacket,"station");
}
}
}
fclose(pcap);
return 0;
}
struct cfrag getcfrag(unsigned char *dect,int slot)
{
struct cfrag frag;
if((dect[2]&0xc0)==0) //Ct tail (?)
{
frag.valid=1;
frag.cttype=(dect[2]&0x20)>>5;
frag.slot=slot;
memcpy(frag.data,dect+3,5);
}
else
frag.valid=0;
return frag;
}
char *getstring(struct strtype *str,int id,int max)
{
int i;
for(i=0;i<max;i++)
{
if(str[i].type==id)
return str[i].name;
}
return NULL;
}
struct cpacket getcpacket(struct cfrag frag,struct cdevice *device)
{
device->packet.valid=0;
if((frag.cttype!=device->type)&&(!device->found))
{
device->packet.addr=frag.data[0];
device->packet.ctrl=frag.data[1];
device->packet.length=frag.data[2];
if((device->packet.length>>2)>0)
{
device->packet.data[0]=frag.data[3];
device->packet.data[1]=frag.data[4];
device->cdata+=2;
device->cnt=1;
device->found=1;
}
else
{
device->packet.checksum=(((unsigned short)(frag.data[3]))<<8)|(frag.data[4]);
device->packet.valid=1;
device->cdata=0;
device->cnt=0;
device->found=0;
}
device->type=!device->type;
}
else if(frag.cttype!=device->type)
{
memcpy(device->packet.data+device->cdata,frag.data,5);
device->cdata+=5;
device->cnt++;
device->type=!device->type;
if(device->cnt>=pklookup[device->packet.length>>2])
{
device->packet.checksum=(((unsigned short)(frag.data[3]))<<8)|(frag.data[4]);
device->packet.valid=1;
device->cdata=0;
device->cnt=0;
device->found=0;
}
}
else
{
//printf("packet loss (?)\n");
device->type=!device->type;
if(device->found)
{
memset(device->packet.data+device->cdata,0xff,5);
device->cdata+=5;
device->cnt++;
if(device->cnt>=pklookup[device->packet.length>>2])
{
device->cdata=0;
device->packet.valid=1;
device->found=0;
printcpacket(device->packet,"failed ");
}
}
getcpacket(frag,device);
}
return device->packet;
}
void printcpacket(struct cpacket packet,char *prefix)
{
int x;
printf("\n%s: addr:%.2x ctrl:%.2x len:%.2x crc:%.4x",prefix,packet.addr,packet.ctrl,packet.length,packet.checksum);
if(packet.length>>2)
{
printf(" -> ");
char id=packet.data[1];
switch(packet.data[0]&0x0f)
{
case 0:
printf("%s :%s",msgtype[packet.data[0]&0x0f].name,NULL);
break;
case 3:
printf("%s :%s",msgtype[packet.data[0]&0x0f].name,getstring(cctype,id,256));
break;
case 4:
printf("%s :%s",msgtype[packet.data[0]&0x0f].name,getstring(sstype,id,256));
break;
case 5:
printf("%s :%s",msgtype[packet.data[0]&0x0f].name,getstring(mmtype,id,256));
break;
case 6:
printf("%s :%s",msgtype[packet.data[0]&0x0f].name,NULL);
break;
case 7:
printf("%s :%s",msgtype[packet.data[0]&0x0f].name,NULL);
break;
default:
printf("reserved ");
break;
}
printf(" ");
for(x=0;x<(packet.length>>2);x++)
printf(" %.2x",packet.data[x]);
}
// printf("\n\n\n");
}