@ingroup packet_parser * @brief AddGlobalIPAddresses from Init,InitAck,or AddIP packets * * AddGlobalIPAddresses scans an SCTP chunk (in sm) for Global IP addresses, and * adds them. * * @param sm Pointer to sctp message information * @param assoc Pointer to the association this SCTP Message belongs to * @param direction SN_TO_LOCAL | SN_TO_GLOBAL * */
| 1324 | * |
| 1325 | */ |
| 1326 | static void |
| 1327 | AddGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int direction) |
| 1328 | { |
| 1329 | struct sctp_ipv4addr_param *ipv4_param; |
| 1330 | struct sctp_paramhdr *param = NULL; |
| 1331 | struct sctp_GlobalAddress *G_Addr; |
| 1332 | struct in_addr g_addr = {0}; |
| 1333 | int bytes_left = 0; |
| 1334 | int param_size; |
| 1335 | int param_count, addr_param_count = 0; |
| 1336 | |
| 1337 | switch (direction) { |
| 1338 | case SN_TO_GLOBAL: /* does not contain global addresses */ |
| 1339 | g_addr = sm->ip_hdr->ip_dst; |
| 1340 | bytes_left = 0; /* force exit */ |
| 1341 | break; |
| 1342 | case SN_TO_LOCAL: |
| 1343 | g_addr = sm->ip_hdr->ip_src; |
| 1344 | param_count = 1; |
| 1345 | switch (sm->msg) { |
| 1346 | case SN_SCTP_INIT: |
| 1347 | bytes_left = sm->chunk_length - sizeof(struct sctp_init_chunk); |
| 1348 | param = (struct sctp_paramhdr *)((char *)sm->sctpchnk.Init + sizeof(struct sctp_init)); |
| 1349 | break; |
| 1350 | case SN_SCTP_INITACK: |
| 1351 | bytes_left = sm->chunk_length - sizeof(struct sctp_init_ack_chunk); |
| 1352 | param = (struct sctp_paramhdr *)((char *)sm->sctpchnk.InitAck + sizeof(struct sctp_init_ack)); |
| 1353 | break; |
| 1354 | case SN_SCTP_ASCONF: |
| 1355 | bytes_left = sm->chunk_length; |
| 1356 | param = sm->sctpchnk.Asconf; |
| 1357 | break; |
| 1358 | } |
| 1359 | } |
| 1360 | if (bytes_left >= SN_MIN_PARAM_SIZE) |
| 1361 | param_size = SCTP_SIZE32(ntohs(param->param_length)); |
| 1362 | else |
| 1363 | param_size = bytes_left+1; /* force skip loop */ |
| 1364 | |
| 1365 | if ((assoc->state == SN_ID) && ((sm->msg == SN_SCTP_INIT) || (bytes_left < SN_MIN_PARAM_SIZE))) {/* add pkt address */ |
| 1366 | G_Addr = (struct sctp_GlobalAddress *) sn_malloc(sizeof(struct sctp_GlobalAddress)); |
| 1367 | if (G_Addr == NULL) {/* out of resources */ |
| 1368 | SN_LOG(SN_LOG_EVENT, |
| 1369 | logsctperror("AddGlobalIPAddress: No resources for adding global address - revert to no tracking", |
| 1370 | sm->sctp_hdr->v_tag, 0, direction)); |
| 1371 | assoc->num_Gaddr = 0; /* don't track any more for this assoc*/ |
| 1372 | sysctl_track_global_addresses=0; |
| 1373 | return; |
| 1374 | } |
| 1375 | G_Addr->g_addr = g_addr; |
| 1376 | if (!Add_Global_Address_to_List(assoc, G_Addr)) |
| 1377 | SN_LOG(SN_LOG_EVENT, |
| 1378 | logsctperror("AddGlobalIPAddress: Address already in list", |
| 1379 | sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction)); |
| 1380 | } |
| 1381 | |
| 1382 | /* step through parameters */ |
| 1383 | while((bytes_left >= param_size) && (bytes_left >= sizeof(struct sctp_ipv4addr_param))) { |
no test coverage detected