@ingroup packet_parser * @brief RmGlobalIPAddresses from DelIP packets * * RmGlobalIPAddresses scans an ASCONF chunk for DelIP parameters to remove the * given Global IP addresses from the association. It will not delete the * the address if it is a list of one address. * * * @param sm Pointer to sctp message information * @param assoc Pointer to the association this SCTP Message belongs
| 1486 | * |
| 1487 | */ |
| 1488 | static void |
| 1489 | RmGlobalIPAddresses(struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int direction) |
| 1490 | { |
| 1491 | struct sctp_asconf_addrv4_param *asconf_ipv4_param; |
| 1492 | struct sctp_paramhdr *param; |
| 1493 | struct sctp_GlobalAddress *G_Addr, *G_Addr_tmp; |
| 1494 | struct in_addr g_addr; |
| 1495 | int bytes_left; |
| 1496 | int param_size; |
| 1497 | int param_count; |
| 1498 | |
| 1499 | if (direction == SN_TO_GLOBAL) |
| 1500 | g_addr = sm->ip_hdr->ip_dst; |
| 1501 | else |
| 1502 | g_addr = sm->ip_hdr->ip_src; |
| 1503 | |
| 1504 | bytes_left = sm->chunk_length; |
| 1505 | param_count = 1; |
| 1506 | param = sm->sctpchnk.Asconf; |
| 1507 | if (bytes_left >= SN_MIN_PARAM_SIZE) { |
| 1508 | param_size = SCTP_SIZE32(ntohs(param->param_length)); |
| 1509 | } else { |
| 1510 | SN_LOG(SN_LOG_EVENT, |
| 1511 | logsctperror("RmGlobalIPAddress: truncated packet - cannot remove IP addresses", |
| 1512 | sm->sctp_hdr->v_tag, sysctl_track_global_addresses, direction)); |
| 1513 | return; |
| 1514 | } |
| 1515 | |
| 1516 | /* step through Asconf parameters */ |
| 1517 | while((bytes_left >= param_size) && (bytes_left >= sizeof(struct sctp_ipv4addr_param))) { |
| 1518 | if (ntohs(param->param_type) == SCTP_DEL_IP_ADDRESS) { |
| 1519 | asconf_ipv4_param = (struct sctp_asconf_addrv4_param *) param; |
| 1520 | if (asconf_ipv4_param->addrp.addr == INADDR_ANY) { /* remove all bar pkt address */ |
| 1521 | LIST_FOREACH_SAFE(G_Addr, &(assoc->Gaddr), list_Gaddr, G_Addr_tmp) { |
| 1522 | if (G_Addr->g_addr.s_addr != sm->ip_hdr->ip_src.s_addr) { |
| 1523 | if (assoc->num_Gaddr > 1) { /* only delete if more than one */ |
| 1524 | LIST_REMOVE(G_Addr, list_Gaddr); |
| 1525 | sn_free(G_Addr); |
| 1526 | assoc->num_Gaddr--; |
| 1527 | } else { |
| 1528 | SN_LOG(SN_LOG_EVENT, |
| 1529 | logsctperror("RmGlobalIPAddress: Request to remove last IP address (didn't)", |
| 1530 | sm->sctp_hdr->v_tag, assoc->num_Gaddr, direction)); |
| 1531 | } |
| 1532 | } |
| 1533 | } |
| 1534 | return; /*shouldn't be any other addresses if the zero address is given*/ |
| 1535 | } else { |
| 1536 | LIST_FOREACH_SAFE(G_Addr, &(assoc->Gaddr), list_Gaddr, G_Addr_tmp) { |
| 1537 | if (G_Addr->g_addr.s_addr == asconf_ipv4_param->addrp.addr) { |
| 1538 | if (assoc->num_Gaddr > 1) { /* only delete if more than one */ |
| 1539 | LIST_REMOVE(G_Addr, list_Gaddr); |
| 1540 | sn_free(G_Addr); |
| 1541 | assoc->num_Gaddr--; |
| 1542 | break; /* Since add only adds new addresses, there should be no double entries */ |
| 1543 | } else { |
| 1544 | SN_LOG(SN_LOG_EVENT, |
| 1545 | logsctperror("RmGlobalIPAddress: Request to remove last IP address (didn't)", |
no test coverage detected