#include <string.h>
#include <stdio.h>
#include "oob_shared.h"
#ifdef _WIN32
#include <ws2tcpip.h>
#else
#include <arpa/inet.h>
#endif
static unsigned short csum(unsigned short *buf, int nwords)
{
unsigned long sum;
for(sum=0; nwords>0; nwords--)
sum += *buf++;
sum = (sum >> 16) + (sum &0xffff);
sum += (sum >> 16);
return (unsigned short)(~sum);
}
void populate_ip_header(struct ipheader *ip, char *sourceip, char *destip, unsigned short api_id, unsigned short protocol)
{
ip->iph_verlen = 0x45;
ip->iph_tos = 0;
ip->iph_len = htons(sizeof(struct ipheader));
ip->iph_ident = htons(api_id);
ip->iph_flags = 0x0040;
ip->iph_ttl = 0x40;
ip->iph_protocol = protocol;
ip->iph_sourceip = inet_addr(sourceip);
ip->iph_destip = inet_addr(destip);
ip->iph_chksum = 0;
}
int oob_build_api_payload(char *buffer, char *sourceip, char *destip, char *message, int message_len)
{
struct ipheader *ip = (struct ipheader *) buffer;
populate_ip_header(ip, sourceip, destip, RIST_OOB_API_IP_IDENT_AUTH, RIST_OOB_API_IP_PROTOCOL);
memcpy(buffer + sizeof(struct ipheader), message, message_len);
int total_len = sizeof(struct ipheader) + message_len;
ip->iph_len = htons(total_len);
ip->iph_chksum = csum((unsigned short *)buffer, total_len);
return total_len;
}
char *oob_process_api_message(int buffer_len, char *buffer, int *message_len)
{
struct ipheader *ip = (struct ipheader *) buffer;
int header_size = sizeof(struct ipheader);
if (htons(buffer_len) != ip->iph_len) {
*message_len = RIST_OOB_ERROR_INVALID_LENGTH;
return NULL;
}
if (ip->iph_protocol != RIST_OOB_API_IP_PROTOCOL) {
*message_len = RIST_OOB_ERROR_INVALID_PROTO;
return NULL;
}
if (ip->iph_ident != htons(RIST_OOB_API_IP_IDENT_AUTH)) {
*message_len = RIST_OOB_ERROR_INVALID_IDENT;
return NULL;
}
*message_len = buffer_len - header_size;
return buffer + header_size;
}