From Michael Tuexen:

put a CRC32C checksum into the header of SCTP packets;

	add a new "-S" option that is similar to "-s" but that also
	includes the DATA chunk header, for input files that contain
	only SCTP payloads.

svn path=/trunk/; revision=4580
This commit is contained in:
Guy Harris 2002-01-20 22:36:03 +00:00
parent bcb323d403
commit 287425df9c
2 changed files with 175 additions and 16 deletions

View File

@ -14,6 +14,7 @@ S<[ B<-e> l3pid ]>
S<[ B<-i> proto ]>
S<[ B<-u> srcport,destport ]>
S<[ B<-s> srcport,destport,tag ]>
S<[ B<-S> srcport,destport,tag ]>
S<[ B<-t> timefmt ]>
I<infile>
I<outfile>
@ -140,8 +141,13 @@ Include dummy SCTP headers before each packet. Specify the source and
destination SCTP ports, and verification tag, for the packet in decimal.
Use this option if your dump is the SCTP payload of a packet but does not
include any SCTP, IP or Ethernet headers. Note that this automatically
includes appropriate Ethernet and IP headers with each packet. The SCTP
checksum will be set to 0, rather than being calculated.
includes appropriate Ethernet and IP headers with each packet. A CRC32C
checksum will be put into the SCTP header.
=item -S srcport,destport,tag
Like B<-s>, but it also includes the DATA chunk header, for input files
that contain only the SCTP payload.
=item -t timefmt

View File

@ -6,7 +6,7 @@
*
* (c) Copyright 2001 Ashok Narayanan <ashokn@cisco.com>
*
* $Id: text2pcap.c,v 1.9 2002/01/16 21:05:09 guy Exp $
* $Id: text2pcap.c,v 1.10 2002/01/20 22:36:02 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -143,6 +143,16 @@ unsigned long hdr_sctp_src = 0;
unsigned long hdr_sctp_dest = 0;
unsigned long hdr_sctp_tag = 0;
/* Dummy DATA chunk header */
int hdr_data_chunk = FALSE;
unsigned char hdr_data_chunk_type = 0;
unsigned char hdr_data_chunk_bits = 3;
unsigned long hdr_data_chunk_tsn = 0;
unsigned short hdr_data_chunk_sid = 0;
unsigned short hdr_data_chunk_ssn = 0;
unsigned long hdr_data_chunk_ppid = 0;
/*--- Local date -----------------------------------------------------------------*/
/* This is where we store the packet currently being built */
@ -250,6 +260,18 @@ typedef struct {
hdr_sctp_t HDR_SCTP = {0, 0, 0, 0};
typedef struct {
unsigned char type;
unsigned char bits;
unsigned short length;
unsigned long tsn;
unsigned short sid;
unsigned short ssn;
unsigned long ppid;
} hdr_data_chunk_t;
hdr_data_chunk_t HDR_DATA_CHUNK = {0, 0, 0, 0, 0, 0, 0};
char tempbuf[64];
/*----------------------------------------------------------------------
@ -346,6 +368,104 @@ in_checksum (void *buf, unsigned long count)
return htons(~sum);
}
/* The CRC32C code is taken from draft-ietf-tsvwg-sctpcsum-01.txt.
* That code is copyrighted by D. Otis and has been modified.
*/
#define CRC32C(c,d) (c=(c>>8)^crc_c[(c^(d))&0xFF])
static unsigned long crc_c[256] =
{
0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L,
0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL,
0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L,
0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L,
0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L,
0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL,
0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL,
0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L,
0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL,
0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L,
0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL,
0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L,
0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L,
0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L,
0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L,
0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L,
0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L,
0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L,
0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L,
0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L,
0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L,
0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L,
0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L,
0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L,
0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL,
0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L,
0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L,
0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL,
0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL,
0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L,
0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL,
0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL,
0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L,
0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L,
0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L,
0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL,
0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L,
0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL,
0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L,
0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL,
0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL,
0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL,
0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L,
0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L,
0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L,
0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL,
0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL,
0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L,
};
static unsigned int
crc32c(const unsigned char* buf, unsigned int len, unsigned long crc32_init)
{
unsigned int i;
unsigned long crc32;
crc32 = crc32_init;
for (i = 0; i < len; i++)
CRC32C(crc32, buf[i]);
return crc32;
}
static unsigned long
number_of_padding_bytes (unsigned long length)
{
unsigned long remainder;
remainder = length % 4;
if (remainder == 0)
return 0;
else
return 4 - remainder;
}
/*----------------------------------------------------------------------
* Write current packet out
*/
@ -356,6 +476,7 @@ write_current_packet (void)
int udp_length = 0;
int ip_length = 0;
int eth_trailer_length = 0;
int i, padding_length;
struct pcaprec_hdr ph;
if (curr_offset > 0) {
@ -363,6 +484,7 @@ write_current_packet (void)
/* Compute packet length */
length = curr_offset;
if (hdr_data_chunk) { length += sizeof(HDR_DATA_CHUNK) + number_of_padding_bytes(curr_offset); }
if (hdr_sctp) { length += sizeof(HDR_SCTP); }
if (hdr_udp) { length += sizeof(HDR_UDP); udp_length = length; }
if (hdr_ip) { length += sizeof(HDR_IP); ip_length = length; }
@ -406,14 +528,39 @@ write_current_packet (void)
fwrite(&HDR_UDP, sizeof(HDR_UDP), 1, output_file);
}
/* Compute DATA chunk header and append padding */
if (hdr_data_chunk) {
HDR_DATA_CHUNK.type = hdr_data_chunk_type;
HDR_DATA_CHUNK.bits = hdr_data_chunk_bits;
HDR_DATA_CHUNK.length = htons(curr_offset + sizeof(HDR_DATA_CHUNK));
HDR_DATA_CHUNK.tsn = htonl(hdr_data_chunk_tsn);
HDR_DATA_CHUNK.sid = htons(hdr_data_chunk_sid);
HDR_DATA_CHUNK.ssn = htons(hdr_data_chunk_ssn);
HDR_DATA_CHUNK.ppid = htonl(hdr_data_chunk_ppid);
padding_length = number_of_padding_bytes(curr_offset);
for (i=0; i<padding_length; i++)
write_byte("0");
}
/* Write SCTP header */
if (hdr_sctp) {
HDR_SCTP.src_port = htons(hdr_sctp_src);
HDR_SCTP.dest_port = htons(hdr_sctp_dest);
HDR_SCTP.tag = htonl(hdr_sctp_tag);
HDR_SCTP.tag = htonl(hdr_sctp_tag);
HDR_SCTP.checksum = htonl(0);
HDR_SCTP.checksum = crc32c((unsigned char *)&HDR_SCTP, sizeof(HDR_SCTP), ~0L);
if (hdr_data_chunk)
HDR_SCTP.checksum = crc32c((unsigned char *)&HDR_DATA_CHUNK, sizeof(HDR_DATA_CHUNK), HDR_SCTP.checksum);
HDR_SCTP.checksum = htonl(crc32c(packet_buf, curr_offset, HDR_SCTP.checksum));
fwrite(&HDR_SCTP, sizeof(HDR_SCTP), 1, output_file);
}
/* Write DATA chunk header */
if (hdr_data_chunk) {
fwrite(&HDR_DATA_CHUNK, sizeof(HDR_DATA_CHUNK), 1, output_file);
}
/* Write packet */
fwrite(packet_buf, curr_offset, 1, output_file);
@ -749,7 +896,7 @@ help (char *progname)
fprintf(stderr,
"\n"
"Usage: %s [-d] [-q] [-o h|o] [-l typenum] [-e l3pid] [-i proto] \n"
" [-u srcp,destp] [-s srcp,destp,tag] [-t timefmt] <input-filename> <output-filename>\n"
" [-u srcp,destp] [-s srcp,destp,tag] [-S srcp,destp,tag] [-t timefmt] <input-filename> <output-filename>\n"
"\n"
"where <input-filename> specifies input filename (use - for standard input)\n"
" <output-filename> specifies output filename (use - for standard output)\n"
@ -774,6 +921,8 @@ help (char *progname)
" verification tag (in DECIMAL).\n"
" Automatically prepends Ethernet and IP headers as well\n"
" Example: -s 30,40,34\n"
" -S srcp,dstp,tag: Same as -s srcp,dstp,tag but also prepends a DATA chunk header.\n"
" Example: -S 30,40,34\n"
" -t timefmt : Treats the text before the packet as a date/time code; the\n"
" specified argument is a format string of the sort supported\n"
" by strptime.\n"
@ -798,7 +947,7 @@ parse_options (int argc, char *argv[])
char *p;
/* Scan CLI parameters */
while ((c = getopt(argc, argv, "dqr:w:e:i:l:o:u:s:t:")) != -1) {
while ((c = getopt(argc, argv, "dqr:w:e:i:l:o:u:s:S:t:")) != -1) {
switch(c) {
case '?': help(argv[0]); break;
case 'h': help(argv[0]); break;
@ -830,15 +979,17 @@ parse_options (int argc, char *argv[])
hdr_ethernet_proto = 0x800;
break;
case 'S':
hdr_data_chunk = TRUE;
case 's':
hdr_sctp = TRUE;
hdr_sctp_src = strtol(optarg, &p, 10);
if (p == optarg || (*p != ',' && *p != '\0')) {
fprintf(stderr, "Bad src port for '-s'\n");
fprintf(stderr, "Bad src port for '-%c'\n", c);
help(argv[0]);
}
if (*p == '\0') {
fprintf(stderr, "No dest port specified for '-s'\n");
fprintf(stderr, "No dest port specified for '-%c'\n", c);
help(argv[0]);
}
p++;
@ -848,14 +999,14 @@ parse_options (int argc, char *argv[])
fprintf(stderr, "Bad dest port for '-s'\n");
help(argv[0]);
} if (*p == '\0') {
fprintf(stderr, "No dest port specified for '-s'\n");
fprintf(stderr, "No dest port specified for '-%c'\n", c);
help(argv[0]);
}
p++;
optarg = p;
hdr_sctp_tag = strtol(optarg, &p, 10);
if (p == optarg || *p != '\0') {
fprintf(stderr, "Bad tag for '-s'\n");
fprintf(stderr, "Bad tag for '-%c'\n", c);
help(argv[0]);
}
@ -931,7 +1082,7 @@ parse_options (int argc, char *argv[])
/* Some validation */
if (pcap_link_type != 1 && hdr_ethernet) {
fprintf(stderr, "Dummy headers (-e, -i, -u, -s) cannot be specified with link type override (-l)\n");
fprintf(stderr, "Dummy headers (-e, -i, -u, -s, -S) cannot be specified with link type override (-l)\n");
exit(-1);
}
@ -951,13 +1102,15 @@ parse_options (int argc, char *argv[])
fprintf(stderr, "Output to: %s\n", output_filename);
if (hdr_ethernet) fprintf(stderr, "Generate dummy Ethernet header: Protocol: 0x%0lX\n",
hdr_ethernet_proto);
hdr_ethernet_proto);
if (hdr_ip) fprintf(stderr, "Generate dummy IP header: Protocol: %ld\n",
hdr_ip_proto);
hdr_ip_proto);
if (hdr_udp) fprintf(stderr, "Generate dummy UDP header: Source port: %ld. Dest port: %ld\n",
hdr_udp_src, hdr_udp_dest);
hdr_udp_src, hdr_udp_dest);
if (hdr_sctp) fprintf(stderr, "Generate dummy SCTP header: Source port: %ld. Dest port: %ld. Tag: %ld\n",
hdr_sctp_src, hdr_sctp_dest, hdr_sctp_tag);
hdr_sctp_src, hdr_sctp_dest, hdr_sctp_tag);
if (hdr_data_chunk) fprintf(stderr, "Generate dummy DATA chunk header: TSN: %ld. SID: %d. SSN: %d. PPID: %ld\n",
hdr_data_chunk_tsn, hdr_data_chunk_sid, hdr_data_chunk_ssn, hdr_data_chunk_ppid);
}
}