Example #1
0
int hlrGetVariable(unsigned char *hlr,int hofs,int varid,int varinstance,
		   unsigned char *value,int *len)
{  
  struct hlrentry_handle *h;
  int hlr_offset=-1;

  h=openhlrentry(hlr,hofs);

  /* Find the place in the HLR record where this variable is */
  while(h)
    {     
      if ((h->var_id<varid)
	  ||(h->var_id==varid&&h->var_instance<varinstance))
	hlr_offset=h->entry_offset;
      else
	{
	  /* Value is here if anywhere */
	  if (h->var_id>varid||h->var_instance>varinstance)
	    return setReason("No such variable instance");
	  if (h->value_len>*len) return setReason("Value too long for buffer");
	  bcopy(h->value,value,h->value_len);
	  *len=h->value_len;
	  return 0;
	  break;
	}
      h=hlrentrygetent(h);
    }

  return setReason("No such variable instance");
}
Example #2
0
int extractRequest(unsigned char *packet,int *packet_ofs,int packet_len,
		   int *itemId,int *instance,unsigned char *value,
		   int *start_offset,int *bytes,int *flags)
{
  if (*packet_ofs<0||(*packet_ofs)+6>=packet_len) 
    return setReason("mal-formed request packet (packet too short/bad offset)");

  *itemId=packet[(*packet_ofs)++];

  if ((*itemId)&0x80) *instance=packet[(*packet_ofs)++];
  if (*instance==0xff) *instance=-1;

  *start_offset=packet[(*packet_ofs)++]<<8;
  *start_offset|=packet[(*packet_ofs)++];

  *bytes=packet[(*packet_ofs)++]<<8;
  *bytes|=packet[(*packet_ofs)++];

  *flags=packet[(*packet_ofs)++];
  if (debug>2) printf("Write flags = 0x%02x\n",*flags);

  if (*packet_ofs<0||(*packet_ofs)+(*bytes)>=packet_len)
    {
      if (debug) fprintf(stderr,"Packet offset is %d, length is %d, and asked for %d bytes.\n",*packet_ofs,packet_len,*bytes);
      return setReason("mal-formed request packet (too short for claimed data)");
    }

  bcopy(&packet[*packet_ofs],value,*bytes);
  (*packet_ofs)+=*bytes;

  return 0;
}
Example #3
0
int unpackageVariableSegment(unsigned char *data,int dlen,int flags,struct response *r)
{
  r->response_len=0;
  if (dlen<7) return setReason("unpackageVariableSegment() fed insufficient data");
  
  r->var_id=data[r->response_len++];
  if (r->var_id&0x80) r->var_instance=data[r->response_len++]; else r->var_instance=0;
  if (r->var_instance==0xff) r->var_instance=-1;

  r->value_len=data[r->response_len++]<<8;
  r->value_len|=data[r->response_len++];

  r->value_offset=data[r->response_len++]<<8;
  r->value_offset|=data[r->response_len++];

  r->value_bytes=data[r->response_len++]<<8;
  r->value_bytes|=data[r->response_len++];

  r->response=&data[r->response_len];

  r->response_len+=r->value_bytes;

  if (flags!=WITHOUTDATA)
    if (r->response_len>dlen) 
      return setReason("unpackageVariableSegment() fed insufficient or corrupt data");
  
  return 0;
}
Example #4
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;
}
Example #5
0
int createHlr(char *did,char *sid) {
  int i;
  int record_offset=0;

  /* Generate random SID */
  for(i=0;i<64;i++) sid[i]=hexdigit[random()&0xf]; sid[64]=0;
  if (debug>1) fprintf(stderr,"Creating new HLR entry with sid %s\n",sid);
  
  /* Find first free byte of HLR */
  findHlr(hlr,&record_offset,NULL,NULL);

  if (record_offset>=hlr_size)
    {
      /* No space */
      return setReason("No space in HLR for a new record");
    }
  else
    {
      /* We have found space, but is it enough? */
      int bytes=hlr_size-record_offset;
      if (bytes<1024) return setReason("<1KB space in HLR");
      
      /* Write shiny fresh new record.
	 32bit - record length 
	 32 bytes - SID
	 Total length = 4+32=36 bytes.
      */
      if (stowSid(hlr,record_offset+4,sid)) return setReason("Could not store SID in new HLR entry");
	
      /* Write length last of all to make entry valid */
      hlr[record_offset]=0;
      hlr[record_offset+1]=0;
      hlr[record_offset+2]=0;
      hlr[record_offset+3]=36;

      /* Store the DID */
      {
	unsigned char packeddid[DID_MAXSIZE];
	int pdidlen=0;
	stowDid(packeddid,&pdidlen,did);
	/* Work out reduced length of DID */
	for(pdidlen=1;pdidlen<DID_MAXSIZE;pdidlen++) if (packeddid[pdidlen-1]==0xff) break;
	hlrSetVariable(hlr,record_offset,VAR_DIDS,0x00,packeddid,pdidlen);
      }

      if (debug) fprintf(stderr,"Created new 36 byte HLR record for DID=[%s] @ 0x%x with SID=[%s]\n",
			 did,record_offset,sid);
      if (debug>2) dump("after HLR create",&hlr[0],256);
      return 0;
    }

  return setReason("Unreachable code turned out not to be");
}
Example #6
0
void HTTPResponse::read(std::istream& istr)
{
	static const int eof = std::char_traits<char>::eof();

	std::string version;
	std::string status;
	std::string reason;
	
	int ch =  istr.get();
	if (ch == eof) throw NoMessageException();
	while (Poco::Ascii::isSpace(ch)) ch = istr.get();
	if (ch == eof) throw MessageException("No HTTP response header");
	while (!Poco::Ascii::isSpace(ch) && ch != eof && version.length() < MAX_VERSION_LENGTH) { version += (char) ch; ch = istr.get(); }
	if (!Poco::Ascii::isSpace(ch)) throw MessageException("Invalid HTTP version string");
	while (Poco::Ascii::isSpace(ch)) ch = istr.get();
	while (!Poco::Ascii::isSpace(ch) && ch != eof && status.length() < MAX_STATUS_LENGTH) { status += (char) ch; ch = istr.get(); }
	if (!Poco::Ascii::isSpace(ch)) throw MessageException("Invalid HTTP status code");
	while (Poco::Ascii::isSpace(ch) && ch != '\r' && ch != '\n' && ch != eof) ch = istr.get();
	while (ch != '\r' && ch != '\n' && ch != eof && reason.length() < MAX_REASON_LENGTH) { reason += (char) ch; ch = istr.get(); }
	if (!Poco::Ascii::isSpace(ch)) throw MessageException("HTTP reason string too long");
	if (ch == '\r') ch = istr.get();

	HTTPMessage::read(istr);
	ch = istr.get();
	while (ch != '\n' && ch != eof) { ch = istr.get(); }
	setVersion(version);
	setStatus(status);
	setReason(reason);
}
VideoTimingEvent::VideoTimingEvent(EventSource *source) :
    VideoEvent(source),
    mVTime(0.0f),
    mATime(0.0f),
    mFrameNumber(0),
    mFramesDropped(0)
{
    setReason(VIDEOTIMEEVENT);
}
Example #8
0
int respondSimple(char *sid,int action,unsigned char *action_text,int action_len,
		  unsigned char *transaction_id)
{
  unsigned char packet[8000];
  int pl=0;
  int *packet_len=&pl;
  int packet_maxlen=8000;
  int i;

  /* ACTION_ERROR is associated with an error message.
     For syntactic simplicity, we do not require the respondSimple() call to provide
     the length of the error message. */
  if (action==ACTION_ERROR) {
    action_len=strlen((char *)action_text);
    /* Make sure the error text isn't too long.
       IF it is, trim it, as we still need to communicate the error */
    if (action_len>255) action_len=255;
  }

  /* Prepare the request packet */
  if (packetMakeHeader(packet,8000,packet_len,transaction_id)) return -1;
  if (sid&&sid[0]) 
    { if (packetSetSid(packet,8000,packet_len,sid)) 
	return setReason("invalid SID in reply"); }
  else 
    { if (packetSetDid(packet,8000,packet_len,"")) 
	return setReason("Could not set empty DID in reply"); }  

  CHECK_PACKET_LEN(1+1+action_len);
  packet[(*packet_len)++]=action;
  if (action==ACTION_ERROR) packet[(*packet_len)++]=action_len;
  for(i=0;i<action_len;i++) packet[(*packet_len)++]=action_text[i];

  if (debug>2) dump("Simple response octets",action_text,action_len);

  if (packetFinalise(packet,8000,packet_len)) return -1;

  if (debug) fprintf(stderr,"Sending response of %d bytes.\n",*packet_len);

  if (packetSendRequest(REQ_REPLY,packet,*packet_len,NONBATCH,transaction_id,NULL)) return -1;
  
  return 0;
}
Example #9
0
int packetAddVariableWrite(unsigned char *packet,int packet_maxlen,
			   int *packet_len,
			   int itemId,int instance,unsigned char *value,
			   int start_offset,int value_len,int flags)
{
  /* Work out which item type we are asking for */
  int packet_len_in=*packet_len;

  int max_offset=start_offset+value_len-1;

  if (debug>1) printf("packetAddVariableWrite(start=%d,len=%d,flags=%d)\n",start_offset,value_len,flags);

  /* Sanity check */
  if (instance<0) return setReason("Asked for illegal variable value instance");
  if (instance>0xfe) return setReason("Asked for illegal variable value instance");
  if ((itemId<0x80)&&instance) return setReason("Asked for secondary value of single-value variable");
  if (start_offset<0||start_offset>0xffff) return setReason("Asked for illegal variable value starting offset");
  if (max_offset<0||max_offset>0xffff) return setReason("Asked for illegal variable value ending offset");
  
  /* Add request to the packet */
  CHECK_PACKET_LEN(1+1+((itemId&0x80)?1:0)+2+2+1);
  packet[(*packet_len)++]=ACTION_SET;
  packet[(*packet_len)++]=itemId;
  if (itemId&0x80) packet[(*packet_len)++]=instance;
  packet[(*packet_len)++]=start_offset>>8;
  packet[(*packet_len)++]=start_offset&0xff;
  packet[(*packet_len)++]=value_len>>8;
  packet[(*packet_len)++]=value_len&0xff;
  packet[(*packet_len)++]=flags;
  
  if (debug>2) dump("Packet with var write header",&packet[0],*packet_len);

  CHECK_PACKET_LEN(value_len);
  bcopy(&value[0],&packet[*packet_len],value_len);
  (*packet_len)+=value_len;

  if (debug>2) dump("Variable request octets (write)",&packet[packet_len_in],(*packet_len)-packet_len_in);

  return 0;
}
Example #10
0
int packetSetSid(unsigned char *packet,int packet_maxlen,int *packet_len,char *sid)
{
  /* Convert and store hex formatted sid */
  int ofs=OFS_SIDDIDFIELD; /* where the DID/subscriber ID gets written */

  if (strlen(sid)!=64) {
    if (debug) fprintf(stderr,"Invalid SID: [%s] - should be 64 hex digits\n",sid);
    return setReason("SID must consist of 64 hex digits");
  }

  packet[ofs++]=0x01; /* SID */
  return stowSid(packet,ofs,sid);
}
Example #11
0
int process_packet(unsigned char *packet,int len,struct sockaddr *sender,int sender_len)
{
  int authenticatedP=0;
  char did[128];
  char sid[128];
  unsigned char *transaction_id=&packet[OFS_TRANSIDFIELD];
  
  did[0]=0; sid[0]=0;
  
  /* Get DID or SID */
  if (packetGetID(packet,len,did,sid)) return setReason("Could not parse DID or SID");
  
  /* Check for PIN */
  if (!isFieldZeroP(packet,OFS_PINFIELD,16))
    {
      /* Authentication has been attempted.
	 If it is incorrect, then we need to return with ACTION_DECLINED
      */
      if (debug>1) fprintf(stderr,"A PIN has been supplied.\n");
      
      /* Can only authenticate by SID, not DID (since DIDs are ambiguous) */
      if (packet[OFS_SIDDIDFIELD]!=1) return setReason("You can only authenticate against a SID");
   
      /* XXX check authentication */
      return setReason("Authentication not yet supported");
    }
  else 
    {
      /* No attempt at authentication was made */
      authenticatedP=0;
      if (debug>1) fprintf(stderr,"No PIN was supplied.\n");
    }

  if (serverMode) return processRequest(packet,len,sender,sender_len,transaction_id,did,sid);
   
  return 0;
}
Example #12
0
/* Create a new HLR entry on a peer.
   Should always try localhost as first peer, which is why
   sendToPeers() does it that way.  We just have to remember to
   ask for serialised attempts, rather than all at once.
*/
int requestNewHLR(char *did,char *pin,char *sid)
{
  unsigned char packet[8000];
  int packet_len=0;
  struct response_set responses;
  unsigned char transaction_id[8];

  bzero(&responses,sizeof(responses));

  /* Prepare the request packet */
  if (packetMakeHeader(packet,8000,&packet_len,NULL)) return -1;
  bcopy(&packet[8],transaction_id,8);
  if (packetSetDid(packet,8000,&packet_len,did)) return -1;
  if (packetAddHLRCreateRequest(packet,8000,&packet_len)) return -1;
  if (packetFinalise(packet,8000,&packet_len)) return -1;

  /* Send it to peers, starting with ourselves, one at a time until one succeeds.
     XXX - This could take a while if we have long timeouts for each. */
  if (packetSendRequest(REQ_SERIAL,packet,packet_len,NONBATCH,transaction_id,&responses)) return -1;

  /* Extract response */
  if (debug>2) dumpResponses(&responses);
  if (!responses.response_count) {
    printf("NOREPLY\n");
    return -1;
  }
  switch(responses.responses->code)
    {
    case ACTION_DECLINED:
      printf("DECLINED\n");
      return -1;
      break;
    case ACTION_OKAY:
      {
	char sid[128];
	int ofs=0;
	extractSid(&responses.responses->sid[0],&ofs,&sid[0]);
	printf("OK:%s\n",sid);
      }
      return 0;
      break;
    default:
      printf("ERROR:Unknown response 0x%02x\n",responses.responses->code);
      return -1;
    }
 
  return setReason("Request creation of new HLR not implemented");
}
Example #13
0
int nextHlr(unsigned char *hlr,int *ofs)
{
  int record_length;

  if (!ofs) return setReason("nextHlr passed NULL pointer.");
  if (*ofs>=hlr_size) return -1;

  /* Get length of this record */
  record_length =hlr[(*ofs)+3]<<0;
  record_length|=hlr[(*ofs)+2]<<8;
  record_length|=hlr[(*ofs)+1]<<16;
  record_length|=hlr[(*ofs)+0]<<24;

  if (!record_length) return -1;

  (*ofs)+=record_length;
  return 0;
}
Example #14
0
int packetOk(unsigned char *packet,int len,unsigned char *transaction_id)
{
  /* Make sure that the packet is meant for us, and is not mal-formed */
  int version;
  int cipher;
  int length;
  int payloadRotation;

  if (len<HEADERFIELDS_LEN) return setReason("Packet is too short");
  if (packet[0]!=0x41||packet[1]!=0x10) return setReason("Packet has incorrect magic value");

  version=(packet[2]<<8)|packet[3];
  length=(packet[4]<<8)|packet[5];
  cipher=(packet[6]<<8)|packet[7];
  if (version!=1) return setReason("Unknown packet format version");
  if (cipher!=0) return setReason("Unknown packet cipher");
  if (length!=len) return setReason("Packet length incorrect");

  if (cipher) 
	  if (packetDecipher(packet,len,cipher)) 
		  return setReason("Could not decipher packet");

  /* Make sure the transaction ID matches */
  if (transaction_id)
    {
      int i;
	  for(i=0;i<TRANSID_SIZE;i++)
		if (packet[OFS_TRANSIDFIELD+i]!=transaction_id[i])
		  return setReason("transaction ID mismatch");
    }
  
  /* Unrotate the payload */
  payloadRotation=packet[OFS_ROTATIONFIELD];
  {
    unsigned char temp[256];
    bcopy(&packet[len-payloadRotation],&temp[0],payloadRotation);
    bcopy(&packet[HEADERFIELDS_LEN],&packet[HEADERFIELDS_LEN+payloadRotation],
	  len-(HEADERFIELDS_LEN)-payloadRotation);
    bcopy(&temp[0],&packet[HEADERFIELDS_LEN],payloadRotation);
  }

  if (debug>1) fprintf(stderr,"Packet passes sanity checks and is ready for decoding.\n");
  if (debug>2) dump("unrotated packet",packet,len);

  return 0;
}
Example #15
0
int packageVariableSegment(unsigned char *data,int *dlen,struct hlrentry_handle *h,
			   int offset,int buffer_size)
{
  int bytes;
  int dlen_in=*dlen;

  if ((buffer_size-(*dlen))<8) return setReason("Insufficient buffer space for packageVariableSegment()");

  /* Figure out how many bytes we need to package */
  bytes=buffer_size-(*dlen)-8;
  if ((h->value_len-offset)<bytes) bytes=h->value_len-offset;
  if (bytes<0) bytes=0;
  if (debug>1) fprintf(stderr,"Packaging %d bytes of variable\n",bytes);

  /* Describe variable */

  /* Variable id and instance # (if required) */
  data[(*dlen)++]=h->var_id;
  if (h->var_id&0x80) data[(*dlen)++]=h->var_instance;

  /* Variable length */
  data[(*dlen)++]=h->value_len>>8;
  data[(*dlen)++]=h->value_len&0xff;

  /* Start offset in this segment */
  data[(*dlen)++]=(offset>>8)&0xff;
  data[(*dlen)++]=offset&0xff;

  /* Number of bytes in this segment */
  data[(*dlen)++]=(bytes>>8)&0xff;
  data[(*dlen)++]=bytes&0xff;
  if (debug>1) fprintf(stderr,"Packaging %d bytes\n",bytes);

  /* Package the variable value itself (or part thereof) */
  bcopy(&h->value[offset],&data[*dlen],bytes);
  (*dlen)+=bytes;

  if (debug>2) dump("Variable segment octets",&data[dlen_in],(*dlen)-dlen_in);

  return 0;
}
Example #16
0
int packetAddVariableRequest(unsigned char *packet,int packet_maxlen,int *packet_len,
			     char *item,int instance,int start_offset,int bytes)
{
  /* Work out which item type we are asking for */
  int itemId;
  int packet_len_in=*packet_len;
  for(itemId=0;vars[itemId].name;itemId++)
    if (!strcmp(item,vars[itemId].name)) {
      break;
    }

  /* Sanity check the request */
  if (!vars[itemId].name) {
    if (debug) fprintf(stderr,"`%s' is not a known HLR variable.\n",item);
    return setReason("Requested unknown HLR variable");
  }
  itemId=vars[itemId].id;
  if (instance<-1) return setReason("Asked for illegal variable value instance");
  if (instance>0xfe) return setReason("Asked for illegal variable value instance");
  if ((itemId<0x80)&&instance) return setReason("Asked for secondary value of single-value variable");
  if (start_offset<0||start_offset>0xffff) return setReason("Asked for illegal variable value starting offset");
  if (bytes<0||(start_offset+bytes)>0xffff) {
    if (debug) fprintf(stderr,"Asked for %d bytes at offset %d\n",bytes,start_offset);
    return setReason("Asked for illegal variable value ending offset");
  }
  
  /* Add request to the packet */
  CHECK_PACKET_LEN(1+1+((itemId&0x80)?1:0)+2+2);
  packet[(*packet_len)++]=ACTION_GET;
  packet[(*packet_len)++]=itemId;
  if (instance==-1) instance=0xff;
  if (itemId&0x80) packet[(*packet_len)++]=instance;
  packet[(*packet_len)++]=start_offset>>8;
  packet[(*packet_len)++]=start_offset&0xff;
  packet[(*packet_len)++]=bytes>>8;
  packet[(*packet_len)++]=bytes&0xff;
  
  if (debug>2) dump("Variable request octets (var)",&packet[packet_len_in],(*packet_len)-packet_len_in);

  return 0;
}
Example #17
0
int processRequest(unsigned char *packet,int len,
		   struct sockaddr *sender,int sender_len,
		   unsigned char *transaction_id,char *did,char *sid)
{
  /* Find HLR entry by DID or SID, unless creating */
  int ofs,rofs=0;
  int records_searched=0;
  
  int prev_pofs=0;
  int pofs=OFS_PAYLOAD;

  while(pofs<len)
    {
      if (debug>1) fprintf(stderr,"  processRequest: len=%d, pofs=%d, pofs_prev=%d\n",len,pofs,prev_pofs);
      /* Avoid infinite loops */
      if (pofs<=prev_pofs) break;
      prev_pofs=pofs;

      if (packet[pofs]==ACTION_CREATEHLR)
	{
	  /* Creating an HLR requires an initial DID number and definately no SID -
	     you can't choose a SID. */
	  if (debug>1) fprintf(stderr,"Creating a new HLR record. did='%s', sid='%s'\n",did,sid);
	  if (!did[0]) return respondSimple(NULL,ACTION_DECLINED,NULL,0,transaction_id);
	  if (sid[0])  return respondSimple(sid,ACTION_DECLINED,NULL,0,transaction_id);
	  if (debug>1) fprintf(stderr,"Verified that create request supplies DID but not SID\n");
	  
	  {
	    char sid[128];
	    /* make HLR with new random SID and initial DID */
	    if (!createHlr(did,sid))
	      return respondSimple(sid,ACTION_OKAY,NULL,0,transaction_id);
	    else
	      return respondSimple(NULL,ACTION_DECLINED,NULL,0,transaction_id);
	  }
	  pofs+=1;
	  pofs+=1+SID_SIZE;
	}
      else
	{
	  switch(packet[pofs])
	    {
	    case ACTION_PAD: /* Skip padding */
	      pofs++;
	      pofs+=1+packet[pofs];
	      break;
	    case ACTION_EOT:  /* EOT */
	      pofs=len;
	      break;
	    case ACTION_STATS:
	      /* short16 variable id,
		 int32 value */
	      {
		pofs++;
		short field=packet[pofs+1]+(packet[pofs]<<8);
		int value=packet[pofs+5]+(packet[pofs+4]<<8)+(packet[pofs+3]<<16)+(packet[pofs+2]<<24);
		pofs+=6;
		if (instrumentation_file)
		  {
		    if (!i_f) { if (strcmp(instrumentation_file,"-")) i_f=fopen(instrumentation_file,"a"); else i_f=stdout; }
		    if (i_f) fprintf(i_f,"%ld:%08x:%d:%d\n",time(0),*(unsigned int *)&sender->sa_data[0],field,value);
		    if (i_f) fflush(i_f);
		  }
	      }
	      break;
	    case ACTION_DIGITALTELEGRAM:
	      // Unpack SMS message.
	      {
		char emitterPhoneNumber[256];
		char message[256];
		pofs++;
		char messageType = packet[pofs];
		pofs++;
		char emitterPhoneNumberLen = packet[pofs];
		pofs++;
		char messageLen = packet[pofs];
		pofs++;
		strncpy(emitterPhoneNumber, (const char*)packet+pofs, emitterPhoneNumberLen);
		pofs+=emitterPhoneNumberLen;
		strncpy(message, (const char*)packet+pofs, messageLen); 
		pofs+=messageLen;
	      
		// Check if I'm the recipient

		// Send SMS to android
		char amCommand[576]; // 64 char + 2*256(max) char = 576
		sprintf(amCommand, "am broadcast -a org.servalproject.DT -e number \"%s\"  -e content \"%s\"", emitterPhoneNumber, message);
		int exitcode = printf(amCommand);
		//int exitcode = system(amCommand); 
	      }
	      break;
	    case ACTION_SET:
	      ofs=0;
	      if (debug>1) fprintf(stderr,"Looking for hlr entries with sid='%s' / did='%s'\n",sid,did);

	      if ((!sid)||(!sid[0])) {
		setReason("You can only set variables by SID");
		return respondSimple(NULL,ACTION_ERROR,(unsigned char *)"SET requires authentication by SID",0,transaction_id);
	      }

	      while(findHlr(hlr,&ofs,sid,did))
		{
		  int itemId,instance,start_offset,bytes,flags;
		  unsigned char value[9000],oldvalue[65536];
		  int oldr,oldl;
		  
		  if (debug>1) fprintf(stderr,"findHlr found a match for writing at 0x%x\n",ofs);
		  if (debug>2) hlrDump(hlr,ofs);
		  
		  /* XXX consider taking action on this HLR
		     (check PIN first depending on the action requested) */
	      
		  /* XXX Doesn't verify PIN authentication */
		  
		  /* Get write request */
		    
		  pofs++; rofs=pofs;
		  if (extractRequest(packet,&pofs,len,
				     &itemId,&instance,value,
				     &start_offset,&bytes,&flags))
		    {
		      setReason("Could not extract ACTION_SET request");
		      return 
			respondSimple(NULL,ACTION_ERROR,(unsigned char *)"Mal-formed SET request",0,transaction_id);
		    }
		  
		  /* Get the stored value */
		  oldl=65536;
		  oldr=hlrGetVariable(hlr,ofs,itemId,instance,oldvalue,&oldl);
		  if (oldr) {
		    if (flags==SET_NOREPLACE) {
		      oldl=0;
		    } else {
		      setReason("Tried to SET_NOCREATE/SET_REPLACE a non-existing value");
		      return 
			  respondSimple(NULL,ACTION_ERROR,
					(unsigned char *)"Cannot SET NOCREATE/REPLACE a value that does not exist",
					0,transaction_id);
		    }
		  } else {
		    if (flags==SET_NOREPLACE) {
		      setReason("Tried to SET_NOREPLACE an existing value");
		      if (debug>1) dump("Existing value",oldvalue,oldl);
		      return 
			respondSimple(NULL,ACTION_ERROR,
				      (unsigned char *)"Cannot SET NOREPLACE; a value exists",
				      0,transaction_id);
		      }
		  }
		  /* Replace the changed portion of the stored value */
		  if ((start_offset+bytes)>oldl) {
		    bzero(&oldvalue[oldl],start_offset+bytes-oldl);
		    oldl=start_offset+bytes;
		  }
		  bcopy(&value[0],&oldvalue[start_offset],bytes);
		    
		  /* Write new value back */
		  if (hlrSetVariable(hlr,ofs,itemId,instance,oldvalue,oldl))
		    {
		      setReason("Failed to write variable");
		      return 
			respondSimple(NULL,ACTION_ERROR,(unsigned char *)"Failed to SET variable",0,transaction_id);
		    }
		  if (debug>2) { fprintf(stderr,"HLR after writing:\n"); hlrDump(hlr,ofs); }
		  
		  /* Reply that we wrote the fragment */
		  respondSimple(sid,ACTION_WROTE,&packet[rofs],6,
				transaction_id);
		  /* Advance to next record and keep searching */
		  if (nextHlr(hlr,&ofs)) break;
		}
	      break;
	    case ACTION_GET:
	      {
		/* Limit transfer size to MAX_DATA_BYTES, plus an allowance for variable packing. */
		unsigned char data[MAX_DATA_BYTES+16];
		int dlen=0;
		int sendDone=0;
		int var_id=packet[pofs+1];
		int instance=packet[pofs+2];
		int offset=(packet[pofs+3]<<8)+packet[pofs+4];
		char *hlr_sid=NULL;

		pofs+=7;
		if (debug>2) dump("Request bytes",&packet[pofs],8);
		if (debug>1) fprintf(stderr,"Processing ACTION_GET (var_id=%02x, instance=%02x, pofs=0x%x, len=%d)\n",var_id,instance,pofs,len);

		ofs=0;
		if (debug>1) fprintf(stderr,"Looking for hlr entries with sid='%s' / did='%s'\n",sid?sid:"null",did?did:"null");

		while(1)
		  {
		    struct hlrentry_handle *h;

		    // if an empty did was passed in, get results from all hlr records
		    if (*sid || *did){
 		      if (!findHlr(hlr,&ofs,sid,did)) break;
		      if (debug>1) fprintf(stderr,"findHlr found a match @ 0x%x\n",ofs);
		    }
		    if (debug>2) hlrDump(hlr,ofs);
  		  
		    /* XXX consider taking action on this HLR
		       (check PIN first depending on the action requested) */

		    /* Form a reply packet containing the requested data */
  		  
		    if (instance==0xff) instance=-1;
  		  
		    /* Step through HLR to find any matching instances of the requested variable */
		    h=openhlrentry(hlr,ofs);
		    if (debug>1) fprintf(stderr,"openhlrentry(hlr,%d) returned %p\n",ofs,h);
		    while(h)
		      {
			/* Is this the variable? */
			if (debug>2) fprintf(stderr,"  considering var_id=%02x, instance=%02x\n",
					     h->var_id,h->var_instance);
			if (h->var_id==var_id)
			  {
			    if (h->var_instance==instance||instance==-1)
			      {
				if (debug>1) fprintf(stderr,"Sending matching variable value instance (instance #%d), value offset %d.\n",
						     h->var_instance,offset);
  			      
				// only send each value when the *next* record is found, that way we can easily stamp the last response with DONE
				if (sendDone>0)
				  respondSimple(hlr_sid,ACTION_DATA,data,dlen,transaction_id);

				dlen=0;
	    
				if (packageVariableSegment(data,&dlen,h,offset,MAX_DATA_BYTES+16))
				  return setReason("packageVariableSegment() failed.");
				hlr_sid=hlrSid(hlr,ofs);

				sendDone++;
			      }
			    else
			      if (debug>2) fprintf(stderr,"Ignoring variable instance %d (not %d)\n",
						   h->var_instance,instance);
			  }
			else
			  if (debug>2) fprintf(stderr,"Ignoring variable ID %d (not %d)\n",
					       h->var_id,var_id);
			h=hlrentrygetent(h);
		      }
  		  
		    /* Advance to next record and keep searching */
		    if (nextHlr(hlr,&ofs)) break;
		  }
		  if (sendDone)
		    {
		      data[dlen++]=ACTION_DONE;
		      data[dlen++]=sendDone&0xff;
		      respondSimple(hlr_sid,ACTION_DATA,data,dlen,transaction_id);
		    }
		  if (gatewayuri&&(var_id==VAR_LOCATIONS)&&did&&strlen(did))
		    {
		      /* We are a gateway, so offer connection via the gateway as well */
		      unsigned char data[MAX_DATA_BYTES+16];
		      int dlen=0;
		      struct hlrentry_handle fake;
		      unsigned char uri[1024];
		      
		      /* Turn gateway into full URI including extension */
		      snprintf((char *)uri,1024,"4101*%s@%s",did,gatewayuri);
		      
		      fake.value_len=strlen((char *)uri);
		      fake.var_id=var_id;
		      fake.value=uri;
		      
		      if (packageVariableSegment(data,&dlen,&fake,offset,MAX_DATA_BYTES+16))
			return setReason("packageVariableSegment() of gateway URI failed.");
		      
		      respondSimple(hlrSid(hlr,0),ACTION_DATA,data,dlen,transaction_id);
		    }
	      
	      }
	      break;
	    default:
	      setReason("Asked to perform unsupported action");
	      if (debug) fprintf(stderr,"Packet offset = 0x%x\n",pofs);
	      if (debug) dump("Packet",packet,len);
	      return -1;
	    }	   
	}
    }
  
  if (debug>1) fprintf(stderr,"Searched %d HLR entries.\n",records_searched);

  return 0;
}
Example #18
0
int writeItem(char *sid,int var_id,int instance,unsigned char *value,
	      int value_start,int value_length,int flags)
{
  unsigned char packet[8000];
  int packet_len=0;
  struct response_set responses;
  struct response *r;
  unsigned char transaction_id[8];

  bzero(&responses,sizeof(responses));

  if (debug>1) fprintf(stderr,"Writing %d bytes of var %02x/%02x @ 0x%d flags=%d\n",
		       value_length,var_id,instance,value_start,flags);

  if (!sid) {
    printf("ERROR:Must use SID when writing values.\n");
    return -1;
  }

  /* Split long writes into many short writes.
     (since each write is acknowledged, we don't have to worry about batch mode) */
  if (value_length-value_start>MAX_DATA_BYTES)
    { 
      int o;      
      if (debug) fprintf(stderr,"Writing large value (%d bytes)\n",value_length-value_start);
      for(o=value_start;o<value_length;o+=MAX_DATA_BYTES)
	{
	  int bytes=MAX_DATA_BYTES;
	  if (o+bytes>value_length) bytes=value_length-o;
	  if (debug>1) fprintf(stderr,"  writing [%d,%d)\n",o,o+bytes-1);
	  if (writeItem(sid,var_id,instance,&value[o-value_start],o,bytes,
			flags|((o>value_start)?SET_FRAGMENT:0)))
	    {
	      if (debug) fprintf(stderr,"   - writing installment failed\n");
	      return setReason("Failure during multi-packet write of long-value");
	    }
	}
      printf("OK:%s\n",sid);
      return 0;
    }

  /* Prepare the request packet */
  if (packetMakeHeader(packet,8000,&packet_len,NULL)) return -1;
  bcopy(&packet[8],transaction_id,8);
  if (packetSetSid(packet,8000,&packet_len,sid)) return -1;
  if (packetAddVariableWrite(packet,8000,&packet_len,var_id,instance,
			     value,value_start,value_length,flags)) return -1;
  if (packetFinalise(packet,8000,&packet_len)) return -1;

  /* XXX should be able to target to the peer holding the SID, if we have it.
     In any case, we */
  if (packetSendRequest(REQ_FIRSTREPLY,packet,packet_len,NONBATCH,transaction_id,&responses)) return -1;

  r=responses.responses;
  while(r)
    {
      int slen;
      char sid[SID_SIZE*2+1];
      extractSid(r->sid,&slen,sid);
      switch(r->code)
	{
	case ACTION_ERROR:
	  /* We allocate an extra byte to allow us to do this */
	  r->response[r->response_len]=0;
	  printf("ERROR:%s\n",(char *)r->response);
	  break;
	case ACTION_OKAY: printf("ERROR:Unexpected OK response\n"); break;
	case ACTION_DECLINED: printf("DECLINED:%s\n",sid); break;
	case ACTION_WROTE: 
	  /* Supress success messages when writing fragments */
	  if (!(flags&SET_FRAGMENT)) printf("WROTE:%s\n",sid); break;
	case ACTION_DATA: printf("ERROR:DATA reponse not implemented\n"); break;
	case ACTION_GET: printf("ERROR:You cant respond with GET\n"); break;
	case ACTION_SET: printf("ERROR:You cant respond with SET\n"); break;
	case ACTION_DEL: printf("ERROR:You cant respond with DEL\n"); break;
	case ACTION_CREATEHLR: printf("ERROR:You cant respond with CREATEHLR\n"); break;
	case ACTION_PAD: /* ignore it */ break;
	case ACTION_EOT: /* ignore it */ break;
	default: printf("ERROR:Unexpected response code 0x%02x\n",r->code);
	}
      fflush(stdout);
      r=r->next;
    }

  return 0;
}
Example #19
0
int extractResponses(struct in_addr sender,unsigned char *buffer,int len,struct response_set *responses)
{
  int ofs=OFS_PAYLOAD;
  
  while(ofs<len)
    {
      /* XXX should allocate responses from a temporary and bounded slab of memory */
      struct response *r=calloc(sizeof(struct response),1);
      if (!r) exit(setReason("calloc() failed."));
      
      r->code=buffer[ofs];
      r->sender=sender;
      /* XXX doesn't make sure it is SID instead of DID */
      bcopy(&buffer[HEADERFIELDS_LEN+1],r->sid,SID_SIZE);

      switch(buffer[ofs])
	{
	case ACTION_EOT:
	  if (debug>1) fprintf(stderr,"Reached response packet EOT.\n");
	case ACTION_DECLINED: case ACTION_OKAY:
	case ACTION_CREATEHLR:
	  r->response_len=0; break;
	case ACTION_GET: 
	  /* Followed by variable # to fetch.
	     XXX If variable number >=0x80 then get instance information */
	  r->response_len=1; break;
	case ACTION_ERROR:
	  r->response_len=buffer[++ofs];
	  break;
	case ACTION_DATA:
	  /* Extract variable value */
	  unpackageVariableSegment(&buffer[ofs+1],len-ofs,WITHDATA,r);
	  break;
	case ACTION_DONE:
	  r->value_offset=buffer[ofs+1];
	  r->response_len=1;
	  break;
	case ACTION_PAD:
	  /* Skip padding bytes */
	  r->response_len=1+buffer[ofs+1];	 
	  break;
	case ACTION_WROTE:
	  /* Extract info about the variable segment that was written.
	     This uses the same format as the request to write it, but without the data */
	  unpackageVariableSegment(&buffer[ofs+1],len-ofs,WITHOUTDATA,r);
	  r->response=NULL;
	  break;
	case ACTION_SET:
	case ACTION_DEL:
	case ACTION_XFER:
	default:
	  free(r);
	  if (debug>1) fprintf(stderr,"Encountered unimplemented response code 0x%02x @ 0x%x\n",buffer[ofs],ofs);
	  return setReason("Encountered unimplemented response type");
	}
      ofs++;
      if (r->response_len) {
	/* extract bytes of response */
	unsigned char *rr;
	if (r->response) rr=r->response; else rr=&buffer[ofs];
	r->response=malloc(r->response_len+1);
	if (!r->response) exit(setReason("malloc() failed."));
	bcopy(&rr[0],r->response,r->response_len);
	ofs+=r->response_len;
      }

      /* Work out peer ID */
      r->sender=sender;
      for(r->peer_id=0;r->peer_id<peer_count;r->peer_id++)
	{
	  if (sender.s_addr==peers[r->peer_id]) break;
	}
      if (r->peer_id>peer_count) r->peer_id=-1;

      /* Link new response into chain */
      if (debug>2) printf("Linking response into response set.\n");
      r->prev=responses->last_response;
      if (responses->last_response)
	responses->last_response->next=r;
      else
	responses->responses=r;
      responses->last_response=r;
      responses->response_count++;

      responseFromPeer(responses,r->peer_id);

      if (debug>2) dumpResponses(responses);
    }
  
  return 0;
}
Example #20
0
int requestItem(char *did,char *sid,char *item,int instance,unsigned char *buffer,int buffer_length,int *len,
		unsigned char *transaction_id)
{
  unsigned char packet[8000];
  int packet_len=0;
  struct response *r;
  struct response_set responses;

  bzero(&responses,sizeof(responses));

  /* Prepare the request packet */
  if (packetMakeHeader(packet,8000,&packet_len,transaction_id)) return -1;
  if (did&&(!sid))
    { if (packetSetDid(packet,8000,&packet_len,did)) return -1; }
  else if (sid&&(!did))
    { if (packetSetSid(packet,8000,&packet_len,sid)) return -1; }
  else return setReason("You must request items by DID or SID, not neither, nor both");

      
  if (packetAddVariableRequest(packet,8000,&packet_len,
			       item,instance,0,buffer_length)) return -1;
  if (packetFinalise(packet,8000,&packet_len)) return -1;

  int method=REQ_PARALLEL;
  if (sid) method=REQ_FIRSTREPLY;
  if (packetSendRequest(method,packet,packet_len,(instance==-1)?BATCH:NONBATCH,transaction_id,&responses)) return -1;

  r=responses.responses;
  while(r)
    {
      char sid[SID_SIZE*2+1];
      int slen=0;
      extractSid(r->sid,&slen,sid);
      switch(r->code)
	{
	case ACTION_OKAY: printf("OK:%s\n",sid); break;
	case ACTION_DECLINED: printf("DECLINED:%s\n",sid); break;
	case ACTION_DATA: 
	  /* Display data.
	     The trick is knowing the format of the data.
	     Fortunately we get the variable id etc.
	     XXX Need to deal with fragmented values.
	     (perhaps the fragments should get auto-assembled when accepting the responses)
	  */
	  switch(r->var_id)
	    {
	    case VAR_DIDS:
	      {
		char did[DID_MAXSIZE+1];
		int dlen=0;
		did[0]=0;
		extractDid(r->response,&dlen,did);
		printf("DIDS:%s:%d:%s\n",sid,r->var_instance,did);
	      }
	      break;
	    case VAR_NOTE:
	    default:
	      /* ASCII formatted variable types */
	      {
		int v=0;
	        int i=0;
		FILE *outputfile=stdout;
		while(vars[v].name&&vars[v].id!=r->var_id) v++;
		if (!vars[v].id) printf("0x%02x",r->var_id);
		while(vars[v].name[i]) fputc(toupper(vars[v].name[i++]),stdout);
		printf(":%s:%d:",sid,r->var_instance);
		
		if (outputtemplate)
		  {
		    char outputname[8192];
		    snprintf(outputname,8192,outputtemplate,sid,r->var_id,r->var_instance);
		    outputfile=fopen(outputname,"w");
		    if (!outputfile) printf("ERROR:Could not open output file '%s'",outputname);
		    if (debug) fprintf(stderr,"Writing output to '%s'\n",outputname);
		  }

		if (outputfile) fwrite(r->response,r->value_bytes,1,outputfile);

		if (r->value_bytes<r->value_len)
		  {
		    /* Partial response, so ask for the rest of it */
		    unsigned char packet[8000];
		    int packet_len=0;
		    struct response *rr;
		    struct response_set responses;
		    int offset,max_bytes;
		    int recv_map[1+(r->value_len/MAX_DATA_BYTES)];
		    int recv_map_size=1+(r->value_len/MAX_DATA_BYTES);
		    int needMoreData;
		    int tries=0;

		    /* work out EXACTLY how many installments we need */
		    while (((recv_map_size-1)*MAX_DATA_BYTES)>=r->value_len) recv_map_size--;

		    recv_map[0]=0; /* we received the first installment, so mark it off ... */
		    /* ... but we haven't received the rest */
		    for(i=1;i<recv_map_size;i++) recv_map[i]=0;		    

		    /* Ask for all remaining pieces in parallel, then keep track of what has arrived
		       XXX - Not yet implemented.  Currently uses a slow serial method, worse than TFTP */  
		    needMoreData=recv_map_size-1;

		    while(needMoreData&&(tries++<15))
		      {
			if (debug>1) fprintf(stderr,"Multi-packet request: try %d, %d fragments remaining.\n",tries,needMoreData);
			needMoreData=0;
			for(i=0;i<recv_map_size;i++)
			  if (!recv_map[i])
			    {
			      needMoreData++;
			      offset=i*MAX_DATA_BYTES;
			      
			      if (debug>1) fprintf(stderr,"Asking for variable segment @ offset %d\n",offset);
			      
			      /* Send accumulated request direct to the responder */
			      if (packet_len>=MAX_DATA_BYTES)
				{
				  if (packetFinalise(packet,8000,&packet_len)) return -1;
				  packetSendFollowup(r->sender,packet,packet_len);
				  packet_len=0;
				}
			      /* Prepare a new request packet if one is not currently being built */
			      if (!packet_len)
				{
				  if (packetMakeHeader(packet,8000,&packet_len,transaction_id)) return -1;
				  if (packetSetSid(packet,8000,&packet_len,sid)) return setReason("SID went mouldy during multi-packet get");
				}
			      
			      max_bytes=65535-offset;
			      if (max_bytes>buffer_length) max_bytes=buffer_length;
			      if (packetAddVariableRequest(packet,8000,&packet_len,
							   item,r->var_instance,offset,max_bytes)) return -1;
			    }
			/* Send accumulated request direct to the responder */
			if (packet_len)
			  {
			    if (packetFinalise(packet,8000,&packet_len)) return -1;
			    packetSendFollowup(r->sender,packet,packet_len);
			    packet_len=0;
			  }
			
			/* Collect responses to our multiple requests */
			bzero(&responses,sizeof(responses));

			/* XXX should target specific peer that sent first piece */
			getReplyPackets(REQ_PARALLEL,i,0,&responses,transaction_id,250);
			rr=responses.responses;
			while(rr)
			  {
			    if (rr->code==ACTION_DATA&&rr->var_id==r->var_id&&rr->var_instance==r->var_instance)
			      {
				int piece=rr->value_offset/MAX_DATA_BYTES;
				if (!recv_map[piece])
				  {
				    if (debug>1) fprintf(stderr,"Extracted value fragment @ offset %d, with %d bytes\n",rr->value_offset,rr->value_bytes);
				    if (debug>2) dump("Fragment",rr->response,rr->value_bytes);
				    fseek(outputfile,rr->value_offset,SEEK_SET);
				    fwrite(rr->response,rr->value_bytes,1,outputfile);
				    recv_map[piece]=1;
				  }
				else
				  {
				    if (debug>1) fprintf(stderr,"DUPLICATE value fragment @ offset %d, with %d bytes\n",rr->value_offset,rr->value_bytes);
				   
				  }
			      }
			    rr=rr->next;
			  }
			clearResponses(&responses);
		      }
		  }
		if (outputtemplate) fclose(outputfile); else fflush(outputfile);		    
		printf("\n");
		break;
	      }
	    } 
	  break;
	case ACTION_DONE: 
	  printf("DONE:%s:%d\n",sid,r->response[0]);
	  break;
	case ACTION_GET: printf("ERROR:You cant respond with GET\n"); break;
	case ACTION_SET: printf("ERROR:You cant respond with SET\n"); break;
	case ACTION_WROTE: printf("ERROR:You cant respond with WROTE\n"); break;
	case ACTION_DEL: printf("ERROR:You cant respond with DEL\n"); break;
	case ACTION_CREATEHLR: printf("ERROR:You cant respond with CREATEHLR\n"); break;
	case ACTION_PAD: /* ignore it */ break;
	case ACTION_EOT: /* ignore it */ break;
	default: printf("ERROR:Unexpected response code 0x%02x\n",r->code);
	}
      fflush(stdout);
      r=r->next;
    }

  return -1;
}
Example #21
0
int server(char *backing_file,int size,int foregroundMode)
{
  
  struct sockaddr_in bind_addr;
  
  /* Get backing store */
  if (!backing_file)
    {
      /* 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;
      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;


  sock=socket(PF_INET,SOCK_DGRAM,0);
  if (sock<0) {
    fprintf(stderr,"Could not create UDP socket.\n");
    perror("socket");
    exit(-3);
  }

  bind_addr.sin_family = AF_INET;
  bind_addr.sin_port = htons( PORT_DNA );
  bind_addr.sin_addr.s_addr = htonl( INADDR_ANY );
  if(bind(sock,(struct sockaddr *)&bind_addr,sizeof(bind_addr))) {
    fprintf(stderr,"MP HLR server could not bind to UDP port %d\n", PORT_DNA);
    perror("bind");
    exit(-3);
  }

  /* Detach from the console */
  if (!foregroundMode) daemon(0,0);

  while(1) {
    unsigned char buffer[16384];
    socklen_t recvaddrlen=sizeof(recvaddr);
    struct pollfd fds;
    int len;

    bzero((void *)&recvaddr,sizeof(recvaddr));
    fds.fd=sock; fds.events=POLLIN;
    
    /* Wait patiently for packets to arrive */
    while (poll(&fds,1,1000)<1)	sleep(0);

    len=recvfrom(sock,buffer,sizeof(buffer),0,&recvaddr,&recvaddrlen);

    client_port=((struct sockaddr_in*)&recvaddr)->sin_port;
    client_addr=((struct sockaddr_in*)&recvaddr)->sin_addr;

    if (debug) fprintf(stderr,"Received packet from %s (len=%d).\n",inet_ntoa(client_addr),len);
    if (debug>1) dump("recvaddr",(unsigned char *)&recvaddr,recvaddrlen);
    if (debug>3) dump("packet",(unsigned char *)buffer,len);
    if (dropPacketP(len)) {
      if (debug) fprintf(stderr,"Simulation mode: Dropped packet due to simulated link parameters.\n");
      continue;
    }
    if (!packetOk(buffer,len,NULL)) process_packet(buffer,len,&recvaddr,recvaddrlen);
    else {
      if (debug) setReason("Ignoring invalid packet");
    }
    if (debug>1) fprintf(stderr,"Finished processing packet, waiting for next one.\n");
  }  
}
SoundTimingEvent::SoundTimingEvent(EventSource *source) :
    SoundEvent(source),
    mTime(0.0)
{
    setReason(TIMEEVENT);
}
Example #23
0
int findHlr(unsigned char *hlr,int *ofs,char *sid,char *did)
{
  unsigned int record_length;
  int match=0;
  int records_searched=0;
  int pid_len=0;
  unsigned char packed_id[40];

  if ((*ofs)>=hlr_size) return 0;

  if (debug>1) fprintf(stderr,"Searching for HLR record sid=[%s]/did=[%s]\n",sid?sid:"NULL",did?did:"NULL");
  
  if (did&&did[0]) {
    /* Make packed version of DID so that we can compare faster with the DIDs in the HLR */
    if (stowDid(packed_id,&pid_len,did)) return setReason("DID appears to be invalid");
    /* Find significant length of packed DID */
    for(pid_len=0;pid_len<DID_MAXSIZE;pid_len++) if ((packed_id[pid_len]&0x0f)==0x0f) { pid_len++; break; }
    if (debug>1) dump("Searching for DID records that match",packed_id,pid_len);
  }

  if (sid&&sid[0]) {
    /* Make packed version of SID for fast comparison */
    if (stowSid(packed_id,pid_len,sid)) return setReason("SID appears to be invalid");
    pid_len=SID_SIZE;
  }

  while(!match)
    {
      /* Get length of this record */
      record_length =hlr[(*ofs)+3]<<0;
      record_length|=hlr[(*ofs)+2]<<8;
      record_length|=hlr[(*ofs)+1]<<16;
      record_length|=hlr[(*ofs)+0]<<24;
      
      if (!record_length) return 0;

      if (debug>1) fprintf(stderr,"Considering HLR entry @ 0x%x\n",*ofs);
  
      records_searched++;
  
      if (sid&&sid[0]) {
	/* Lookup by SID, so just see if it matches */
	if (!bcompare(packed_id,&hlr[(*ofs)+4],SID_SIZE)) {
	  if (debug>1) fprintf(stderr,"Found requested SID at address 0x%x.\n",*ofs);
	  match=1;
	}
      }
      if (did&&did[0]) {
	/* Lookup by did, so see if there are any matching DID entries for this subscriber */
	int rofs=(*ofs);
	struct hlrentry_handle *h=openhlrentry(hlr,rofs);
	while(h)
	  {
	    /* Search through variables for matching DIDs */
	    if (debug>2) {
	      fprintf(stderr,"Considering variable 0x%02x, instance %d.\n",
		      h->var_id,h->var_instance);
	      dump("variable value",h->value,h->value_len);
	    }
	    if (h->var_id==VAR_DIDS) { /* DID entry  */
	      if (debug>2) fprintf(stderr,"Checking DID against record DID\n");
	      if (!bcompare(packed_id,h->value,pid_len)) {		
		if (debug>1) fprintf(stderr,"Found matching DID in HLR record #%d\n",records_searched);
		match=1;
		break;
	      }
	    }
	    else
	      {
		if (debug>2) fprintf(stderr,"Skipping non-DID variable while searching for DID.\n");
	      }		
	    h=hlrentrygetent(h);
	  }
      }
  
      /* For each match ... */
      if (match) 
	{
	  if (debug>1) fprintf(stderr,"Returning HLR entry @ 0x%x\n",*ofs);
	  return 1;
	}
  
      /* Consider next record */
      (*ofs)+=record_length;

      if ((*ofs)>=hlr_size) return 0;
    }

  return 0;
}
Example #24
0
int getReplyPackets(int method,int peer,int batchP,
		    struct response_set *responses,
		    unsigned char *transaction_id,int timeout)
{
  /* set timeout alarm */
  
  /* get packets until timeout, or until we get a packet from the specified peer
     if method==REQ_SERIAL.  If REQ_SERIAL we also reject packets from other 
     senders as they must be spoofs.
  */
  struct timeval t;
  int timeout_secs;
  int timeout_usecs;
  int to=timeout;

  if (debug>1) printf("getReplyPackets(policy=%d)\n",method);

  /* Work out when the timeout will expire */
  gettimeofday(&t,NULL); 
  timeout_secs=t.tv_sec; timeout_usecs=t.tv_usec;
  if (to>1000) { timeout_secs+=(to/1000); to=to%1000; }
  timeout_usecs+=to*1000; if (timeout_usecs>1000000) { timeout_secs++; timeout_usecs-=1000000; }
  
  while(1) {
    unsigned char buffer[16384];
    socklen_t recvaddrlen=sizeof(recvaddr);
    struct pollfd fds;
    client_port=((struct sockaddr_in*)&recvaddr)->sin_port;
    bzero((void *)&recvaddr,sizeof(recvaddr));
    fds.fd=sock; fds.events=POLLIN;
    while (poll(&fds,1,10 /* wait for 10ms at a time */)<1)
      {
	gettimeofday(&t,NULL);
	if (t.tv_sec>timeout_secs) return 1;
	if (t.tv_sec==timeout_secs&&t.tv_usec>=timeout_usecs) return 1;
      }
    client_port=((struct sockaddr_in*)&recvaddr)->sin_port;
    int len=recvfrom(sock,buffer,sizeof(buffer),0,&recvaddr,&recvaddrlen);
    client_addr=((struct sockaddr_in*)&recvaddr)->sin_addr;
    if (debug) fprintf(stderr,"Received reply from %s (len=%d).\n",inet_ntoa(client_addr),len);
    if (debug>1) dump("recvaddr",(unsigned char *)&recvaddr,recvaddrlen);
    if (debug>2) dump("packet",(unsigned char *)buffer,len);
    if (dropPacketP(len)) {
      if (debug) fprintf(stderr,"Simulation mode: Dropped packet due to simulated link parameters.\n");
      continue;
    }
    if (!packetOk(buffer,len,transaction_id)) {
      /* Packet passes tests - extract responses and append them to the end of the response list */
      if (extractResponses(client_addr,buffer,len,responses)) 
	return setReason("Problem extracting response fields from reply packets");
      if (method==REQ_SERIAL||method==REQ_FIRSTREPLY) {
	if (!batchP) return 0;
	/* In batch mode we need ACTION_DONE to mark end of transmission. 
	   While it gets sent last, out-of-order delivery means we can't rely on
	   such a nice arrangement. */
	{
	  /* XXX inefficient for long lists.
	     XXX can be made better by working backwards from end using double-linked list and 
	     remembering the previous length of the list */
	  struct response *r=responses->responses;
	  while(r)
	    {
	      if (r->code==ACTION_DONE) return 0;
	      r=r->next;
	    }
	}
      }
      else {
	if (debug>1) printf("Waiting for more packets, since called with policy %d\n",method);
      }
    } else {
      if (debug) setReason("Ignoring invalid packet");
    }      
  }
}