Reimported features from Raiders Of The Lost Source (gateway, hlr import/export)

This commit is contained in:
gardners 2011-05-06 11:57:33 +09:30
parent f024213414
commit bba5ec6bd8
6 changed files with 355 additions and 6 deletions

View File

@ -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

View File

@ -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
View File

@ -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
View 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;
}

View File

@ -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;
}

View File

@ -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);