Beispiel #1
0
void NAT_ALG_TCP_checksum
   (
      IP_HEADER_PTR    ip_header_ptr    /* [IN]  pointer to IP header */
   )
{ /* Body */
   TRANSPORT_UNION    transport;
   uint16_t           checksum;
   uint16_t           protocol;
   uint16_t           iplen = IPH_LEN(ip_header_ptr);
   uint16_t           len = mqx_ntohs(ip_header_ptr->LENGTH) - iplen; 
   
   /* Get TCP header */
   transport.PTR = TRANSPORT_PTR(ip_header_ptr);

   mqx_htons(transport.TCP_PTR->checksum, 0);    /* Clear checksum field */
   protocol = mqx_ntohc(ip_header_ptr->PROTOCOL); /* PROTOCOL */
   checksum = (uint16_t) _mem_sum_ip(protocol, 8, ip_header_ptr->SOURCE);  /* IP SRC and DST ADDR */
   checksum = (uint16_t) _mem_sum_ip(checksum, len, transport.PTR);

   /* TCP LENGTH */
   checksum = IP_Sum_immediate(checksum, len);
   
   checksum = IP_Sum_invert(checksum);
   mqx_htons(transport.TCP_PTR->checksum, checksum);   

} /* Endbody */
Beispiel #2
0
DNAT_RULE_STRUCT_PTR DNAT_lookup_rule
   (
      NAT_CFG_STRUCT_PTR      nat_cfg_ptr,
      IP_HEADER_PTR           ip_header_ptr,
      bool                 pub_to_prv
    )
{ /* Body */
   TRANSPORT_UNION            transport;
   DNAT_ELEMENT_STRUCT_PTR    element_ptr;
   _ip_address                source_ip = mqx_ntohl(ip_header_ptr->SOURCE);
   uint32_t                    ip_protocol;
   uint16_t                    source_port, destination_port; /* source port and destination port */
 
   transport.PTR = TRANSPORT_PTR(ip_header_ptr);
   
   ip_protocol = mqx_ntohc(ip_header_ptr->PROTOCOL);

   /* NAT spports ICMP, UDP and TCP transport layer protocols */
   switch (ip_protocol) {
      case IPPROTO_TCP:
          destination_port = mqx_ntohs(transport.TCP_PTR->dest_port);
          source_port = mqx_ntohs(transport.TCP_PTR->source_port);
          break;
      
      case IPPROTO_UDP:
          destination_port = mqx_ntohs(transport.UDP_PTR->DEST_PORT);
          source_port = mqx_ntohs(transport.UDP_PTR->SRC_PORT);
          break;
      
      case IPPROTO_ICMP:
          /* Allow all ICMP request/reply */
          return NULL;
   } /* Endswitch */
     
     
   element_ptr = (DNAT_ELEMENT_STRUCT_PTR) _queue_head(&nat_cfg_ptr->RULE_QUEUE);  

   /*
   ** Check for the target port and then forward the packet to the corresponding 
   ** DNAT rule target ip.
   */
   while (element_ptr != NULL) {
      if (element_ptr->RULE.IP_PROTOCOL == ip_protocol) {
         if (pub_to_prv) {
            if ((destination_port >= element_ptr->RULE.PUBLIC_START_PORT) &&
                (destination_port <= element_ptr->RULE.PUBLIC_END_PORT)) {
               break;
            }
         } else {
            if ((source_ip == element_ptr->RULE.PRIVATE_IP) &&
                (source_port >= element_ptr->RULE.PRIVATE_START_PORT) &&  
                (source_port <= element_ptr->RULE.PRIVATE_END_PORT)) {
               break;  
            }
         }
      }
      element_ptr = (DNAT_ELEMENT_STRUCT_PTR)  _queue_next(&nat_cfg_ptr->RULE_QUEUE, &element_ptr->ELEMENT);
   } /* Endwhile */
   
   if (element_ptr!=NULL) {
      return &element_ptr->RULE;
   } else {
      return NULL;
   }
}/* Endbody */
Beispiel #3
0
uint_32 NAT_ALG_tftp_apply
   (
      RTCSPCB_PTR _PTR_    pcb_ptr_ptr,               /* [IN/OUT] PCB containing packet   */
      boolean              pub_to_prv,                /* [IN] Direction of packet         */
      pointer              alg_cfg_ptr,               /* [IN] Pointer to TFTP config      */
      pointer _PTR_        session_ptr_ptr   /* [OUT] Pointer to session         */
   )
{ /* Body */
   NAT_SESSION_STRUCT_PTR  nat_session_ptr = *((NAT_SESSION_STRUCT_PTR *)session_ptr_ptr);
   uchar_ptr               data_ptr = (pointer)RTCSPCB_DATA(*pcb_ptr_ptr);
   IP_HEADER_PTR           ip_header_ptr = (IP_HEADER_PTR)(pointer)data_ptr;
   TRANSPORT_UNION         transport;
   TFTP_HEADER_PTR         tftp_header_ptr;
   uint_16                 opcode, block;
 
   if (nat_session_ptr == NULL) {
      return RTCS_OK;
   } /* Endif */
   
   
   /* TFTP uses UDP */
   if (ntohc(ip_header_ptr->PROTOCOL) != IPPROTO_UDP) {
      return RTCS_OK;
   } /* Endif */
      
   transport.PTR = TRANSPORT_PTR(ip_header_ptr);
   
   /* The UDP length should be long enough to contain a TFTP header */
   if (ntohs(transport.UDP_PTR->LENGTH) < sizeof(UDP_HEADER) + sizeof(TFTP_HEADER)) {
      return RTCS_OK;
   } /* Endif */         
   
   tftp_header_ptr = (TFTP_HEADER_PTR)(pointer)(transport.UDP_PTR + 1);

   opcode = ntohs(tftp_header_ptr->OP);
   block = ntohs(tftp_header_ptr->BLOCK);
   
   /*
   ** A normal reply should have:  OP 3 (DATA) and BLOCK 1 (first block) or
   ** an OP 4 and BLOCK 0. Error replies should have: OP 5, and a variable 
   ** error code 
   */
   if ((opcode != 3 || block != 1) &&
       (opcode != 4 || block != 0) &&
       (opcode != 5))   
   {
      return RTCS_OK;
   } /* Endif */      

   if (nat_session_ptr->SNAT_OR_DNAT == SNAT) {
      /* We only need to consider the first packet returned by the server */
      if (!pub_to_prv) {
         return RTCS_OK;
      } /* Endif */

      /* Make sure port number is the TFTP port number */
      if (nat_session_ptr->PUB_PORT != IPPORT_TFTP) {
         return RTCS_OK;
      } /* Endif */
      
      /* Set new server port number */
      nat_session_ptr->PUB_PORT = ntohs(transport.UDP_PTR->SRC_PORT);
   } else {
      /* We only need to consider the first packet returned by the server */
      if (pub_to_prv){
         return RTCS_OK;
      } /* Endif */

      /* Make sure port number is the TFTP port number */
      if (nat_session_ptr->PRV_PORT != IPPORT_TFTP) {
         return RTCS_OK;
      } /* Endif */
      
      /* Set new server port number */
      nat_session_ptr->PRV_PORT = ntohs(transport.UDP_PTR->SRC_PORT);       
   } /* Endif */
   
   return RTCS_OK;   
} /* Endbody */