mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-18 20:57:56 +00:00
Reimported features from Raiders Of The Lost Source (gateway, hlr import/export)
This commit is contained in:
parent
f024213414
commit
bba5ec6bd8
2
Makefile
2
Makefile
@ -1,5 +1,5 @@
|
||||
OBJS= dna.o server.o client.o peers.o ciphers.o responses.o packetformats.o dataformats.o \
|
||||
hlrdata.o srandomdev.o simulate.o batman.o overlay.o
|
||||
hlrdata.o srandomdev.o simulate.o batman.o overlay.o export.o
|
||||
HDRS= Makefile mphlr.h
|
||||
LDFLAGS=
|
||||
DEFS= -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DHAVE_LIBC=1 -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_STDIO_H=1 -DHAVE_ERRNO_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRINGS_H=1 -DHAVE_UNISTD_H=1 -DHAVE_STRING_H=1 -DHAVE_ARPA_INET_H=1 -DHAVE_SYS_SOCKET_H=1 -DHAVE_SYS_MMAN_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_POLL_H=1 -DHAVE_NETDB_H=1
|
||||
|
@ -1,5 +1,5 @@
|
||||
OBJS= dna.o server.o client.o peers.o ciphers.o responses.o packetformats.o dataformats.o \
|
||||
hlrdata.o srandomdev.o simulate.o batman.o overlay.o
|
||||
hlrdata.o srandomdev.o simulate.o batman.o overlay.o export.o
|
||||
HDRS= Makefile mphlr.h
|
||||
LDFLAGS= @LDFLAGS@
|
||||
DEFS= @DEFS@
|
||||
|
39
dna.c
39
dna.c
@ -18,9 +18,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "mphlr.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
char *gatewayuri=NULL;
|
||||
|
||||
char *outputtemplate=NULL;
|
||||
char *instrumentation_file=NULL;
|
||||
char *importFile=NULL;
|
||||
|
||||
int debug=0;
|
||||
int timeout=3000; /* 3000ms request timeout */
|
||||
@ -112,12 +116,23 @@ int dumpResponses(struct response_set *responses)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int setReason(char *msg)
|
||||
int setReason(char *fmt, ...)
|
||||
{
|
||||
va_list ap,ap2;
|
||||
char msg[8192];
|
||||
|
||||
va_start(ap,fmt);
|
||||
va_copy(ap2,ap);
|
||||
|
||||
vsnprintf(msg,8192,fmt,ap2); msg[8191]=0;
|
||||
|
||||
va_end(ap);
|
||||
|
||||
fprintf(stderr,"Error: %s\n",msg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int hexvalue(unsigned char c)
|
||||
{
|
||||
if (c>='0'&&c<='9') return c-'0';
|
||||
@ -200,7 +215,7 @@ int usage(char *complaint)
|
||||
{
|
||||
fprintf(stderr,"dna: %s\n",complaint);
|
||||
fprintf(stderr,"usage:\n");
|
||||
fprintf(stderr," dna [-v ...] -S <hlr size in MB> [-f HLR backing file]\n");
|
||||
fprintf(stderr," dna [-v ...] -S <hlr size in MB> [-f HLR backing file] [-I import.txt] [-G SIP gateway]\n");
|
||||
fprintf(stderr,"or\n");
|
||||
fprintf(stderr," dna <-d|-s> id -A\n");
|
||||
fprintf(stderr,"or\n");
|
||||
@ -211,6 +226,8 @@ int usage(char *complaint)
|
||||
fprintf(stderr," [-v ...] [-t request timeout in ms]\n");
|
||||
fprintf(stderr,"or\n");
|
||||
fprintf(stderr," dna [-v ...] [-t timeout] -d did -C\n");
|
||||
fprintf(stderr,"or\n");
|
||||
fprintf(stderr," dna [-v ...] -f <hlr.dat> -E <export.txt>\n");
|
||||
|
||||
fprintf(stderr,"\n");
|
||||
fprintf(stderr," -v - increase verbosity.\n");
|
||||
@ -259,10 +276,26 @@ int main(int argc,char **argv)
|
||||
|
||||
srandomdev();
|
||||
|
||||
while((c=getopt(argc,argv,"Ab:B:S:f:d:i:l:L:np:P:s:t:vR:W:U:D:CO:")) != -1 )
|
||||
while((c=getopt(argc,argv,"Ab:B:E:G:I:S:f:d:i:l:L:np:P:s:t:vR:W:U:D:CO:")) != -1 )
|
||||
{
|
||||
switch(c)
|
||||
{
|
||||
case 'G': /* Offer gateway services */
|
||||
gatewayuri=strdup(optarg);
|
||||
break;
|
||||
case 'E': /* Export HLR into plain text file that can be imported later */
|
||||
if (!hlr_file) usage("You must specify an HLR file to export from, i.e., dna -f hlr.dat -E hlr.txt");
|
||||
return exportHlr((unsigned char*)hlr_file,optarg);
|
||||
break;
|
||||
case 'I': /* Import HLR data from a plain text file into current HLR */
|
||||
if (importFile) usage("-I multiply specified.");
|
||||
importFile=optarg;
|
||||
if (!hlr_file||!serverMode) usage("-I requires -S and -f.");
|
||||
if (openHlrFile(hlr_file,hlr_size))
|
||||
exit(setReason("Failed to open HLR database"));
|
||||
importHlr(importFile);
|
||||
return 0;
|
||||
break;
|
||||
case 'n': /* don't detach from foreground in server mode */
|
||||
foregroundMode=1; break;
|
||||
case 'b': /* talk peers on a BATMAN mesh */
|
||||
|
255
export.c
Normal file
255
export.c
Normal file
@ -0,0 +1,255 @@
|
||||
/*
|
||||
Export the contents of an binary formatted HLR into plain text.
|
||||
|
||||
*/
|
||||
|
||||
#include "mphlr.h"
|
||||
|
||||
int nyblValue(int c)
|
||||
{
|
||||
if (c>='0'&&c<='9') return c-'0';
|
||||
if (c>='A'&&c<='F') return c-'A'+10;
|
||||
if (c>='a'&&c<='f') return c-'a'+10;
|
||||
exit(setReason("Illegal character `%c' in hexadecimal value.",c));
|
||||
}
|
||||
|
||||
int importHlr(char *textfile)
|
||||
{
|
||||
int j;
|
||||
FILE *i;
|
||||
unsigned char line[1024];
|
||||
char sid[128];
|
||||
int state=0;
|
||||
int hofs=-1;
|
||||
int varinst;
|
||||
int varid;
|
||||
int varlen;
|
||||
unsigned char data[65536];
|
||||
int dlen=0;
|
||||
int linenum=0;
|
||||
|
||||
if (!strcmp("-",textfile)) i=stdin;
|
||||
else
|
||||
if ((i=fopen(textfile,"r"))==NULL) exit(setReason("Could not open import file `%s'"));
|
||||
|
||||
line[0]=0; fgets((char *)line,1024,i);
|
||||
while(!feof(i))
|
||||
{
|
||||
int l=strlen((char *)line);
|
||||
linenum++;
|
||||
|
||||
/* Strip CR/LFs */
|
||||
while(l>0&&(line[l-1]=='\n'||line[l-1]=='\r')) l--; line[l]=0;
|
||||
|
||||
/* Sanity check line */
|
||||
for(j=0;j<l;j++) if ((line[j]<' ')||((line[j]>0x7f)&&line[j]!='\n')) {
|
||||
exit(setReason("Illegal character 0x%02x encountered in line %d of HLR import file.",line[j],linenum));
|
||||
}
|
||||
|
||||
if (line[0]!='#')
|
||||
{
|
||||
/* Deal with line */
|
||||
switch(state)
|
||||
{
|
||||
case 0: /* looking for a control line */
|
||||
if (!strncmp("sid=",(char *)line,4)) {
|
||||
/* Read SID, and create HLR record for it if one doesn't already exist */
|
||||
if (l!=4+SID_SIZE*2)
|
||||
exit(setReason("Malformed sid= line encountered in line %d of HLR import file.",linenum));
|
||||
|
||||
/* Extract SID */
|
||||
for(j=0;j<SID_SIZE*2;j++) sid[j]=line[4+j]; sid[SID_SIZE*2]=0;
|
||||
|
||||
/* Find or Create HLR Record */
|
||||
if (findHlr(hlr,&hofs,sid,NULL))
|
||||
{
|
||||
/* Have found HLR record for this SID, so no need to create */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No matching HLR record, so create one.
|
||||
Actually, we can't create it until we have the first DID for it,
|
||||
so set hofs to -1 to remind us to do that. */
|
||||
hofs=-1;
|
||||
}
|
||||
|
||||
/* Note that now we are looking for record contents */
|
||||
state=1;
|
||||
} else {
|
||||
exit(setReason("Unexpected line encountered in line %d of HLR import file -- was looking for a sid= line.",linenum));
|
||||
}
|
||||
break;
|
||||
case 1: /* Reading a HLR record set of values */
|
||||
if (!strcmp("eor",(char *)line))
|
||||
{
|
||||
state=0;
|
||||
if (hofs==-1)
|
||||
{
|
||||
/* whoops, we never got around to creating this record because it didn't contain any DIDs.
|
||||
This is something that should probably be complained about.
|
||||
It could also potentially arise when importing an export from an unhappy HLR, but because of the way
|
||||
that we enforce the presense of at least on DID when creating an HLR entry, this should not occur in
|
||||
normal operations. */
|
||||
exit(setReason("Encountered end of exported record at line %d without seeing a DID assignment. This is bad.\n"
|
||||
" sid= should be followed by a var=80:00 line.",linenum));
|
||||
}
|
||||
}
|
||||
else if (sscanf((char *)line,"var=%02x:%02x len=%d",&varid,&varinst,&varlen)==3) {
|
||||
if (varid<0x80||varid>0xff)
|
||||
exit(setReason("%s:%d var= line contains illegal variable ID. "
|
||||
"Multi-value variables must be in the range 80-ff (hexadecimal)",textfile,linenum));
|
||||
if (varinst<0||varinst>0xff)
|
||||
exit(setReason("%s:%d var= line contains illegal variable instance number. Must be in the range 00-ff (hexadecimal)",
|
||||
textfile,linenum));
|
||||
if (varlen<1||varlen>65534)
|
||||
exit(setReason("%s:%d var= line contains illegal length. Must be in the range 1-65534.",textfile,linenum));
|
||||
|
||||
/* Okay, we have a valid variable, lets switch to accumulating its value */
|
||||
dlen=0;
|
||||
state=2;
|
||||
}
|
||||
else if (sscanf((char *)line,"var=%02x len=%d",&varid,&varlen)==2) {
|
||||
if (varid>0x7f||varid<0)
|
||||
exit(setReason("%s:%d var= line contains illegal variable ID. "
|
||||
"Single-value variables must be in the range 00-7f (hexadecimal)",textfile,linenum));
|
||||
varinst=0;
|
||||
if (varlen<1||varlen>65534)
|
||||
exit(setReason("%s:%d var= line contains illegal length. Must be in the range 1-65534.",textfile,linenum));
|
||||
|
||||
/* Okay, we have a valid variable, lets switch to accumulating its value */
|
||||
dlen=0;
|
||||
state=2;
|
||||
} else {
|
||||
exit(setReason("%s:%d Syntax error in HLR record.",textfile,linenum));
|
||||
}
|
||||
break;
|
||||
case 2: /* Reading a variable value */
|
||||
/* Read line of data */
|
||||
for(j=0;j<l;)
|
||||
{
|
||||
if (dlen>=varlen)
|
||||
exit(setReason("%s:%d Variable value data exceeds stated length.\nThis is what was left after I had taken all I needed: `%s'.",textfile,linenum,&line[j]));
|
||||
switch(line[j])
|
||||
{
|
||||
case '\\':
|
||||
j++;
|
||||
switch(line[j])
|
||||
{
|
||||
case 'n': data[dlen++]='\n'; break;
|
||||
case 'r': data[dlen++]='\r'; break;
|
||||
case 'x': data[dlen++]=(hexvalue(line[j+1])<<4)+hexvalue(line[j+2]); j+=2; break;
|
||||
default:
|
||||
exit(setReason("%s:%d Illegal \\ sequence `\\%c' encountered in variable value. Only \\r, \\n and \\x are accepted.",textfile,linenum,line[j]));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
data[dlen++]=line[j];
|
||||
}
|
||||
j++;
|
||||
}
|
||||
|
||||
if (dlen==varlen) {
|
||||
state=1;
|
||||
if (hofs==-1) {
|
||||
if (varid!=VAR_DIDS||varinst!=0)
|
||||
{
|
||||
/* This variable instance is not the first DID, but we still need to create the HLR record.
|
||||
This is naughty. The first var= line after a sid= line MUST be var=80:00 to specify the first DID. */
|
||||
exit(setReason("%s:%d The first var= line after a sid= line MUST be var=80:00 to specify the first DID.",textfile,linenum));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Okay, this is the first DID, so now we can create the HLR record.
|
||||
But first, we need to unpack the DID into ascii */
|
||||
char did[SIDDIDFIELD_LEN+1];
|
||||
int zero=0;
|
||||
extractDid(data,&zero,did);
|
||||
printf("DID=%s\n",did);
|
||||
if (createHlr((char *)did,sid))
|
||||
exit(setReason("%s:%d createHlr() failed.",textfile,linenum));
|
||||
hofs=0;
|
||||
findHlr(hlr,&hofs,NULL,did);
|
||||
if (hofs<0)
|
||||
exit(setReason("%s:%d Could not find created HLR record.",textfile,linenum));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
line[0]=0; fgets((char *)line,1024,i);
|
||||
}
|
||||
|
||||
fclose(i);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int exportHlr(unsigned char *hlr_file,char *text)
|
||||
{
|
||||
FILE *o;
|
||||
int ofs=0,i;
|
||||
if (openHlrFile((char *)hlr_file,-1)) exit(setReason("Could not open HLR database"));
|
||||
|
||||
if (!strcmp("-",text)) o=stdout;
|
||||
else
|
||||
if ((o=fopen(text,"w"))==NULL) exit(setReason("Could not create export file"));
|
||||
|
||||
while(findHlr(hlr,&ofs,NULL,NULL))
|
||||
{
|
||||
int hofs=ofs;
|
||||
fprintf(o,"# HLR Record at 0x%08x\n",ofs);
|
||||
|
||||
/* Output SID for this record */
|
||||
fprintf(o,"sid=");
|
||||
for(i=0;i<32;i++) fprintf(o,"%02x",hlr[hofs+4+i]);
|
||||
fprintf(o,"\n");
|
||||
|
||||
struct hlrentry_handle *h=openhlrentry(hlr,hofs);
|
||||
|
||||
while(h)
|
||||
{
|
||||
int cols;
|
||||
if (h->var_id==0&&h->value_len==0) break;
|
||||
|
||||
fprintf(o,"var=%02x",h->var_id);
|
||||
if (h->var_id&0x80) fprintf(o,":%02x",h->var_instance);
|
||||
fprintf(o," len=%d",h->value_len);
|
||||
for(i=0;vars[i].name;i++) if (vars[i].id==h->var_id) { fprintf(o," name=%s",vars[i].name); break; }
|
||||
fprintf(o,"\n");
|
||||
|
||||
cols=0;
|
||||
for (i=0;i<h->value_len;i++)
|
||||
{
|
||||
if (h->value[i]>=' '&&h->value[i]<=0x7f&&h->value[i]!='\\'&&(cols||h->value[i]!='#'))
|
||||
{
|
||||
fprintf(o,"%c",h->value[i]);
|
||||
cols++;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(h->value[i]) {
|
||||
case '\r': fprintf(o,"\\r"); cols+=2; break;
|
||||
case '\n': fprintf(o,"\\n"); cols+=2; break;
|
||||
default:
|
||||
fprintf(o,"\\x%02x",(unsigned char)h->value[i]); cols+=4;
|
||||
}
|
||||
if (cols>75) { fprintf(o,"\n"); cols=0; }
|
||||
}
|
||||
}
|
||||
if (cols) { fprintf(o,"\n"); cols=0; }
|
||||
|
||||
h=hlrentrygetent(h);
|
||||
}
|
||||
|
||||
/* Mark the end of the record
|
||||
(as much to make life easier for the import parser as anything) */
|
||||
fprintf(o,"eor\n");
|
||||
|
||||
/* Advance to next record and keep searching */
|
||||
if (nextHlr(hlr,&ofs)) break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
56
hlrdata.c
56
hlrdata.c
@ -439,3 +439,59 @@ int hlrDump(unsigned char *hlr,int hofs)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int openHlrFile(char *backing_file,int size)
|
||||
{
|
||||
/* Get backing store */
|
||||
if (!backing_file)
|
||||
{
|
||||
if (size<0) exit(setReason("You must provide an HLR file or size"));
|
||||
|
||||
/* transitory storage of HLR data, so just malloc() the memory */
|
||||
hlr=calloc(size,1);
|
||||
if (!hlr) exit(setReason("Failed to calloc() HLR database."));
|
||||
if (debug) fprintf(stderr,"Allocated %d byte temporary HLR store\n",size);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned char zero[8192];
|
||||
FILE *f=fopen(backing_file,"r+");
|
||||
if (!f) f=fopen(backing_file,"w+");
|
||||
if (!f) exit(setReason("Could not open backing file."));
|
||||
bzero(&zero[0],8192);
|
||||
fseek(f,0,SEEK_END);
|
||||
errno=0;
|
||||
|
||||
/* Obtain size from existing backing file */
|
||||
if (size<0) size=ftell(f);
|
||||
|
||||
while(ftell(f)<size)
|
||||
{
|
||||
int r;
|
||||
fseek(f,0,SEEK_END);
|
||||
if ((r=fwrite(zero,8192,1,f))!=1)
|
||||
{
|
||||
perror("fwrite");
|
||||
exit(setReason("Could not enlarge backing file to requested size (short write)"));
|
||||
}
|
||||
fseek(f,0,SEEK_END);
|
||||
}
|
||||
|
||||
if (errno) perror("fseek");
|
||||
if (fwrite("",1,1,f)!=1)
|
||||
{
|
||||
fprintf(stderr,"Failed to set backing file size.\n");
|
||||
perror("fwrite");
|
||||
}
|
||||
hlr=(unsigned char *)mmap(NULL,size,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_NORESERVE,fileno(f),0);
|
||||
if (hlr==MAP_FAILED) {
|
||||
perror("mmap");
|
||||
exit(setReason("Memory mapping of HLR backing file failed."));
|
||||
}
|
||||
if (debug) fprintf(stderr,"Allocated %d byte HLR store backed by file `%s'\n",
|
||||
size,backing_file);
|
||||
}
|
||||
hlr_size=size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
7
mphlr.h
7
mphlr.h
@ -107,6 +107,8 @@ double simulatedBER;
|
||||
|
||||
extern int serverMode;
|
||||
|
||||
extern char *gatewayuri;
|
||||
|
||||
extern struct sockaddr recvaddr;
|
||||
extern struct in_addr client_addr;
|
||||
extern int client_port;
|
||||
@ -275,7 +277,7 @@ int requestItem(char *did,char *sid,char *item,int instance,unsigned char *buffe
|
||||
int requestNewHLR(char *did,char *pin,char *sid);
|
||||
int server(char *backing_file,int size,int foregroundMode);
|
||||
|
||||
int setReason(char *msg);
|
||||
int setReason(char *fmt, ...);
|
||||
int hexvalue(unsigned char c);
|
||||
int dump(char *name,unsigned char *addr,int len);
|
||||
int packetOk(unsigned char *packet,int len,unsigned char *transaction_id);
|
||||
@ -339,3 +341,6 @@ int getBatmanPeerList(char *socket_path,struct in_addr peers[],int *peer_count,i
|
||||
int hlrDump(unsigned char *hlr,int hofs);
|
||||
int peerAddress(char *did,char *sid,int flags);
|
||||
int fixResponses(struct response_set *responses);
|
||||
int importHlr(char *textfile);
|
||||
int exportHlr(unsigned char *hlr,char *text);
|
||||
int openHlrFile(char *backing_file,int size);
|
||||
|
Loading…
Reference in New Issue
Block a user