/***************************************************************
 *
 * OpenBeacon.org - dirty OnAir protocol replayer
 * accepts a concatenaded set of binary 24C3 sputnik logs. 
 *
 * ---> for internal use only <---
 *
 *
 * See the following website for binary Sputnik data:
 * http://people.openpcd.org/meri/openbeacon/sputnik/data/24c3/beware-of-the-leopard/
 * (just conatenate all binary log files by using 'cat' into 'sputnik.bin') 
 *
 * Copyright 2006 Milosch Meriac <meriac@openbeacon.de>
 *
 ***************************************************************/

/*
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; version 2.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

*/
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>

#define SRV_IP "127.0.0.1"
#define PORT 2342

typedef struct
{
  u_int32_t timestamp;
  u_int32_t ip;
  u_int8_t size, proto;
  u_int8_t flags, strength;
  u_int32_t seq;
  u_int32_t oid;
  u_int16_t reserved;
  u_int16_t crc;
} __attribute__((__packed__)) TBeaconTracker;

void diep(char *s)
{
    perror(s);
    exit(1);
}

unsigned short crc16 (const void *buf, int size)
{
    unsigned short crc = 0xFFFF;
    const unsigned char *buffer = (const unsigned char *)buf;

    if(buffer && size)
        while (size--)
        {
            crc = (crc >> 8) | (crc << 8);
            crc ^= *buffer++;
            crc ^= ((unsigned char) crc) >> 4;
            crc ^= crc << 12;
            crc ^= (crc & 0xFF) << 5;
        }

    return crc;
}

int main(void)
{
    int res,f,s,i;
    struct sockaddr_in si_other;
    TBeaconTracker item;    

    memset ((char *) &si_other, 0, sizeof (si_other));
    si_other.sin_family = AF_INET;
    si_other.sin_port = htons (PORT);
    if (inet_aton (SRV_IP, &si_other.sin_addr) == 0)
	diep("inet_aton() failed\n");

    if ((s = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
	diep ("socket");
    
    if((f=open("sputnik.bin",0))==-1)
    {
	diep("sputnik log file");
	close(s);	
    }
    
    res=i=0;
    while(read(f,&item,sizeof(item))==sizeof(item))
    {
	if(ntohs(item.crc)!=crc16(&item.size,sizeof(item)-sizeof(item.crc)-sizeof(item.timestamp)-sizeof(item.ip)))
	{
	    printf("\nCRC broken.");
	    res=2;
	    break;
	}	
	
	if (sendto (s,((unsigned char*)(&item))+4, sizeof(item)-4, 0, (struct sockaddr*)&si_other, sizeof(si_other)) == -1)
	{
	    printf("\nnetwork broken.");
	    res=3;
	    break;
	}
	
	usleep(100000);
    }    
    
    close(s);
    close(f);
    
    return res;
}

