blob: 69b8fd5e0322dbe24521725b8993a65d5dc3f4fe [file]
/*******************************************************************
*
* Description: Test application for SCTP
*
* Date: 06/15/99
*
*/
/******************************************************************
* Test application for SCTP
******************************************************************/
/******************************************************************
* EXTERNAL REFERENCES
*******************************************************************
*/
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <strings.h>
#include <poll.h>
#include <errno.h>
#include <setjmp.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/sctp.h>
#include <pcap.h>
struct part_ip {
uint8_t ver;
uint8_t tos;
uint16_t len;
uint16_t ip_id;
uint16_t ip_off;
};
struct part_ip6 {
uint32_t ver;
uint16_t len;
uint16_t rest;
};
int
main(int argc, char **argv)
{
uint8_t buf[SCTP_PACKET_LOG_SIZE];
FILE *io, *out;
int ret, i;
struct pcap_file_header head;
uint32_t loopback = 0x00000002;
struct pcap_pkthdr phead;
struct part_ip *ip;
struct part_ip6 *ip6;
uint16_t len;
char *infile=NULL, *outfile=NULL;
int byte_order_rev=0;
int limit, at, wlen, cnt=0;
struct sctp_packet_log {
uint32_t datasize;
uint32_t prev;
uint32_t timestamp;
/* we should always have at least 20 bytes */
char data[20];
} *header;
while ((i = getopt(argc,argv,"i:o:e?")) != EOF) {
switch (i) {
case 'i':
infile = optarg;
break;
case 'o':
outfile = optarg;
break;
case 'e':
byte_order_rev = 1;
break;
default:
case '?':
goto error_out;
}
}
if((infile == NULL) || (outfile == NULL) ) {
error_out:
printf("Use %s -i input-file -o output-file [-e]\n", argv[0]);
printf(" -e is for dumps generated on a non intel byte order machine\n");
return (-1);
}
io = fopen(infile, "r");
if(io == NULL) {
printf("Can't open %s error:%d\n", argv[1], errno);
return (0);
}
out = fopen(outfile, "w+");
if (out == NULL) {
printf("Can't open %s error:%d\n", argv[2], errno);
return (0);
}
limit = fread(buf, 1, SCTP_PACKET_LOG_SIZE, io);
if(limit < 0) {
printf("Could not read error %d\n", errno);
fclose(io);
return (0);
}
printf("Read in %d bytes\n", limit);
/* build pcap header and write */
if (byte_order_rev) {
head.magic = htonl(0xa1b2c3d4);
head.version_major = htons(PCAP_VERSION_MAJOR);
head.version_minor = htons(PCAP_VERSION_MINOR);
head.snaplen = htonl(0x0000ffff);
} else {
head.magic = 0xa1b2c3d4;
head.version_major = PCAP_VERSION_MAJOR;
head.version_minor = PCAP_VERSION_MINOR;
head.snaplen = 0x0000ffff;
}
head.thiszone = 0;
head.sigfigs = 0;
head.linktype = 0;
if( (ret=fwrite(&head, sizeof(head), 1, out)) < 1) {
printf("Can't write header ret:%d errno=%d\n",
ret,errno);
return(0);
}
header = (struct sctp_packet_log *)buf;
at = 0;
while (at < limit) {
if(byte_order_rev) {
int x;
x = ntohl(header->datasize);
header->datasize = x;
x = ntohl(header->timestamp);
header->timestamp = x;
}
printf("%d - %d bytes (including pad), ts:%x ipversion:%x\n",
cnt,
header->datasize,
header->timestamp,
((header->data[0] >> 4) & 0x0f));
cnt++;
phead.ts.tv_sec = header->timestamp/1000000;
if(header->timestamp > 1000000) {
phead.ts.tv_usec = header->timestamp % 1000000;
}
if( header->datasize > limit) {
printf("strange, size > limit:%d\n", limit);
break;
}
if(((header->data[0] & 0xf0) >> 4) == 4) {
uint16_t tmp;
ip = (struct part_ip *) header->data;
if(byte_order_rev == 0) {
len = ip->len;
tmp = htons(ip->ip_off);
ip->ip_off = tmp;
ip->len = htons(header->datasize-16);
} else {
len = ntohs(ip->len);
}
len = wlen = header->datasize-16;
wlen = ((((len)+3) >> 2) << 2);
} else if (((header->data[0] & 0xf0) >> 4) == 6) {
ip6 = (struct part_ip6 *)header->data;
if(byte_order_rev)
len = ntohs(ip6->len);
else
len = ip6->len;
wlen = header->datasize - 12;
} else {
printf("Not v6 or v4?\n");
break;
}
if(byte_order_rev)
phead.len = phead.caplen = htonl(wlen + 4);
else
phead.len = phead.caplen = wlen + 4;
if((ret=fwrite(&phead, sizeof(phead), 1, out)) < 1) {
printf("Can't write phead ret:%d errno=%d\n",
ret,errno);
fclose(out);
return(0);
}
if ((ret=fwrite(&loopback, sizeof(loopback), 1, out)) < 1) {
printf("Can't write encaps ret:%d errno=%d\n",
ret,errno);
fclose(out);
return(0);
}
if ((ret=fwrite(header->data, wlen, 1, out)) < 1) {
printf("Can't write body ret:%d errno=%d\n",
ret,errno);
fclose(out);
return(0);
}
at += header->datasize;
header = (struct sctp_packet_log *)(&buf[at]);
}
printf("pcap file complete\n");
fclose(out);
fclose(io);
return (0);
}