INET Framework for OMNeT++/OMNEST
inet::serializer::SCTPSerializer Class Reference

Converts between SCTPMessage and binary (network byte order) SCTP header. More...

#include <SCTPSerializer.h>

Inheritance diagram for inet::serializer::SCTPSerializer:
inet::serializer::SerializerBase

Public Member Functions

 SCTPSerializer (const char *name=nullptr)
 
int32 serialize (const sctp::SCTPMessage *msg, uint8 *buf, uint32 bufsize)
 Serializes an SCTPMessage for transmission on the wire. More...
 
void parse (const uint8 *buf, uint32 bufsize, sctp::SCTPMessage *dest)
 Puts a packet sniffed from the wire into an SCTPMessage. More...
 
void calculateSharedKey ()
 
bool compareRandom ()
 
- Public Member Functions inherited from inet::serializer::SerializerBase
 SerializerBase (const char *name=nullptr)
 
void serializePacket (const cPacket *pkt, Buffer &b, Context &context)
 
cPacket * deserializePacket (const Buffer &b, Context &context)
 

Static Public Member Functions

static uint32 checksum (const uint8 *buf, register uint32 len)
 
static void hmacSha1 (const uint8 *buf, uint32 buflen, const uint8 *key, uint32 keylen, uint8 *digest)
 
- Static Public Member Functions inherited from inet::serializer::SerializerBase
static SerializerBaselookupSerializer (const cPacket *pkt, Context &context, ProtocolGroup group, int id)
 
static void lookupAndSerialize (const cPacket *pkt, Buffer &b, Context &context, ProtocolGroup group, int id, unsigned int maxLength=(unsigned int)(-1))
 
static SerializerBaselookupDeserializer (Context &context, ProtocolGroup group, int id)
 
static cPacket * lookupAndDeserialize (const Buffer &b, Context &context, ProtocolGroup group, int id, unsigned int maxLength=(unsigned int)(-1))
 

Protected Member Functions

virtual void serialize (const cPacket *pkt, Buffer &b, Context &context) override
 Serializes a cPacket for transmission on the wire. More...
 
virtual cPacket * deserialize (const Buffer &b, Context &context) override
 Puts a packet sniffed from the wire into an EtherFrame. More...
 

Static Private Attributes

static unsigned char keyVector [512]
 
static unsigned int sizeKeyVector = 0
 
static unsigned char peerKeyVector [512]
 
static unsigned int sizePeerKeyVector = 0
 
static unsigned char sharedKey [512]
 

Detailed Description

Converts between SCTPMessage and binary (network byte order) SCTP header.

Constructor & Destructor Documentation

inet::serializer::SCTPSerializer::SCTPSerializer ( const char *  name = nullptr)
inline
38 : SerializerBase(name) {}
SerializerBase(const char *name=nullptr)
Definition: SerializerBase.h:84

Member Function Documentation

void inet::serializer::SCTPSerializer::calculateSharedKey ( )
2242 {
2243  unsigned int i;
2244  bool peerFirst = false;
2245 
2246  peerFirst = compareRandom();
2247 
2248  if (peerFirst == false) {
2249  for (i = 0; i < sizeKeyVector; i++)
2250  sharedKey[i] = keyVector[i];
2251  for (i = 0; i < sizePeerKeyVector; i++)
2252  sharedKey[i + sizeKeyVector] = peerKeyVector[i];
2253  }
2254  else {
2255  for (i = 0; i < sizePeerKeyVector; i++)
2256  sharedKey[i] = peerKeyVector[i];
2257  for (i = 0; i < sizeKeyVector; i++)
2258  sharedKey[i + sizePeerKeyVector] = keyVector[i];
2259  }
2260 }
static unsigned int sizePeerKeyVector
Definition: SCTPSerializer.h:62
static unsigned char sharedKey[512]
Definition: SCTPSerializer.h:63
static unsigned int sizeKeyVector
Definition: SCTPSerializer.h:60
static unsigned char peerKeyVector[512]
Definition: SCTPSerializer.h:61
static unsigned char keyVector[512]
Definition: SCTPSerializer.h:59
bool compareRandom()
Definition: SCTPSerializer.cc:2219
uint32 inet::serializer::SCTPSerializer::checksum ( const uint8 buf,
register uint32  len 
)
static
1149 {
1150  uint32 h;
1151  unsigned char byte0, byte1, byte2, byte3;
1152  uint32 crc32c;
1153  uint32 i;
1154  uint32 res = (~0L);
1155  for (i = 0; i < len; i++)
1156  CRC32C(res, buf[i]);
1157  h = ~res;
1158  byte0 = h & 0xff;
1159  byte1 = (h >> 8) & 0xff;
1160  byte2 = (h >> 16) & 0xff;
1161  byte3 = (h >> 24) & 0xff;
1162  crc32c = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3);
1163  return htonl(crc32c);
1164 }
uint16_t len
Definition: TCP_NSC.cc:85
u32_t htonl(u32_t n)
#define CRC32C(c, d)
Definition: sctphdr.h:44
uint32_t uint32
Definition: Compat.h:30
const value< double, compose< units::J, units::s > > h(6.62606896e-34)
bool inet::serializer::SCTPSerializer::compareRandom ( )
2220 {
2221  unsigned int i, size;
2224  return false;
2225  }
2226  else {
2227  return true;
2228  }
2229  }
2230  else
2231  size = sizeKeyVector;
2232  for (i = 0; i < size; i++) {
2233  if (keyVector[i] < peerKeyVector[i])
2234  return false;
2235  if (keyVector[i] > peerKeyVector[i])
2236  return true;
2237  }
2238  return true;
2239 }
static unsigned int sizePeerKeyVector
Definition: SCTPSerializer.h:62
static unsigned int sizeKeyVector
Definition: SCTPSerializer.h:60
static unsigned char peerKeyVector[512]
Definition: SCTPSerializer.h:61
static unsigned char keyVector[512]
Definition: SCTPSerializer.h:59
cPacket * inet::serializer::SCTPSerializer::deserialize ( const Buffer b,
Context context 
)
overrideprotectedvirtual

Puts a packet sniffed from the wire into an EtherFrame.

Implements inet::serializer::SerializerBase.

68 {
69  SCTPMessage *dest = new SCTPMessage("parsed-sctp");
70  parse(static_cast<const uint8 *>(b.accessNBytes(0)), b.getRemainingSize(), dest);
71  b.accessNBytes(b.getRemainingSize());
72  return dest;
73 }
void parse(const uint8 *buf, uint32 bufsize, sctp::SCTPMessage *dest)
Puts a packet sniffed from the wire into an SCTPMessage.
Definition: SCTPSerializer.cc:1166
value< double, units::m > b
Definition: Units.h:1054
void inet::serializer::SCTPSerializer::hmacSha1 ( const uint8 buf,
uint32  buflen,
const uint8 key,
uint32  keylen,
uint8 digest 
)
static
1141 {
1142  /* XXX needs to be implemented */
1143  for (uint16 i = 0; i < SHA_LENGTH; i++) {
1144  digest[i] = 0;
1145  }
1146 }
#define SHA_LENGTH
Definition: SCTPAssociation.h:235
uint16_t uint16
Definition: Compat.h:32
void inet::serializer::SCTPSerializer::parse ( const uint8 buf,
uint32  bufsize,
sctp::SCTPMessage dest 
)

Puts a packet sniffed from the wire into an SCTPMessage.

1167 {
1168  int32 size_common_header = sizeof(struct common_header);
1169  int32 size_init_chunk = sizeof(struct init_chunk);
1170  int32 size_init_ack_chunk = sizeof(struct init_ack_chunk);
1171  int32 size_data_chunk = sizeof(struct data_chunk);
1172  int32 size_sack_chunk = sizeof(struct sack_chunk);
1173  int32 size_heartbeat_chunk = sizeof(struct heartbeat_chunk);
1174  int32 size_heartbeat_ack_chunk = sizeof(struct heartbeat_ack_chunk);
1175  int32 size_abort_chunk = sizeof(struct abort_chunk);
1176  int32 size_cookie_echo_chunk = sizeof(struct cookie_echo_chunk);
1177  int size_error_chunk = sizeof(struct error_chunk);
1178  int size_forward_tsn_chunk = sizeof(struct forward_tsn_chunk);
1179  int size_asconf_chunk = sizeof(struct asconf_chunk);
1180  int size_addip_parameter = sizeof(struct add_ip_parameter);
1181  int size_asconf_ack_chunk = sizeof(struct asconf_ack_chunk);
1182  int size_auth_chunk = sizeof(struct auth_chunk);
1183  int size_stream_reset_chunk = sizeof(struct stream_reset_chunk);
1184  uint16 paramType;
1185  int32 parptr, chunklen, cLen, woPadding;
1186  struct common_header *common_header = (struct common_header *)(buf);
1187  int32 tempChecksum = common_header->checksum;
1188  common_header->checksum = 0;
1189  int32 chksum = checksum((unsigned char *)common_header, bufsize);
1190  common_header->checksum = tempChecksum;
1191 
1192  const unsigned char *chunks = (unsigned char *)(buf + size_common_header);
1193  EV_TRACE << "SCTPSerializer::parse SCTPMessage\n";
1194  if (tempChecksum == chksum)
1195  dest->setChecksumOk(true);
1196  else
1197  dest->setChecksumOk(false);
1198  EV_DETAIL << "checksumOK=" << dest->getChecksumOk() << "\n";
1199  dest->setSrcPort(ntohs(common_header->source_port));
1200  dest->setDestPort(ntohs(common_header->destination_port));
1201  dest->setTag(ntohl(common_header->verification_tag));
1202  dest->setBitLength(SCTP_COMMON_HEADER * 8);
1203  // chunks
1204  uint32 chunkPtr = 0;
1205 
1206  // catch ALL chunks - when a chunk is taken, the chunkPtr is set to the next chunk
1207  while (chunkPtr < (bufsize - size_common_header)) {
1208  const struct chunk *chunk = (struct chunk *)(chunks + chunkPtr);
1209  int32 chunkType = chunk->type;
1210  woPadding = ntohs(chunk->length);
1211  cLen = ADD_PADDING(woPadding);
1212  switch (chunkType) {
1213  case DATA: {
1214  EV_INFO << "Data received\n";
1215  const struct data_chunk *dc = (struct data_chunk *)(chunks + chunkPtr);
1216  EV_DETAIL << "cLen=" << cLen << "\n";
1217  if (cLen == 0)
1218  throw new cRuntimeError("Incoming SCTP packet contains data chunk with length==0");
1219  SCTPDataChunk *chunk = new SCTPDataChunk("DATA");
1220  chunk->setChunkType(chunkType);
1221  chunk->setUBit(dc->flags & UNORDERED_BIT);
1222  chunk->setBBit(dc->flags & BEGIN_BIT);
1223  chunk->setEBit(dc->flags & END_BIT);
1224  chunk->setIBit(dc->flags & I_BIT);
1225  chunk->setTsn(ntohl(dc->tsn));
1226  chunk->setSid(ntohs(dc->sid));
1227  chunk->setSsn(ntohs(dc->ssn));
1228  chunk->setPpid(ntohl(dc->ppi));
1229  chunk->setByteLength(SCTP_DATA_CHUNK_LENGTH);
1230  EV_DETAIL << "parse data: woPadding=" << woPadding << " size_data_chunk=" << size_data_chunk << "\n";
1231  if (woPadding > size_data_chunk) {
1232  SCTPSimpleMessage *msg = new SCTPSimpleMessage("data");
1233  int32 datalen = (woPadding - size_data_chunk);
1234  msg->setBitLength(datalen * 8);
1235  msg->setDataLen(datalen);
1236  msg->setDataArraySize(datalen);
1237  for (int32 i = 0; i < datalen; i++)
1238  msg->setData(i, dc->user_data[i]);
1239 
1240  chunk->encapsulate(msg);
1241  }
1242  EV_DETAIL << "datachunkLength=" << chunk->getByteLength() << "\n";
1243  dest->addChunk(chunk);
1244  break;
1245  }
1246 
1247  case INIT: {
1248  EV << "parse INIT\n";
1249  const struct init_chunk *init_chunk = (struct init_chunk *)(chunks + chunkPtr); // (recvBuffer + size_ip + size_common_header);
1250  struct tlv *cp;
1251  struct random_parameter *rp;
1252  struct hmac_algo *hp;
1253  unsigned int rplen = 0, hplen = 0, cplen = 0;
1254  chunklen = SCTP_INIT_CHUNK_LENGTH;
1255  SCTPInitChunk *chunk = new SCTPInitChunk("INIT");
1256  chunk->setChunkType(chunkType);
1257  chunk->setName("INIT");
1258  chunk->setInitTag(ntohl(init_chunk->initiate_tag));
1259  chunk->setA_rwnd(ntohl(init_chunk->a_rwnd));
1260  chunk->setNoOutStreams(ntohs(init_chunk->mos));
1261  chunk->setNoInStreams(ntohs(init_chunk->mis));
1262  chunk->setInitTSN(ntohl(init_chunk->initial_tsn));
1263  chunk->setAddressesArraySize(0);
1264  chunk->setUnrecognizedParametersArraySize(0);
1265  //sctpEV3<<"INIT arrived from wire\n";
1266  if (cLen > size_init_chunk) {
1267  int32 parcounter = 0, addrcounter = 0;
1268  parptr = 0;
1269  int chkcounter = 0;
1270  bool stopProcessing = false;
1271  while (cLen > size_init_chunk + parptr && !stopProcessing) {
1272  EV_INFO << "Process INIT parameters" << endl;
1273  const struct tlv *parameter = (struct tlv *)(((unsigned char *)init_chunk) + size_init_chunk + parptr);
1274  paramType = ntohs(parameter->type);
1275  EV_INFO << "search for param: " << paramType << " - current chunklen: " << chunklen << endl;
1276  switch (paramType) {
1277  case SUPPORTED_ADDRESS_TYPES: {
1278  const struct supported_address_types_parameter *sup_addr = (struct supported_address_types_parameter *)(((unsigned char *)init_chunk) + size_init_chunk + parptr);
1279  if (sup_addr->address_type_1 == ntohs(INIT_PARAM_IPV4) || sup_addr->address_type_2 == ntohs(INIT_PARAM_IPV4)) {
1280  chunk->setIpv4Supported(true);
1281  } else {
1282  chunk->setIpv4Supported(false);
1283  }
1284  if (sup_addr->address_type_1 == ntohs(INIT_PARAM_IPV6) || sup_addr->address_type_2 == ntohs(INIT_PARAM_IPV6)) {
1285  chunk->setIpv6Supported(true);
1286  } else {
1287  chunk->setIpv6Supported(false);
1288  }
1289  chunklen += 8;
1290  break;
1291  }
1292 
1293  case INIT_PARAM_IPV4: {
1294  // we supppose an ipv4 address parameter
1295  EV_INFO << "IPv4\n";
1296  const struct init_ipv4_address_parameter *v4addr;
1297  v4addr = (struct init_ipv4_address_parameter *)(((unsigned char *)init_chunk) + size_init_chunk + parptr);
1298  chunk->setAddressesArraySize(++addrcounter);
1299  L3Address localv4Addr(IPv4Address(ntohl(v4addr->address)));
1300  chunk->setAddresses(addrcounter - 1, localv4Addr);
1301  chunklen += 8;
1302  break;
1303  }
1304 
1305  case INIT_PARAM_IPV6: {
1306  EV_INFO << "IPv6\n";
1307  const struct init_ipv6_address_parameter *ipv6addr;
1308  ipv6addr = (struct init_ipv6_address_parameter *)(((unsigned char *)init_chunk) + size_init_chunk + parptr);
1309  IPv6Address ipv6Addr = IPv6Address(ipv6addr->address[0], ipv6addr->address[1],
1310  ipv6addr->address[2], ipv6addr->address[3]);
1311  L3Address localv6Addr(ipv6Addr);
1312  EV_INFO << "address" << ipv6Addr << "\n";
1313  chunk->setAddressesArraySize(++addrcounter);
1314  chunk->setAddresses(addrcounter - 1, localv6Addr);
1315  chunklen += 20;
1316  break;
1317  }
1318 
1319  case SUPPORTED_EXTENSIONS: {
1320  EV_INFO << "Supported extensions\n";
1321  const struct supported_extensions_parameter *supext;
1322  supext = (struct supported_extensions_parameter *)(((unsigned char *)init_chunk) + size_init_chunk + parptr);
1323  unsigned short chunkTypes;
1324  int len = 4;
1325  EV_INFO << "supext->len=" << ntohs(supext->length) << "\n";
1326  while (ntohs(supext->length) > len) {
1327  chunkTypes = (int)*(chunks + chunkPtr + size_init_chunk + parptr + 4 + chkcounter);
1328  chunk->setSepChunksArraySize(++chkcounter);
1329  EV_INFO << "Extension " << chunkTypes << " added\n";
1330  chunk->setSepChunks(chkcounter - 1, chunkTypes);
1331  len++;
1332  }
1333  chunklen += ADD_PADDING(len);
1334  break;
1335  }
1336 
1338  EV_INFO << "Forward TSN\n";
1339  int size = chunk->getChunkTypesArraySize();
1340  chunk->setChunkTypesArraySize(size + 1);
1341  chunk->setChunkTypes(size, FORWARD_TSN_SUPPORTED_PARAMETER);
1342  chunklen += ntohs(parameter->length);
1343  break;
1344  }
1345 
1346  case RANDOM: {
1347  EV_INFO << "random parameter received\n";
1348  const struct random_parameter *rand;
1349  rand = (struct random_parameter *)(((unsigned char *)init_chunk) + size_init_chunk + parptr);
1350  unsigned char *rv = (unsigned char *)malloc(64);
1351  rp = (struct random_parameter *)((unsigned char *)rv);
1352  rp->type = rand->type;
1353  rplen = ntohs(rand->length);
1354  rp->length = rand->length;
1355  int rlen = ntohs(rand->length) - 4;
1356  chunk->setRandomArraySize(rlen);
1357  for (int i = 0; i < rlen; i++) {
1358  chunk->setRandom(i, (unsigned char)(rand->random[i]));
1359  rp->random[i] = (unsigned char)(rand->random[i]);
1360  }
1361  EV_INFO << "adding " << ntohs(parameter->length) << " bytes" << endl;
1362  chunklen += ntohs(parameter->length);
1363  break;
1364  }
1365 
1366  case HMAC_ALGO: {
1367  EV_INFO << "hmac_algo parameter received\n";
1368  const struct hmac_algo *hmac;
1369  hmac = (struct hmac_algo *)(((unsigned char *)init_chunk) + size_init_chunk + parptr);
1370  int num = (ntohs(hmac->length) - 4) / 2;
1371  chunk->setHmacTypesArraySize(num);
1372  unsigned char *hv = (unsigned char *)malloc(64);
1373  hp = (struct hmac_algo *)((unsigned char *)hv);
1374  hp->type = hmac->type;
1375  hplen = ntohs(hmac->length);
1376  hp->length = hmac->length;
1377  for (int i = 0; i < num; i++) {
1378  chunk->setHmacTypes(i, ntohs(hmac->ident[i]));
1379  hp->ident[i] = hmac->ident[i];
1380  }
1381  chunklen += 4 + 2 * num;
1382  break;
1383  }
1384 
1385  case CHUNKS: {
1386  EV_INFO << "chunks parameter received\n";
1387  const struct tlv *chunks;
1388  chunks = (struct tlv *)(((unsigned char *)init_chunk) + size_init_chunk + parptr);
1389  unsigned char *cv = (unsigned char *)malloc(64);
1390  cp = (struct tlv *)((unsigned char *)cv);
1391  cp->type = chunks->type;
1392  cplen = ntohs(chunks->length);
1393  cp->length = chunks->length;
1394  int num = cplen - 4;
1395  chunk->setChunkTypesArraySize(num);
1396  for (int i = 0; i < num; i++) {
1397  chunk->setChunkTypes(i, (chunks->value[i]));
1398  cp->value[i] = chunks->value[i];
1399  }
1400  chunklen += ADD_PADDING(ntohs(parameter->length));
1401  break;
1402  }
1403 
1404  default: {
1405  EV_INFO << "ExtInterface: Unknown SCTP INIT parameter type " << paramType << "\n";
1406  uint16 skip = (paramType & 0x8000) >> 15;
1407  if (skip == 0)
1408  stopProcessing = true;
1409  uint16 report = (paramType & 0x4000) >> 14;
1410 
1411  const struct tlv *unknown;
1412  unknown = (struct tlv *)(((unsigned char *)init_chunk) + size_init_chunk + parptr);
1413 
1414  if (report != 0) {
1415  uint32 unknownLen = chunk->getUnrecognizedParametersArraySize();
1416  chunk->setUnrecognizedParametersArraySize(unknownLen + ADD_PADDING(ntohs(unknown->length)));
1417  struct data_vector *dv = (struct data_vector *)(((unsigned char *)init_chunk) + size_init_chunk + parptr);
1418 
1419  for (uint32 i = unknownLen; i < unknownLen + ADD_PADDING(ntohs(unknown->length)); i++)
1420  chunk->setUnrecognizedParameters(i, dv->data[i - unknownLen]);
1421  } else {
1422  chunklen += ADD_PADDING(ntohs(unknown->length));
1423  }
1424  EV_INFO << "stopProcessing=" << stopProcessing << " report=" << report << "\n";
1425  break;
1426  }
1427  }
1428  parptr += ADD_PADDING(ntohs(parameter->length));
1429  parcounter++;
1430  }
1431  }
1432  if (chunk->getHmacTypesArraySize() != 0) {
1433  unsigned char *vector = (unsigned char *)malloc(64);
1434  sizePeerKeyVector = rplen;
1435  memcpy(vector, rp, rplen);
1436  for (unsigned int k = 0; k < sizePeerKeyVector; k++) {
1437  peerKeyVector[k] = vector[k];
1438  }
1439  memcpy(vector, cp, cplen);
1440  for (unsigned int k = 0; k < cplen; k++) {
1441  peerKeyVector[sizePeerKeyVector + k] = vector[k];
1442  }
1443  sizePeerKeyVector += cplen;
1444  memcpy(vector, hp, hplen);
1445  for (unsigned int k = 0; k < hplen; k++) {
1446  peerKeyVector[sizePeerKeyVector + k] = vector[k];
1447  }
1448  sizePeerKeyVector += hplen;
1449  free(vector);
1450  }
1451  chunk->setBitLength(chunklen * 8);
1452  EV_INFO << "chunklen: " << chunk->getByteLength() << endl;
1453  dest->addChunk(chunk);
1454  //chunkPtr += cLen;
1455  break;
1456  }
1457 
1458  case INIT_ACK: {
1459  const struct init_ack_chunk *iac = (struct init_ack_chunk *)(chunks + chunkPtr);
1460  struct tlv *cp = nullptr;
1461  struct random_parameter *rp = nullptr;
1462  struct hmac_algo *hp = nullptr;
1463  unsigned int rplen = 0, hplen = 0, cplen = 0;
1464  chunklen = SCTP_INIT_CHUNK_LENGTH;
1465  SCTPInitAckChunk *chunk = new SCTPInitAckChunk("INIT_ACK");
1466  chunk->setChunkType(chunkType);
1467  chunk->setInitTag(ntohl(iac->initiate_tag));
1468  chunk->setA_rwnd(ntohl(iac->a_rwnd));
1469  chunk->setNoOutStreams(ntohs(iac->mos));
1470  chunk->setNoInStreams(ntohs(iac->mis));
1471  chunk->setInitTSN(ntohl(iac->initial_tsn));
1472  chunk->setUnrecognizedParametersArraySize(0);
1473  if (cLen > size_init_ack_chunk) {
1474  int32 parcounter = 0, addrcounter = 0;
1475  parptr = 0;
1476  int chkcounter = 0;
1477  bool stopProcessing = false;
1478  //sctpEV3<<"cLen="<<cLen<<"\n";
1479  while (cLen > size_init_ack_chunk + parptr && !stopProcessing) {
1480  const struct tlv *parameter = (struct tlv *)(((unsigned char *)iac) + size_init_ack_chunk + parptr);
1481  paramType = ntohs(parameter->type);
1482  //sctpEV3<<"ParamType = "<<paramType<<" parameterLength="<<ntohs(parameter->length)<<"\n";
1483 
1484  EV_INFO << "Chunklen before: " << chunklen << endl;
1485  switch (paramType) {
1486  case SUPPORTED_ADDRESS_TYPES: {
1487  const struct supported_address_types_parameter *sup_addr = (struct supported_address_types_parameter *)(((unsigned char *)iac) + size_init_ack_chunk + parptr);
1488  if (sup_addr->address_type_1 == ntohs(INIT_PARAM_IPV4) || sup_addr->address_type_2 == ntohs(INIT_PARAM_IPV4)) {
1489  chunk->setIpv4Supported(true);
1490  } else {
1491  chunk->setIpv4Supported(false);
1492  }
1493  if (sup_addr->address_type_1 == ntohs(INIT_PARAM_IPV6) || sup_addr->address_type_2 == ntohs(INIT_PARAM_IPV6)) {
1494  chunk->setIpv6Supported(true);
1495  } else {
1496  chunk->setIpv6Supported(false);
1497  }
1498  chunklen += 8;
1499  break;
1500  }
1501 
1502  case INIT_PARAM_IPV4: {
1503  EV_INFO << "parse IPv4\n";
1504  const struct init_ipv4_address_parameter *v4addr;
1505  v4addr = (struct init_ipv4_address_parameter *)(((unsigned char *)iac) + size_init_ack_chunk + parptr);
1506  chunk->setAddressesArraySize(++addrcounter);
1507  L3Address localv4Addr(IPv4Address(ntohl(v4addr->address)));
1508  chunk->setAddresses(addrcounter - 1, localv4Addr);
1509  chunklen += 8;
1510  break;
1511  }
1512 
1513  case INIT_PARAM_IPV6: {
1514  EV_INFO << "IPv6\n";
1515  const struct init_ipv6_address_parameter *ipv6addr;
1516  ipv6addr = (struct init_ipv6_address_parameter *)(((unsigned char *)iac) + size_init_chunk + parptr);
1517  IPv6Address ipv6Addr = IPv6Address(ipv6addr->address[0], ipv6addr->address[1],
1518  ipv6addr->address[2], ipv6addr->address[3]);
1519  EV_INFO << "address" << ipv6Addr << "\n";
1520  L3Address localv6Addr(ipv6Addr);
1521 
1522  chunk->setAddressesArraySize(++addrcounter);
1523  chunk->setAddresses(addrcounter - 1, localv6Addr);
1524  chunklen += 20;
1525  break;
1526  }
1527 
1528  case RANDOM: {
1529  const struct random_parameter *rand;
1530  rand = (struct random_parameter *)(((unsigned char *)iac) + size_init_ack_chunk + parptr);
1531  int rlen = ntohs(rand->length) - 4;
1532  chunk->setRandomArraySize(rlen);
1533  rp = (struct random_parameter *)((unsigned char *)malloc(64));
1534  rp->type = rand->type;
1535  rplen = ntohs(rand->length);
1536  rp->length = rand->length;
1537  for (int i = 0; i < rlen; i++) {
1538  chunk->setRandom(i, (unsigned char)(rand->random[i]));
1539  rp->random[i] = (unsigned char)(rand->random[i]);
1540  }
1541 
1542  chunklen += ntohs(parameter->length);
1543  break;
1544  }
1545 
1546  case HMAC_ALGO: {
1547  const struct hmac_algo *hmac;
1548  hmac = (struct hmac_algo *)(((unsigned char *)iac) + size_init_ack_chunk + parptr);
1549  int num = (ntohs(hmac->length) - 4) / 2;
1550  chunk->setHmacTypesArraySize(num);
1551  hp = (struct hmac_algo *)((unsigned char *)malloc(64));
1552  hp->type = hmac->type;
1553  hplen = ntohs(hmac->length);
1554  hp->length = hmac->length;
1555  for (int i = 0; i < num; i++) {
1556  chunk->setHmacTypes(i, ntohs(hmac->ident[i]));
1557  hp->ident[i] = hmac->ident[i];
1558  }
1559  chunklen += 4 + 2 * num;
1560  break;
1561  }
1562 
1563  case CHUNKS: {
1564  const struct tlv *chunks;
1565  chunks = (struct tlv *)(((unsigned char *)iac) + size_init_ack_chunk + parptr);
1566  int num = ntohs(chunks->length) - 4;
1567  chunk->setChunkTypesArraySize(num);
1568  cp = (struct tlv *)((unsigned char *)malloc(64));
1569  cp->type = chunks->type;
1570  cplen = ntohs(chunks->length);
1571  cp->length = chunks->length;
1572  for (int i = 0; i < num; i++) {
1573  chunk->setChunkTypes(i, chunks->value[i]);
1574  cp->value[i] = chunks->value[i];
1575  }
1576  chunklen += ADD_PADDING(ntohs(parameter->length));
1577  break;
1578  }
1579 
1580  case INIT_PARAM_COOKIE: {
1581  const struct tlv *cookie = (struct tlv *)(((unsigned char *)iac) + size_init_ack_chunk + parptr);
1582  int32 cookieLen = ntohs(cookie->length) - 4;
1583  // put cookie data into chunk (char array cookie)
1584  chunk->setCookieArraySize(cookieLen);
1585  for (int32 i = 0; i < cookieLen; i++)
1586  chunk->setCookie(i, cookie->value[i]);
1587  chunklen += cookieLen + 4;
1588  break;
1589  }
1590 
1591  case SUPPORTED_EXTENSIONS: {
1592  const struct supported_extensions_parameter *supext;
1593  supext = (struct supported_extensions_parameter *)(((unsigned char *)iac) + size_init_ack_chunk + parptr);
1594  unsigned short chunkTypes;
1595  //chunklen += 4;
1596  int len = 4;
1597  while (ntohs(supext->length) > len) {
1598  chunkTypes = (int)*(chunks + chunkPtr + size_init_ack_chunk + parptr + 4 + chkcounter);
1599  chunk->setSepChunksArraySize(++chkcounter);
1600  chunk->setSepChunks(chkcounter - 1, chunkTypes);
1601  //chunklen++;
1602  len++;
1603  }
1604  chunklen += ADD_PADDING(len);
1605  break;
1606  }
1607 
1609  int size = chunk->getChunkTypesArraySize();
1610  chunk->setChunkTypesArraySize(size + 1);
1611  chunk->setChunkTypes(size, FORWARD_TSN_SUPPORTED_PARAMETER);
1612  chunklen++;
1613  break;
1614  }
1615 
1616  default: {
1617  EV_INFO << "ExtInterface: Unknown SCTP INIT-ACK parameter type " << paramType << "\n";
1618  uint16 skip = (paramType & 0x8000) >> 15;
1619  if (skip == 0)
1620  stopProcessing = true;
1621  uint16 report = (paramType & 0x4000) >> 14;
1622 
1623  const struct tlv *unknown;
1624  unknown = (struct tlv *)(((unsigned char *)iac) + size_init_ack_chunk + parptr);
1625 
1626  if (report != 0) {
1627  uint32 unknownLen = chunk->getUnrecognizedParametersArraySize();
1628  chunk->setUnrecognizedParametersArraySize(unknownLen + ADD_PADDING(ntohs(unknown->length)));
1629  struct data_vector *dv = (struct data_vector *)(((unsigned char *)iac) + size_init_ack_chunk + parptr);
1630 
1631  for (uint32 i = unknownLen; i < unknownLen + ADD_PADDING(ntohs(unknown->length)); i++)
1632  chunk->setUnrecognizedParameters(i, dv->data[i - unknownLen]);
1633  } else {
1634  chunklen += ADD_PADDING(ntohs(unknown->length));
1635  }
1636  EV_INFO << "stopProcessing=" << stopProcessing << " report=" << report << "\n";
1637 
1638  break;
1639  }
1640  }
1641  EV_INFO << "Chunklen after: " << chunklen << endl;
1642  parptr += ADD_PADDING(ntohs(parameter->length));
1643  //sctpEV3<<"parptr="<<parptr<<"\n";
1644  parcounter++;
1645  }
1646  }
1647  if (chunk->getHmacTypesArraySize() != 0) {
1648  unsigned char vector[64];
1649  if (rplen > 64) {
1650  EV_ERROR << "Random parameter too long. It will be truncated.\n";
1651  rplen = 64;
1652  }
1653  sizePeerKeyVector = rplen;
1654  memcpy(vector, rp, rplen);
1655  for (unsigned int k = 0; k < sizePeerKeyVector; k++) {
1656  peerKeyVector[k] = vector[k];
1657  }
1658  free(rp);
1659  if (cplen > 64) {
1660  EV_ERROR << "Chunks parameter too long. It will be truncated.\n";
1661  cplen = 64;
1662  }
1663  memcpy(vector, cp, cplen);
1664  for (unsigned int k = 0; k < cplen; k++) {
1665  peerKeyVector[sizePeerKeyVector + k] = vector[k];
1666  }
1667  free(cp);
1668  sizePeerKeyVector += cplen;
1669  if (hplen > 64) {
1670  EV_ERROR << "HMac parameter too long. It will be truncated.\n";
1671  hplen = 64;
1672  }
1673  memcpy(vector, hp, hplen);
1674  for (unsigned int k = 0; k < hplen; k++) {
1675  peerKeyVector[sizePeerKeyVector + k] = vector[k];
1676  }
1677  free(hp);
1678  sizePeerKeyVector += hplen;
1680  }
1681  chunk->setBitLength(chunklen * 8);
1682  dest->addChunk(chunk);
1683  break;
1684  }
1685 
1686  case SACK: {
1687  EV << "SCTPMessage: SACK received\n";
1688  const struct sack_chunk *sac = (struct sack_chunk *)(chunks + chunkPtr);
1689  SCTPSackChunk *chunk = new SCTPSackChunk("SACK");
1690  chunk->setChunkType(chunkType);
1691  uint32 cumtsnack = ntohl(sac->cum_tsn_ack);
1692  chunk->setCumTsnAck(cumtsnack);
1693  chunk->setA_rwnd(ntohl(sac->a_rwnd));
1694 
1695  int32 ngaps = ntohs(sac->nr_of_gaps);
1696  int32 ndups = ntohs(sac->nr_of_dups);
1697  chunk->setNumGaps(ngaps);
1698  chunk->setNumDupTsns(ndups);
1699 
1700  chunk->setGapStartArraySize(ngaps);
1701  chunk->setGapStopArraySize(ngaps);
1702  chunk->setDupTsnsArraySize(ndups);
1703 
1704  for (int32 i = 0; i < ngaps; i++) {
1705  const struct sack_gap *gap = (struct sack_gap *)(((unsigned char *)sac) + size_sack_chunk + i * sizeof(sack_gap));
1706  chunk->setGapStart(i, ntohs(gap->start) + cumtsnack);
1707  chunk->setGapStop(i, ntohs(gap->stop) + cumtsnack);
1708  }
1709  for (int32 i = 0; i < ndups; i++) {
1710  const struct sack_duptsn *dup = (struct sack_duptsn *)(((unsigned char *)sac) + size_sack_chunk + ngaps * sizeof(sack_gap) + i * sizeof(sack_duptsn));
1711  chunk->setDupTsns(i, ntohl(dup->tsn));
1712  }
1713 
1714  chunk->setBitLength(cLen * 8);
1715  dest->addChunk(chunk);
1716  break;
1717  }
1718 
1719  case HEARTBEAT: {
1720  //sctpEV3<<"SCTPMessage: Heartbeat received\n";
1721  const struct heartbeat_chunk *hbc = (struct heartbeat_chunk *)(chunks + chunkPtr);
1722  SCTPHeartbeatChunk *chunk = new SCTPHeartbeatChunk("HEARTBEAT");
1723  chunk->setChunkType(chunkType);
1724  if (cLen > size_heartbeat_chunk) {
1725  int32 parcounter = 0;
1726  parptr = 0;
1727  while (cLen > size_heartbeat_chunk + parptr) {
1728  // we supppose type 1 here
1729  //sctpEV3<<"HB-chunk+parptr="<<size_heartbeat_chunk+parptr<<"\n";
1730  const struct heartbeat_info *hbi = (struct heartbeat_info *)(((unsigned char *)hbc) + size_heartbeat_chunk + parptr);
1731  if (ntohs(hbi->type) == 1) { // sender specific hb info
1732  //sctpEV3<<"HBInfo\n";
1733  int32 infoLen = ntohs(hbi->length) - 4;
1734  parptr += ADD_PADDING(infoLen) + 4;
1735  parcounter++;
1736  chunk->setInfoArraySize(infoLen);
1737  for (int32 i = 0; i < infoLen; i++)
1738  chunk->setInfo(i, HBI_INFO(hbi)[i]);
1739  }
1740  else {
1741  parptr += ADD_PADDING(ntohs(hbi->length)); // set pointer forwards with count of bytes in length field of TLV
1742  parcounter++;
1743  continue;
1744  }
1745  }
1746  }
1747  chunk->setBitLength(cLen * 8);
1748  dest->addChunk(chunk);
1749  break;
1750  }
1751 
1752  case HEARTBEAT_ACK: {
1753  EV << "SCTPMessage: Heartbeat_Ack received\n";
1754  const struct heartbeat_ack_chunk *hbac = (struct heartbeat_ack_chunk *)(chunks + chunkPtr);
1755  SCTPHeartbeatAckChunk *chunk = new SCTPHeartbeatAckChunk("HEARTBEAT_ACK");
1756  chunk->setChunkType(chunkType);
1757  if (cLen > size_heartbeat_ack_chunk) {
1758  int32 parcounter = 0;
1759  parptr = 0;
1760  while (cLen > size_heartbeat_ack_chunk + parptr) {
1761  // we supppose type 1 here, the same provided in heartbeat chunks
1762  const struct heartbeat_info *hbi = (struct heartbeat_info *)(((unsigned char *)hbac) + size_heartbeat_ack_chunk + parptr);
1763  if (ntohs(hbi->type) == 1) { // sender specific hb info
1764  uint16 ilen = ntohs(hbi->length);
1765  ASSERT(ilen >= 4 && ilen == cLen - size_heartbeat_ack_chunk);
1766  uint16 infoLen = ilen - 4;
1767  parptr += ADD_PADDING(infoLen) + 4;
1768  parcounter++;
1769  chunk->setRemoteAddr(L3Address(IPv4Address(ntohl(HBI_ADDR(hbi).v4addr.address))));
1770  chunk->setTimeField(ntohl((uint32)HBI_TIME(hbi)));
1771  chunk->setInfoArraySize(infoLen);
1772  for (int32 i = 0; i < infoLen; i++)
1773  chunk->setInfo(i, HBI_INFO(hbi)[i]);
1774  }
1775  else {
1776  parptr += ntohs(hbi->length); // set pointer forwards with count of bytes in length field of TLV
1777  parcounter++;
1778  continue;
1779  }
1780  }
1781  }
1782  chunk->setBitLength(cLen * 8);
1783  dest->addChunk(chunk);
1784  break;
1785  }
1786 
1787  case ABORT: {
1788  EV << "SCTPMessage: Abort received\n";
1789  const struct abort_chunk *ac = (struct abort_chunk *)(chunks + chunkPtr);
1790  cLen = ntohs(ac->length);
1791  SCTPAbortChunk *chunk = new SCTPAbortChunk("ABORT");
1792  chunk->setChunkType(chunkType);
1793  chunk->setT_Bit(ac->flags & T_BIT);
1794  if (cLen > size_abort_chunk) {
1795  // TODO: handle attached error causes
1796  }
1797  chunk->setBitLength(cLen * 8);
1798  dest->addChunk(chunk);
1799  break;
1800  }
1801 
1802  case COOKIE_ECHO: {
1803  SCTPCookieEchoChunk *chunk = new SCTPCookieEchoChunk("COOKIE_ECHO");
1804  chunk->setChunkType(chunkType);
1805  EV_INFO << "Parse Cookie-Echo\n";
1806  if (cLen > size_cookie_echo_chunk) {
1807  int32 cookieSize = woPadding - size_cookie_echo_chunk;
1808  EV_DETAIL << "cookieSize=" << cookieSize << "\n";
1809  const struct cookie_parameter *cookie = (struct cookie_parameter *)(chunks + chunkPtr + 4);
1810  SCTPCookie *stateCookie = new SCTPCookie();
1811  stateCookie->setCreationTime(ntohl(cookie->creationTime));
1812  stateCookie->setLocalTag(ntohl(cookie->localTag));
1813  stateCookie->setPeerTag(ntohl(cookie->peerTag));
1814  stateCookie->setLocalTieTagArraySize(32);
1815  stateCookie->setPeerTieTagArraySize(32);
1816  for (int32 i = 0; i < 32; i++) {
1817  stateCookie->setLocalTieTag(i, cookie->localTieTag[i]);
1818  stateCookie->setPeerTieTag(i, cookie->peerTieTag[i]);
1819  }
1820  stateCookie->setBitLength(SCTP_COOKIE_LENGTH * 8);
1821  chunk->setStateCookie(stateCookie);
1822  }
1823  chunk->setBitLength(woPadding * 8);
1824  dest->addChunk(chunk);
1825  break;
1826  }
1827 
1828  case COOKIE_ACK: {
1829  EV << "SCTPMessage: Cookie_Ack received\n";
1830  SCTPCookieAckChunk *chunk = new SCTPCookieAckChunk("COOKIE_ACK");
1831  chunk->setChunkType(chunkType);
1832  chunk->setBitLength(cLen * 8);
1833  dest->addChunk(chunk);
1834  break;
1835  }
1836 
1837  case SHUTDOWN: {
1838  EV << "SCTPMessage: Shutdown received\n";
1839  const struct shutdown_chunk *sc = (struct shutdown_chunk *)(chunks + chunkPtr);
1840  SCTPShutdownChunk *chunk = new SCTPShutdownChunk("SHUTDOWN");
1841  chunk->setChunkType(chunkType);
1842  uint32 cumtsnack = ntohl(sc->cumulative_tsn_ack);
1843  chunk->setCumTsnAck(cumtsnack);
1844  chunk->setBitLength(cLen * 8);
1845  dest->addChunk(chunk);
1846  break;
1847  }
1848 
1849  case SHUTDOWN_ACK: {
1850  EV << "SCTPMessage: ShutdownAck received\n";
1851  SCTPShutdownAckChunk *chunk = new SCTPShutdownAckChunk("SHUTDOWN_ACK");
1852  chunk->setChunkType(chunkType);
1853  chunk->setBitLength(cLen * 8);
1854  dest->addChunk(chunk);
1855  break;
1856  }
1857 
1858  case SHUTDOWN_COMPLETE: {
1859  EV << "SCTPMessage: ShutdownComplete received\n";
1860  const struct shutdown_complete_chunk *scc = (struct shutdown_complete_chunk *)(chunks + chunkPtr);
1861  SCTPShutdownCompleteChunk *chunk = new SCTPShutdownCompleteChunk("SHUTDOWN_COMPLETE");
1862  chunk->setChunkType(chunkType);
1863  chunk->setTBit(scc->flags & T_BIT);
1864  chunk->setBitLength(cLen * 8);
1865  dest->addChunk(chunk);
1866  break;
1867  }
1868 
1869  case ERRORTYPE: {
1870  const struct error_chunk *error;
1871  error = (struct error_chunk *)(chunks + chunkPtr);
1872  SCTPErrorChunk *errorchunk;
1873  errorchunk = new SCTPErrorChunk("ERROR");
1874  errorchunk->setChunkType(chunkType);
1875  errorchunk->setBitLength(SCTP_ERROR_CHUNK_LENGTH * 8);
1876  parptr = 0;
1877  const struct error_cause *err = (struct error_cause *)(((unsigned char *)error) + size_error_chunk + parptr);
1878  if (err->cause_code == UNSUPPORTED_HMAC) {
1879  SCTPSimpleErrorCauseParameter *errParam;
1880  errParam = new SCTPSimpleErrorCauseParameter();
1881  errParam->setParameterType(err->cause_code);
1882  errParam->setByteLength(err->length);
1883  errorchunk->addParameters(errParam);
1884  }
1885  dest->addChunk(errorchunk);
1886  break;
1887  }
1888 
1889  case FORWARD_TSN: {
1890  EV << "SCTPMessage: ForwardTsn received" << endl;
1891  const struct forward_tsn_chunk *forward_tsn_chunk;
1892  forward_tsn_chunk = (struct forward_tsn_chunk *)(chunks + chunkPtr);
1893  SCTPForwardTsnChunk *chunk;
1894  chunk = new SCTPForwardTsnChunk("FORWARD_TSN");
1895  chunk->setChunkType(chunkType);
1896  chunk->setName("FORWARD_TSN");
1897  chunk->setNewCumTsn(ntohl(forward_tsn_chunk->cum_tsn));
1898  int streamNumber = 0, streamptr = 0;
1899  while (cLen > size_forward_tsn_chunk + streamptr) {
1900  const struct forward_tsn_streams *forward = (struct forward_tsn_streams *)(((unsigned char *)forward_tsn_chunk) + size_forward_tsn_chunk + streamptr);
1901  chunk->setSidArraySize(++streamNumber);
1902  chunk->setSid(streamNumber - 1, ntohs(forward->sid));
1903  chunk->setSsnArraySize(streamNumber);
1904  chunk->setSsn(streamNumber - 1, ntohs(forward->ssn));
1905  streamptr += sizeof(struct forward_tsn_streams);
1906  }
1907  chunk->setByteLength(cLen);
1908  dest->addChunk(chunk);
1909  break;
1910  }
1911 
1912  case AUTH: {
1913  int hmacSize;
1914  struct auth_chunk *ac = (struct auth_chunk *)(chunks + chunkPtr);
1915  SCTPAuthenticationChunk *chunk = new SCTPAuthenticationChunk("AUTH");
1916  chunk->setChunkType(chunkType);
1917  chunk->setSharedKey(ntohs(ac->shared_key));
1918  chunk->setHMacIdentifier(ntohs(ac->hmac_identifier));
1919  if (cLen > size_auth_chunk) {
1920  hmacSize = woPadding - size_auth_chunk;
1921  chunk->setHMACArraySize(hmacSize);
1922  for (int i = 0; i < hmacSize; i++) {
1923  chunk->setHMAC(i, ac->hmac[i]);
1924  ac->hmac[i] = 0;
1925  }
1926  }
1927 
1928  unsigned char result[SHA_LENGTH];
1929  unsigned int flen;
1930  flen = bufsize - (size_common_header + chunkPtr);
1931 
1932  const struct data_vector *sc = (struct data_vector *)(chunks + chunkPtr);
1933  hmacSha1((uint8 *)sc->data, flen, sharedKey, sizeKeyVector + sizePeerKeyVector, result);
1934 
1935  chunk->setHMacOk(true);
1936  for (unsigned int j = 0; j < SHA_LENGTH; j++) {
1937  if (result[j] != chunk->getHMAC(j)) {
1938  EV_DETAIL << "hmac falsch\n";
1939  chunk->setHMacOk(false);
1940  break;
1941  }
1942  }
1943  chunk->setByteLength(woPadding);
1944  dest->addChunk(chunk);
1945  break;
1946  }
1947 
1948  case ASCONF: {
1949  const struct asconf_chunk *asconf_chunk = (struct asconf_chunk *)(chunks + chunkPtr); // (recvBuffer + size_ip + size_common_header);
1950  int paramLength = 0;
1951  SCTPAsconfChunk *chunk = new SCTPAsconfChunk("ASCONF");
1952  chunk->setChunkType(chunkType);
1953  chunk->setName("ASCONF");
1954  chunk->setSerialNumber(ntohl(asconf_chunk->serial));
1955  if (cLen > size_asconf_chunk) {
1956  int parcounter = 0;
1957  parptr = 0;
1958  // we supppose an ipv4 address parameter
1959  const struct init_ipv4_address_parameter *ipv4addr = (struct init_ipv4_address_parameter *)(((unsigned char *)asconf_chunk) + size_asconf_chunk + parptr);
1960  int parlen = ADD_PADDING(ntohs(ipv4addr->length));
1961  parptr += parlen;
1962  // set pointer forwards with count of bytes in length field of TLV
1963  parcounter++;
1964  if (ntohs(ipv4addr->type) != INIT_PARAM_IPV4) {
1965  if (parlen == 0)
1966  throw new cRuntimeError("ParamLen == 0.");
1967  continue;
1968  }
1969  else {
1970  L3Address localAddr(IPv4Address(ntohl(ipv4addr->address)));
1971  chunk->setAddressParam(localAddr);
1972  }
1973  while (cLen > size_asconf_chunk + parptr) {
1974  const struct add_ip_parameter *ipparam = (struct add_ip_parameter *)(((unsigned char *)asconf_chunk) + size_asconf_chunk + parptr);
1975  paramType = ntohs(ipparam->type);
1976  paramLength = ntohs(ipparam->length);
1977  switch (paramType) {
1978  case ADD_IP_ADDRESS: {
1979  EV_INFO << "parse ADD_IP_ADDRESS\n";
1980  SCTPAddIPParameter *addip;
1981  addip = new SCTPAddIPParameter("ADD_IP");
1982  addip->setParameterType(ntohs(ipparam->type));
1983  addip->setRequestCorrelationId(ntohl(ipparam->correlation_id));
1984  const struct init_ipv4_address_parameter *v4addr1;
1985  v4addr1 = (struct init_ipv4_address_parameter *)(((unsigned char *)asconf_chunk) + size_asconf_chunk + parptr + size_addip_parameter);
1986  L3Address localAddr(IPv4Address(ntohl(v4addr1->address)));
1987  addip->setAddressParam(localAddr);
1988  chunk->addAsconfParam(addip);
1989  break;
1990  }
1991 
1992  case DELETE_IP_ADDRESS: {
1993  EV_INFO << "parse DELETE_IP_ADDRESS\n";
1994  SCTPDeleteIPParameter *deleteip;
1995  deleteip = new SCTPDeleteIPParameter("DELETE_IP");
1996  deleteip->setParameterType(ntohs(ipparam->type));
1997  deleteip->setRequestCorrelationId(ntohl(ipparam->correlation_id));
1998  const struct init_ipv4_address_parameter *v4addr2;
1999  v4addr2 = (struct init_ipv4_address_parameter *)(((unsigned char *)asconf_chunk) + size_asconf_chunk + parptr + size_addip_parameter);
2000  L3Address localAddr(IPv4Address(ntohl(v4addr2->address)));
2001  deleteip->setAddressParam(localAddr);
2002  chunk->addAsconfParam(deleteip);
2003  break;
2004  }
2005 
2006  case SET_PRIMARY_ADDRESS: {
2007  EV_INFO << "parse SET_PRIMARY_ADDRESS\n";
2008  SCTPSetPrimaryIPParameter *priip;
2009  priip = new SCTPSetPrimaryIPParameter("SET_PRI_IP");
2010  priip->setParameterType(ntohs(ipparam->type));
2011  priip->setRequestCorrelationId(ntohl(ipparam->correlation_id));
2012  const struct init_ipv4_address_parameter *v4addr3;
2013  v4addr3 = (struct init_ipv4_address_parameter *)(((unsigned char *)asconf_chunk) + size_asconf_chunk + parptr + size_addip_parameter);
2014  L3Address localAddr(IPv4Address(ntohl(v4addr3->address)));
2015  priip->setAddressParam(localAddr);
2016  chunk->addAsconfParam(priip);
2017  break;
2018  }
2019 
2020  default:
2021  printf("TODO: Implement parameter type %d!\n", paramType);
2022  EV << "ExtInterface: Unknown SCTP parameter type " << paramType;
2023  /*throw new cRuntimeError("TODO: unknown parametertype in incoming packet from external interface! Implement it!");*/
2024  break;
2025  }
2026  parptr += ADD_PADDING(paramLength);
2027  parcounter++;
2028  }
2029  }
2030  chunk->setByteLength(cLen);
2031  dest->addChunk(chunk);
2032  break;
2033  }
2034 
2035  case ASCONF_ACK: {
2036  const struct asconf_ack_chunk *asconf_ack_chunk = (struct asconf_ack_chunk *)(chunks + chunkPtr); // (recvBuffer + size_ip + size_common_header);
2037  int paramLength = 0;
2038  SCTPAsconfAckChunk *chunk = new SCTPAsconfAckChunk("ASCONF_ACK");
2039  chunk->setChunkType(chunkType);
2040  chunk->setName("ASCONF_ACK");
2041  chunk->setSerialNumber(ntohl(asconf_ack_chunk->serial));
2042  if (cLen > size_asconf_ack_chunk) {
2043  int parcounter = 0;
2044  parptr = 0;
2045 
2046  while (cLen > size_asconf_ack_chunk + parptr) {
2047  const struct add_ip_parameter *ipparam = (struct add_ip_parameter *)(((unsigned char *)asconf_ack_chunk) + size_asconf_ack_chunk + parptr);
2048  paramType = ntohs(ipparam->type);
2049  paramLength = ntohs(ipparam->length);
2050  switch (paramType) {
2051  case ERROR_CAUSE_INDICATION: {
2052  SCTPErrorCauseParameter *errorip;
2053  errorip = new SCTPErrorCauseParameter("ERROR_CAUSE");
2054  errorip->setParameterType(ntohs(ipparam->type));
2055  errorip->setResponseCorrelationId(ntohl(ipparam->correlation_id));
2056  const struct error_cause *errorcause;
2057  errorcause = (struct error_cause *)(((unsigned char *)asconf_ack_chunk) + size_asconf_ack_chunk + parptr + size_addip_parameter);
2058  errorip->setErrorCauseType(htons(errorcause->cause_code));
2059  chunk->addAsconfResponse(errorip);
2060  break;
2061  }
2062 
2063  case SUCCESS_INDICATION: {
2064  SCTPSuccessIndication *success;
2065  success = new SCTPSuccessIndication("SUCCESS");
2066  success->setParameterType(ntohs(ipparam->type));
2067  success->setResponseCorrelationId(ntohl(ipparam->correlation_id));
2068  chunk->addAsconfResponse(success);
2069  break;
2070  }
2071 
2072  default:
2073  printf("TODO: Implement parameter type %d!\n", paramType);
2074  EV << "ExtInterface: Unknown SCTP parameter type " << paramType;
2075  break;
2076  }
2077  parptr += ADD_PADDING(paramLength);
2078  parcounter++;
2079  }
2080  }
2081  chunk->setByteLength(cLen);
2082  dest->addChunk(chunk);
2083  break;
2084  }
2085 
2086  case RE_CONFIG: {
2087  const struct stream_reset_chunk *stream_reset_chunk;
2088  stream_reset_chunk = (struct stream_reset_chunk *)(chunks + chunkPtr);
2089  SCTPStreamResetChunk *chunk;
2090  chunk = new SCTPStreamResetChunk("RE_CONFIG");
2091  chunk->setChunkType(chunkType);
2092  chunk->setName("RE_CONFIG");
2093  chunk->setByteLength(SCTP_STREAM_RESET_CHUNK_LENGTH);
2094  chunklen = SCTP_STREAM_RESET_CHUNK_LENGTH;
2095  int len;
2096  if ((unsigned int)cLen > sizeof(struct stream_reset_chunk)) {
2097  parptr = 0;
2098  int parcounter = 0;
2099  int snnumbers, sncounter;
2100  while (cLen > size_stream_reset_chunk + parptr) {
2101  const struct tlv *parameter = (struct tlv *)(((unsigned char *)stream_reset_chunk) + size_stream_reset_chunk + parptr);
2102  paramType = ntohs(parameter->type);
2103  int paramLength = ntohs(parameter->length);
2104  switch (paramType) {
2106  const struct outgoing_reset_request_parameter *outrr;
2107  outrr = (struct outgoing_reset_request_parameter *)(((unsigned char *)stream_reset_chunk) + size_stream_reset_chunk + parptr);
2108  SCTPOutgoingSSNResetRequestParameter *outstrrst;
2109  outstrrst = new SCTPOutgoingSSNResetRequestParameter("OUT_STR_RST");
2110  outstrrst->setParameterType(OUTGOING_RESET_REQUEST_PARAMETER);
2111  outstrrst->setSrReqSn(ntohl(outrr->srReqSn)); //Stream Reset Request Sequence Number
2112  outstrrst->setSrResSn(ntohl(outrr->srResSn)); //Stream Reset Response Sequence Number
2113  outstrrst->setLastTsn(ntohl(outrr->lastTsn)); //Senders last assigned TSN
2116  sncounter = 0;
2117  while (ntohs(outrr->length) > len) {
2118  snnumbers = (int)*(chunks + chunkPtr + size_stream_reset_chunk + parptr + SCTP_OUTGOING_RESET_REQUEST_PARAMETER_LENGTH + sncounter * 2);
2119  outstrrst->setStreamNumbersArraySize(++sncounter);
2120  outstrrst->setStreamNumbers(sncounter - 1, snnumbers);
2121  chunklen += 2;
2122  len += 2;
2123  }
2124  chunk->addParameter(outstrrst);
2125  break;
2126  }
2127 
2129  const struct incoming_reset_request_parameter *inrr;
2130  inrr = (struct incoming_reset_request_parameter *)(((unsigned char *)stream_reset_chunk) + size_stream_reset_chunk + parptr);
2131  SCTPIncomingSSNResetRequestParameter *instrrst;
2132  instrrst = new SCTPIncomingSSNResetRequestParameter("IN_STR_RST");
2133  instrrst->setParameterType(INCOMING_RESET_REQUEST_PARAMETER);
2134  instrrst->setSrReqSn(ntohl(inrr->srReqSn)); //Stream Reset Request Sequence Number
2137  sncounter = 0;
2138  while (ntohs(inrr->length) > len) {
2139  snnumbers = (int)*(chunks + chunkPtr + size_stream_reset_chunk + parptr + SCTP_OUTGOING_RESET_REQUEST_PARAMETER_LENGTH + sncounter * 2);
2140  instrrst->setStreamNumbersArraySize(++sncounter);
2141  instrrst->setStreamNumbers(sncounter - 1, snnumbers);
2142  chunklen += 2;
2143  len += 2;
2144  }
2145  chunk->addParameter(instrrst);
2146  break;
2147  }
2148 
2150  const struct ssn_tsn_reset_request_parameter *ssnrr;
2151  ssnrr = (struct ssn_tsn_reset_request_parameter *)(((unsigned char *)stream_reset_chunk) + size_stream_reset_chunk + parptr);
2152  SCTPSSNTSNResetRequestParameter *ssnstrrst;
2153  ssnstrrst = new SCTPSSNTSNResetRequestParameter("SSN_STR_RST");
2154  ssnstrrst->setParameterType(SSN_TSN_RESET_REQUEST_PARAMETER);
2155  ssnstrrst->setSrReqSn(ntohl(ssnrr->srReqSn));
2157  chunk->addParameter(ssnstrrst);
2158  break;
2159  }
2160 
2162  const struct stream_reset_response_parameter *resp;
2163  resp = (struct stream_reset_response_parameter *)(((unsigned char *)stream_reset_chunk) + size_stream_reset_chunk + parptr);
2164  SCTPStreamResetResponseParameter *strrst;
2165  strrst = new SCTPStreamResetResponseParameter("STR_RST_RESPONSE");
2166  strrst->setParameterType(STREAM_RESET_RESPONSE_PARAMETER);
2167  strrst->setSrResSn(ntohl(resp->srResSn));
2168  strrst->setResult(ntohl(resp->result));
2170  if (cLen > size_stream_reset_chunk + parptr + SCTP_STREAM_RESET_RESPONSE_PARAMETER_LENGTH) {
2171  strrst->setSendersNextTsn(ntohl(resp->sendersNextTsn));
2172  strrst->setReceiversNextTsn(ntohl(resp->receiversNextTsn));
2173  pLen += 8;
2174  }
2175  strrst->setByteLength(pLen);
2176  chunk->addParameter(strrst);
2177  break;
2178  }
2179  }
2180  parptr += ADD_PADDING(paramLength);
2181  parcounter++;
2182  }
2183  }
2184  chunk->setByteLength(cLen);
2185  dest->addChunk(chunk);
2186  break;
2187  }
2188 
2189  case PKTDROP: {
2190  const struct pktdrop_chunk *drop;
2191  drop = (struct pktdrop_chunk *)(chunks + chunkPtr);
2192  SCTPPacketDropChunk *dropChunk;
2193  dropChunk = new SCTPPacketDropChunk("PKTDROP");
2194  dropChunk->setChunkType(PKTDROP);
2195  dropChunk->setCFlag(drop->flags & C_FLAG);
2196  dropChunk->setTFlag(drop->flags & T_FLAG);
2197  dropChunk->setBFlag(drop->flags & B_FLAG);
2198  dropChunk->setMFlag(drop->flags & M_FLAG);
2199  dropChunk->setMaxRwnd(ntohl(drop->max_rwnd));
2200  dropChunk->setQueuedData(ntohl(drop->queued_data));
2201  dropChunk->setTruncLength(ntohs(drop->trunc_length));
2202  EV_INFO << "SCTPSerializer::pktdrop: parse SCTPMessage\n";
2203  SCTPMessage *msg;
2204  msg = new SCTPMessage();
2205  parse((unsigned char *)chunks + chunkPtr + 16, bufsize - size_common_header - chunkPtr - 16, msg);
2206  break;
2207  }
2208 
2209  default:
2210  //printf("TODO: Implement chunk type %d, found in chunk array on %d!\n", chunkType, ct);
2211  EV_ERROR << "Parser: Unknown SCTP chunk type " << chunkType;
2212  break;
2213  } // end of switch(chunkType)
2214  chunkPtr += cLen;
2215  } // end of while()
2216  EV_INFO << "SCTPSerializer - pkt info - " << dest->getByteLength() << " bytes" << endl;
2217 }
#define M_FLAG
Definition: sctphdr.h:40
uint8_t uint8
Definition: Compat.h:34
#define INIT_PARAM_IPV4
Definition: sctphdr.h:319
static unsigned int sizePeerKeyVector
Definition: SCTPSerializer.h:62
Definition: SCTPAssociation.h:172
void parse(const uint8 *buf, uint32 bufsize, sctp::SCTPMessage *dest)
Puts a packet sniffed from the wire into an SCTPMessage.
Definition: SCTPSerializer.cc:1166
#define SCTP_SSN_TSN_RESET_REQUEST_PARAMETER_LENGTH
Definition: SCTPAssociation.h:227
Definition: SCTPAssociation.h:111
Definition: SCTPAssociation.h:191
#define SCTP_INCOMING_RESET_REQUEST_PARAMETER_LENGTH
Definition: SCTPAssociation.h:226
#define T_FLAG
Definition: sctphdr.h:38
u16_t ntohs(u16_t n)
Definition: SCTPAssociation.h:127
Definition: SCTPAssociation.h:118
Definition: SCTPAssociation.h:119
Definition: SCTPAssociation.h:121
#define HBI_ADDR(hbi)
Definition: sctphdr.h:429
uint16_t len
Definition: TCP_NSC.cc:85
#define SCTP_DATA_CHUNK_LENGTH
Definition: SCTPAssociation.h:214
#define BEGIN_BIT
Definition: sctphdr.h:34
Definition: SCTPAssociation.h:182
#define SCTP_STREAM_RESET_CHUNK_LENGTH
Definition: SCTPAssociation.h:224
#define SHA_LENGTH
Definition: SCTPAssociation.h:235
#define SCTP_ERROR_CHUNK_LENGTH
Definition: SCTPAssociation.h:223
Definition: SCTPAssociation.h:122
#define C_FLAG
Definition: sctphdr.h:37
Definition: SCTPAssociation.h:115
Definition: SCTPAssociation.h:170
static uint32 checksum(const uint8 *buf, register uint32 len)
Definition: SCTPSerializer.cc:1148
Definition: SCTPAssociation.h:116
Definition: SCTPAssociation.h:183
Definition: SCTPAssociation.h:168
Definition: SCTPAssociation.h:159
Definition: SCTPAssociation.h:130
#define SCTP_COMMON_HEADER
Definition: SCTPAssociation.h:212
u32_t ntohl(u32_t n)
void * malloc(YYSIZE_T)
static unsigned char sharedKey[512]
Definition: SCTPSerializer.h:63
#define ADD_PADDING(x)
Definition: SCTPAssociation.h:261
Definition: SCTPAssociation.h:185
u16_t htons(u16_t n)
#define SCTP_STREAM_RESET_RESPONSE_PARAMETER_LENGTH
Definition: SCTPAssociation.h:228
#define INIT_PARAM_COOKIE
Definition: sctphdr.h:321
#define SCTP_INIT_CHUNK_LENGTH
Definition: SCTPAssociation.h:213
#define T_BIT
Definition: sctphdr.h:36
static unsigned int sizeKeyVector
Definition: SCTPSerializer.h:60
static unsigned char peerKeyVector[512]
Definition: SCTPSerializer.h:61
void calculateSharedKey()
Definition: SCTPSerializer.cc:2241
Definition: SCTPAssociation.h:124
Definition: SCTPAssociation.h:156
Definition: SCTPAssociation.h:128
#define HBI_INFO(hbi)
Definition: sctphdr.h:428
Definition: SCTPAssociation.h:171
#define INIT_PARAM_IPV6
Definition: sctphdr.h:320
Definition: SCTPAssociation.h:112
#define SCTP_COOKIE_LENGTH
Definition: SCTPAssociation.h:241
#define SCTP_OUTGOING_RESET_REQUEST_PARAMETER_LENGTH
Definition: SCTPAssociation.h:225
Definition: SCTPAssociation.h:157
int32_t int32
Definition: Compat.h:31
uint32_t uint32
Definition: Compat.h:30
Definition: SCTPAssociation.h:181
Definition: SCTPAssociation.h:114
#define I_BIT
Definition: sctphdr.h:32
Definition: SCTPAssociation.h:158
Definition: SCTPAssociation.h:129
Definition: SCTPAssociation.h:120
#define HBI_TIME(hbi)
Definition: sctphdr.h:430
Definition: SCTPAssociation.h:117
void free(void *)
Definition: SCTPAssociation.h:126
uint16_t uint16
Definition: Compat.h:32
#define UNORDERED_BIT
Definition: sctphdr.h:33
Definition: SCTPAssociation.h:113
const double k
Definition: QAM16Modulation.cc:24
#define END_BIT
Definition: sctphdr.h:35
Definition: SCTPAssociation.h:184
Definition: SCTPAssociation.h:174
static void hmacSha1(const uint8 *buf, uint32 buflen, const uint8 *key, uint32 keylen, uint8 *digest)
Definition: SCTPSerializer.cc:1140
Definition: SCTPAssociation.h:173
#define B_FLAG
Definition: sctphdr.h:39
Definition: SCTPAssociation.h:123
void inet::serializer::SCTPSerializer::serialize ( const cPacket *  pkt,
Buffer b,
Context context 
)
overrideprotectedvirtual

Serializes a cPacket for transmission on the wire.

Returns the length of data written into buffer.

Implements inet::serializer::SerializerBase.

Referenced by deserialize().

62 {
63  int32 len = serialize(check_and_cast<const SCTPMessage *>(pkt), static_cast<unsigned char *>(b.accessNBytes(0)), b.getRemainingSize());
64  b.accessNBytes(len);
65 }
uint16_t len
Definition: TCP_NSC.cc:85
virtual void serialize(const cPacket *pkt, Buffer &b, Context &context) override
Serializes a cPacket for transmission on the wire.
Definition: SCTPSerializer.cc:61
int32_t int32
Definition: Compat.h:31
value< double, units::m > b
Definition: Units.h:1054
int32 inet::serializer::SCTPSerializer::serialize ( const sctp::SCTPMessage msg,
uint8 buf,
uint32  bufsize 
)

Serializes an SCTPMessage for transmission on the wire.

The checksum is NOT filled in. (The kernel does that when sending the frame over a raw socket.) Returns the length of data written into buffer.

Member Data Documentation

unsigned char inet::serializer::SCTPSerializer::keyVector
staticprivate
unsigned char inet::serializer::SCTPSerializer::peerKeyVector
staticprivate
unsigned char inet::serializer::SCTPSerializer::sharedKey
staticprivate
unsigned int inet::serializer::SCTPSerializer::sizeKeyVector = 0
staticprivate
unsigned int inet::serializer::SCTPSerializer::sizePeerKeyVector = 0
staticprivate

The documentation for this class was generated from the following files: