//--------------------------------------------------------------------------- // Search the entity with the IPv4 address 'addr' struct cx_entity *nasmt_CLASS_cx4(struct sk_buff *skb, unsigned char dscp, int *paddr_type, unsigned char *cx_index) { //--------------------------------------------------------------------------- unsigned char cxi; uint32_t daddr; struct cx_entity *cx=NULL; struct classifier_entity *pclassifier=NULL; struct in_addr masked_addr; #ifdef NAS_DEBUG_CLASS printk("nasmt_CLASS_cx4: begin\n"); #endif if (skb!=NULL) { daddr = ((struct iphdr*)(skb_network_header(skb)))->daddr; if (daddr != INADDR_ANY) { #ifdef NAS_DEBUG_CLASS printk("nasmt_CLASS_cx4: SOURCE ADDR %d.%d.%d.%d",NIPADDR(ip_hdr(skb)->saddr)); printk(" DEST ADDR %d.%d.%d.%d\n",NIPADDR(ip_hdr(skb)->daddr)); #endif if (ipv4_is_multicast(ip_hdr(skb)->daddr)) { // TO BE CHECKED *paddr_type = NAS_IPV4_ADDR_MC_SIGNALLING; } else { if (ipv4_is_lbcast(ip_hdr(skb)->daddr)) { // TO BE CHECKED *paddr_type = NAS_IPV4_ADDR_BROADCAST; } else { if (IN_CLASSA(ip_hdr(skb)->daddr) || IN_CLASSB(ip_hdr(skb)->daddr) || IN_CLASSC(ip_hdr(skb)->daddr)) { *paddr_type = NAS_IPV4_ADDR_UNICAST; cxi = 0; (*cx_index)++; pclassifier = gpriv->cx[cxi].sclassifier[dscp]; while (pclassifier!=NULL) { // verify that this is an IPv4 classifier if ((pclassifier->version == NAS_VERSION_4) || (pclassifier->version == NAS_VERSION_DEFAULT)) { nasmt_create_mask_ipv4_addr(&masked_addr, pclassifier->dplen); if (IN_ARE_ADDR_MASKED_EQUAL(&ip_hdr(skb)->daddr, &(pclassifier->daddr.ipv4), &masked_addr)) { #ifdef NAS_DEBUG_CLASS printk("nasmt_CLASS_cx4: IP MASK MATCHED: found cx %d: %d.%d.%d.%d/%d\n",cxi, NIPADDR(pclassifier->daddr.ipv4), pclassifier->dplen); #endif return &gpriv->cx[cxi]; } } // goto to next classification rule for the connection pclassifier = pclassifier->next; } } else { *paddr_type = NAS_IPV4_ADDR_UNKNOWN; } } } } } return cx; }
int start_connect (hs_key *pksid, hs_body *pbsid) { int n, dret; struct sockaddr_in stServerAddr; stServerAddr.sin_family = AF_INET; stServerAddr.sin_addr.s_addr = pbsid->dest_ipaddr; stServerAddr.sin_port = pbsid->dest_port; if ( (n = connect (pbsid->cfd, (struct sockaddr *)&stServerAddr, sizeof(stServerAddr))) < 0) { if (errno != EINPROGRESS) { dAppLog (LOG_DEBUG, "Nonblocking connect error! %d.%s-%s", errno, strerror(errno), __FUNCTION__); return -1; } #if 0 epollOne_cli_add (pbsid->tcpsock.sockfd); dAppLog(LOG_DEBUG, "--->] Nonblocking connect succss!! Dst:%d.%d.%d.%d : %d", NIPADDR(pbsid->dest_ipaddr), ntohs(pbsid->dest_port)); #endif } return 0; }
void rcv_tcpsock (struct epoll_event *event) { int flags, event_fd; int n, error, dret; char rbuf[1024*4]; int tcp_readlen; _hkey_fd hfd_key; _hbody_fd *phfd_body; hfd_key.sockfd = event_fd = event->data.fd; phfd_body = find_fd_session (&hfd_key); if (phfd_body == NULL) { dAppLog(LOG_DEBUG, "<--%d] Not found FD Session! %s-%d", hfd_key.sockfd, __FUNCTION__, __LINE__); /** clean **/ del_fd_session(event_fd); return -1; } flags = phfd_body->tcpsock.f_flags; if ((flags & F_CONNECTING) && (event->events == EPOLLIN || event->events == EPOLLOUT)) { n = sizeof (error); if ((getsockopt(event_fd, SOL_SOCKET, SO_ERROR, &error, &n) < 0) || (error != 0)) { dAppLog(LOG_WARN, "---] nonblocking connect failed (reset)aaa %d-%s..%s-line:%d", error, strerror(error), __FUNCTION__, __LINE__); } phfd_body->tcpsock.f_flags = F_READING; epollin_cli_mod (event_fd); phfd_body->tcpsock.sock_idx = g_sock_cnt; g_sock [g_sock_cnt++] = event_fd; // write if (g_auto_send == 1) { send_http_num_only (event_fd); } } else if (flags & F_READING) { tcp_readlen = read (event_fd, rbuf, sizeof (rbuf)); dAppLog (LOG_DEBUG, "tcp_readlen: %d", tcp_readlen); #ifdef SHOW_TRAFFIC rcurr_traffic += tcp_readlen; rtotal_cnt ++; rcurr_cnt ++; rnew_time = time(NULL); if ((rnew_time - rold_time) >= 5) { dAppLog (LOG_CRI, "WCLI TCP Traffic: %6.3f Kbps, Count: total=%d, %6.3f/sec", (float)rcurr_traffic*8 / ((float)(rnew_time-rold_time)*1024), rtotal_cnt, (float)rcurr_cnt/(rnew_time-rold_time)); rold_time = rnew_time; rcurr_traffic = 0; rcurr_cnt = 0; } #endif #ifdef TCP_DUMP dAppLog (LOG_DEBUG,"[TCP RECV] ==============================>>>================================="); dAppDump((char*)rbuf, tcpreadlen); #endif if (tcp_readlen == 0) { // tcp close timerN_del(pReTimerInfo, phfd_body->send_timer); del_fd_session(event_fd); event_fd = -1; } else if (tcp_readlen > 0) { // dAppDump((char*)rbuf, tcp_readlen); // dAppLog (LOG_DEBUG, "%s", rbuf); // phfd_body->send_timer = timerN_update (pReTimerInfo, phfd_body->send_timer, time(0) + g_wait_timeout); // dAppLog (LOG_CRI, "phfd_body->send_timer :%d", phfd_body->send_timer); } else { dAppLog (LOG_DEBUG, "read fail %d-%s", errno, strerror(errno)); } } else { tcp_readlen = read (event_fd, rbuf, sizeof (rbuf)); dAppLog (LOG_CRI, "??? read %d-", tcp_readlen); if (tcp_readlen <= 0) { dAppLog(LOG_WARN, "---] nonblocking connect refuse (reset)eeee %d-%s..", errno, strerror(errno)); dAppLog(LOG_CRI, "---%d] Proxy off2! DestIP: %d.%d.%d.%d : %d connect failed", event_fd, NIPADDR(phfd_body->dest_ipaddr), ntohs(phfd_body->dest_port)); del_fd_session(event_fd); } } }
//--------------------------------------------------------------------------- // Search the sending function for IP Packet void nasmt_CLASS_send(struct sk_buff *skb) { //--------------------------------------------------------------------------- struct classifier_entity *pclassifier, *sp; uint8_t *protocolh = NULL; uint8_t version; uint8_t protocol, dscp; uint16_t classref; struct cx_entity *cx; #ifdef NAS_DEBUG_CLASS char sfct[10], sprotocol[10]; #endif struct net_device *dev = gdev; unsigned char cx_index,no_connection; int addr_type; struct in6_addr masked6_addr; struct in_addr masked_addr; // RARP vars struct arphdr *rarp; unsigned char *rarp_ptr; /* s for "source", t for "target" */ __be32 sip, tip; unsigned char *sha, *tha; #ifdef NAS_DEBUG_CLASS printk("nasmt_CLASS_send: begin -\n"); #endif if (skb==NULL) { printk("nasmt_CLASS_send - input parameter skb is NULL \n"); return; } //*** #ifdef NAS_DEBUG_SEND printk("nasmt_CLASS_send - Received IP packet to transmit:"); if ((skb->data) != NULL) { if (skb->len<100) nasmt_TOOL_print_buffer(skb->data,skb->len); else nasmt_TOOL_print_buffer(skb->data,100); } #endif //*** // find all connections related to socket cx_index = 0; no_connection = 1; cx = NULL; #ifdef NAS_DEBUG_CLASS printk("nasmt_CLASS_send: [before switch on IP protocol version] \n"); #endif // Get mobile connexion entity, protocol and dscp from IP packet switch (ntohs(skb->protocol)) { case ETH_P_IPV6: #ifdef NAS_DEBUG_CLASS printk("nasmt_CLASS_send : skb->protocol : IPv6 \n"); #endif version = NAS_VERSION_6; addr_type = NAS_IPV6_ADDR_UNKNOWN; protocolh = nasmt_TOOL_get_protocol6(ipv6_hdr(skb), &protocol); dscp = nasmt_TOOL_get_dscp6 (ipv6_hdr(skb)); cx = nasmt_CLASS_cx6 (skb, dscp, &addr_type, &cx_index); #ifdef NAS_DEBUG_CLASS printk("nasmt_CLASS_send - ETH_P_IPV6 skb %p dscp %d gpriv %p cx_index %p \n",skb, dscp, gpriv, &cx_index); #endif // find in default DSCP a valid classification if (cx == NULL) { switch (addr_type) { case NAS_IPV6_ADDR_MC_SIGNALLING: case NAS_IPV6_ADDR_UNICAST: pclassifier=(&gpriv->cx[0])->sclassifier[NAS_DSCP_DEFAULT]; while (pclassifier!=NULL) { if ((pclassifier->version == NAS_VERSION_6) || (pclassifier->version == NAS_VERSION_DEFAULT)) { // ok found default classifier for this packet nasmt_create_mask_ipv6_addr(&masked6_addr, pclassifier->dplen); if (IN6_ARE_ADDR_MASKED_EQUAL(&pclassifier->daddr.ipv6, &ipv6_hdr(skb)->daddr, &masked6_addr)) { // then force dscp cx = &gpriv->cx[0]; #ifdef NAS_DEBUG_CLASS printk("nasmt_CLASS_send - ETH_P_IPV6 FOUND NAS_DSCP_DEFAULT with IN6_ARE_ADDR_MASKED_EQUAL(%d bits)\n",pclassifier->dplen); #endif dscp = NAS_DSCP_DEFAULT; break; } else { if(IN6_IS_ADDR_UNSPECIFIED(&pclassifier->daddr.ipv6)) { cx = &gpriv->cx[0]; #ifdef NAS_DEBUG_CLASS printk("nasmt_CLASS_send - ETH_P_IPV6 FOUND NAS_DSCP_DEFAULT with IN6_IS_ADDR_UNSPECIFIED\n"); #endif dscp = NAS_DSCP_DEFAULT; break; } } } pclassifier = pclassifier->next; } break; // should have found a valid classification rule case NAS_IPV6_ADDR_UNKNOWN: default: printk("nasmt_CLASS_send: No corresponding address type\n"); } } break; case ETH_P_ARP: #ifdef NAS_DEBUG_CLASS printk("nasmt_CLASS_send : skb->protocol : ARP \n"); #endif version = NAS_VERSION_4; addr_type = NAS_IPV4_ADDR_BROADCAST; dscp = 0; cx = NULL; // Basic sanity checks can be done without the lock rarp = (struct arphdr *)skb_network_header(skb); if (rarp) { if (rarp->ar_hln != dev->addr_len || dev->type != ntohs(rarp->ar_hrd)) { printk("nasmt_CLASS_send: ARP PACKET WRONG ADDR LEN or WRONG ARP HEADER TYPE\n"); break; } } else { printk("nasmt_CLASS_send: ARP HEADER POINTER IS NULL\n"); break; } // If it's not Ethernet, delete it. if (rarp->ar_pro != htons(ETH_P_IP)) { printk("nasmt_CLASS_send: ARP PACKET PROTOCOL IS NOT ETHERNET\n"); break; } rarp_ptr = (unsigned char *) (rarp + 1); sha = rarp_ptr; rarp_ptr += dev->addr_len; memcpy(&sip, rarp_ptr, 4); rarp_ptr += 4; tha = rarp_ptr; rarp_ptr += dev->addr_len; memcpy(&tip, rarp_ptr, 4); #ifdef NAS_DEBUG_CLASS printk("nasmt_CLASS_send: ARP DEST IP transport IP = %d.%d.%d.%d\n",NIPADDR(tip)); #endif pclassifier=(&gpriv->cx[0])->sclassifier[NAS_DSCP_DEFAULT]; while (pclassifier!=NULL) { if ((pclassifier->version == NAS_VERSION_4) || (pclassifier->version == NAS_VERSION_DEFAULT)) { // ok found default classifier for this packet nasmt_create_mask_ipv4_addr(&masked_addr, pclassifier->dplen); #ifdef NAS_DEBUG_CLASS printk("nasmt_CLASS_send: MASK = %d.%d.%d.%d\n",NIPADDR(masked_addr.s_addr)); #endif // if (IN_ARE_ADDR_MASKED_EQUAL(&pclassifier->daddr.ipv4, &tip, &masked_addr.s_addr)) { // then force dscp cx = &gpriv->cx[0]; #ifdef NAS_DEBUG_CLASS printk("nasmt_CLASS_send: ETH_P_ARP FOUND NAS_DSCP_DEFAULT with IN_ARE_ADDR_MASKED_EQUAL(%d bits)\n", pclassifier->dplen); #endif dscp = NAS_DSCP_DEFAULT; break; } else { if (INADDR_ANY == pclassifier->daddr.ipv4) { cx = &gpriv->cx[0]; #ifdef NAS_DEBUG_CLASS printk("nasmt_CLASS_send: ETH_P_ARP FOUND NAS_DSCP_DEFAULT with INADDR_ANY\n"); #endif dscp = NAS_DSCP_DEFAULT; break; } } } pclassifier = pclassifier->next; } break; case ETH_P_IP: #ifdef NAS_DEBUG_CLASS printk("nasmt_CLASS_send : skb->protocol : IPv4 \n"); #endif version = NAS_VERSION_4; addr_type = NAS_IPV4_ADDR_UNKNOWN; dscp = nasmt_TOOL_get_dscp4((struct iphdr *)(skb_network_header(skb))); cx = nasmt_CLASS_cx4(skb, dscp, &addr_type, &cx_index); protocolh = nasmt_TOOL_get_protocol4((struct iphdr *)(skb_network_header(skb)), &protocol); // find in default DSCP a valid classification if (cx == NULL) { switch (addr_type) { case NAS_IPV4_ADDR_MC_SIGNALLING: case NAS_IPV4_ADDR_UNICAST: case NAS_IPV4_ADDR_BROADCAST: pclassifier=(&gpriv->cx[0])->sclassifier[NAS_DSCP_DEFAULT]; while (pclassifier != NULL) { if ((pclassifier->version == NAS_VERSION_4) || (pclassifier->version == NAS_VERSION_DEFAULT)) { // ok found default classifier for this packet nasmt_create_mask_ipv4_addr(&masked_addr, pclassifier->dplen); #ifdef NAS_DEBUG_CLASS printk("nasmt_CLASS_send : MASK = %d.%d.%d.%d\n", NIPADDR(masked_addr.s_addr)); #endif if (IN_ARE_ADDR_MASKED_EQUAL(&pclassifier->daddr.ipv4, &ip_hdr(skb)->daddr, &masked_addr.s_addr)) { // then force dscp cx = &gpriv->cx[0]; #ifdef NAS_DEBUG_CLASS printk("nasmt_CLASS_send : ETH_P_IP FOUND NAS_DSCP_DEFAULT with IN_ARE_ADDR_MASKED_EQUAL(%d bits)\n",pclassifier->dplen); #endif dscp = NAS_DSCP_DEFAULT; break; } else { if(INADDR_ANY == pclassifier->daddr.ipv4) { cx = &gpriv->cx[0]; #ifdef NAS_DEBUG_CLASS printk("nasmt_CLASS_send : ETH_P_IP FOUND NAS_DSCP_DEFAULT with INADDR_ANY\n"); #endif dscp = NAS_DSCP_DEFAULT; break; } } } pclassifier = pclassifier->next; } break; // should have found a valid classification rule case NAS_IPV4_ADDR_UNKNOWN: default: printk("nasmt_CLASS_send: No corresponding address type\n"); } } #ifdef NAS_DEBUG_CLASS //printk("nasmt_CLASS_send: ETH_P_IP Received IPv4 packet (%02X), dscp = %d, cx = %08X\n",ntohs(skb->protocol),dscp,cx); if (cx) printk("nasmt_CLASS_send: ETH_P_IP Received IPv4 packet (%02X), dscp = %d, cx = %d\n",ntohs(skb->protocol),dscp,cx->lcr); else printk("nasmt_CLASS_send: ETH_P_IP Received IPv4 packet (%02X), dscp = %d, No valid connection\n",ntohs(skb->protocol),dscp); #endif break; default: printk("nasmt_CLASS_send: Unknown IP version protocol\n"); version = 0; return; } #ifdef NAS_DEBUG_SEND_DETAIL printk("nasmt_CLASS_send: [before if (cx != NULL)]\n"); #endif // If a valid connection for the DSCP/EXP with destination address // is found scan all protocol-based classification rules if (cx != NULL) { classref = 0; sp = NULL; if (cx->state!=NAS_CX_DCH) { #ifdef NAS_DEBUG_CLASS printk("nasmt_CLASS_send: UE not connected, in state %d. Packet is dropped\n",cx->state); #endif return; } #ifdef NAS_DEBUG_CLASS printk("nasmt_CLASS_send: DSCP %d version %d: looking for classifier entry\n",dscp, version); #endif for (pclassifier=cx->sclassifier[dscp]; pclassifier!=NULL; pclassifier=pclassifier->next) { #ifdef NAS_DEBUG_CLASS printk("nasmt_CLASS_send: DSCP %d p->classref=%d,p->protocol=%d,p->version=%d\n",dscp,pclassifier->classref,pclassifier->protocol,pclassifier->version); #endif // normal rule checks that network protocol version matches if ((pclassifier->version == version) || (pclassifier->version == NAS_VERSION_DEFAULT)) { //printk("nasmt_CLASS_send: IP version are equals\n"); sp=pclassifier; classref=sp->classref; #ifdef NAS_DEBUG_SEND_DETAIL printk("nasmt_CLASS_send: classifier found for dscp %u \n", dscp); #endif break; } } if (sp!=NULL) { #ifdef NAS_DEBUG_CLASS //char sfct[10], sprotocol[10]; // classifier entity found. Print its parameters if (sp->fct==nasmt_COMMON_QOS_send) strcpy(sfct, "data xfer"); if (sp->fct==nasmt_CTL_send) strcpy(sfct, "iocontrol"); if (sp->fct==nasmt_COMMON_del_send) strcpy(sfct, "delete"); if (sp->fct==nasmt_ASCTL_DC_send_sig_data_request) strcpy(sfct, "DC-SAP"); switch(protocol) { case NAS_PROTOCOL_UDP: strcpy(sprotocol, "udp"); printk("udp packet\n"); break; case NAS_PROTOCOL_TCP: strcpy(sprotocol, "tcp"); printk("tcp packet\n"); break; case NAS_PROTOCOL_ICMP4: strcpy(sprotocol, "icmp4"); printk("icmp4 packet\n"); break; case NAS_PROTOCOL_ICMP6: strcpy(sprotocol, "icmp6"); nasmt_TOOL_pk_icmp6((struct icmp6hdr*)protocolh); break; default: strcpy(sprotocol, "other L4"); break; } printk("nasmt_CLASS_send: (dscp %u, %s) received, (classref %u, fct %s, drb_id %u) classifier rule\n", dscp, sprotocol, sp->classref, sfct, sp->rab_id); #endif //forward packet to the correct entity if (sp->fct!=NULL) { sp->fct(skb, cx, sp); } else { printk("\n\nnasmt_CLASS_send: ERROR : CLASSIFIER FUNCTION IS NULL\n\n"); } no_connection = 0; // end : if classifier entry match found } else { printk("nasmt_CLASS_send: no corresponding item in the classifier list, so the message is dropped\n"); printk("nasmt_CLASS_send: packet parameters: dscp %u, %s\n", dscp, sprotocol); nasmt_COMMON_del_send(skb, cx, NULL); // Note MW: LG has commented this line. Why? } } // if connection found #ifdef NAS_DEBUG_CLASS if (no_connection == 1) { printk("nasmt_CLASS_send: no corresponding connection, so the message is dropped\n"); } printk("nasmt_CLASS_send: end\n"); #endif }
int mme_app_config_init(char* lib_config_file_name_pP, mme_app_config_t* config_pP) { config_t cfg; config_setting_t *setting_sgw = NULL; char *sgw_interface_name_for_S1u_S12_S4_up = NULL; char *sgw_ipv4_address_for_S1u_S12_S4_up = NULL; char *sgw_interface_name_for_S5_S8_up = NULL; char *sgw_ipv4_address_for_S5_S8_up = NULL; char *sgw_interface_name_for_S11 = NULL; char *sgw_ipv4_address_for_S11 = NULL; config_setting_t *setting_pgw = NULL; config_setting_t *subsetting = NULL; config_setting_t *sub2setting = NULL; char *pgw_interface_name_for_S5_S8 = NULL; char *pgw_ipv4_address_for_S5_S8 = NULL; char *pgw_interface_name_for_SGI = NULL; char *pgw_ipv4_address_for_SGI = NULL; char *delimiters=NULL; char *saveptr1= NULL; char *astring = NULL; char *atoken = NULL; char *atoken2 = NULL; char *address = NULL; char *cidr = NULL; char *mask = NULL; int num = 0; int i = 0; int jh, jn; unsigned char buf_in6_addr[sizeof(struct in6_addr)]; struct in6_addr addr6_start; struct in6_addr addr6_mask; int prefix_mask; uint64_t counter64; unsigned char buf_in_addr[sizeof(struct in_addr)]; struct in_addr addr_start; struct in_addr addr_end; memset((char*)config_pP, 0 , sizeof(mme_app_config_t)); config_init(&cfg); if(lib_config_file_name_pP != NULL) { /* Read the file. If there is an error, report it and exit. */ if(! config_read_file(&cfg, lib_config_file_name_pP)) { MME_APP_ERROR("%s:%d - %s\n", lib_config_file_name_pP, config_error_line(&cfg), config_error_text(&cfg)); config_destroy(&cfg); AssertFatal (1 == 0, "Failed to parse eNB configuration file %s!\n", lib_config_file_name_pP); } } else { SPGW_APP_ERROR("No SP-GW configuration file provided!\n"); config_destroy(&cfg); AssertFatal (0, "No SP-GW configuration file provided!\n"); } setting_sgw = config_lookup(&cfg, SGW_CONFIG_STRING_SGW_CONFIG); if(setting_sgw != NULL) { subsetting = config_setting_get_member (setting_sgw, SGW_CONFIG_STRING_NETWORK_INTERFACES_CONFIG); if(subsetting != NULL) { if( ( config_setting_lookup_string( subsetting, SGW_CONFIG_STRING_SGW_INTERFACE_NAME_FOR_S1U_S12_S4_UP, (const char **)&sgw_interface_name_for_S1u_S12_S4_up) && config_setting_lookup_string( subsetting, SGW_CONFIG_STRING_SGW_IPV4_ADDRESS_FOR_S1U_S12_S4_UP, (const char **)&sgw_ipv4_address_for_S1u_S12_S4_up) && config_setting_lookup_string( subsetting, SGW_CONFIG_STRING_SGW_INTERFACE_NAME_FOR_S5_S8_UP, (const char **)&sgw_interface_name_for_S5_S8_up) && config_setting_lookup_string( subsetting, SGW_CONFIG_STRING_SGW_IPV4_ADDRESS_FOR_S5_S8_UP, (const char **)&sgw_ipv4_address_for_S5_S8_up) && config_setting_lookup_string( subsetting, SGW_CONFIG_STRING_SGW_INTERFACE_NAME_FOR_S11, (const char **)&sgw_interface_name_for_S11) && config_setting_lookup_string( subsetting, SGW_CONFIG_STRING_SGW_IPV4_ADDRESS_FOR_S11, (const char **)&sgw_ipv4_address_for_S11) ) ) { config_pP->sgw_config.ipv4.sgw_interface_name_for_S1u_S12_S4_up = strdup(sgw_interface_name_for_S1u_S12_S4_up); cidr = strdup(sgw_ipv4_address_for_S1u_S12_S4_up); address = strtok(cidr, "/"); mask = strtok(NULL, "/"); IPV4_STR_ADDR_TO_INT_NWBO ( address, config_pP->sgw_config.ipv4.sgw_ipv4_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR S1u_S12_S4 !\n" ) config_pP->sgw_config.ipv4.sgw_ip_netmask_for_S1u_S12_S4_up = atoi(mask); free(cidr); config_pP->sgw_config.ipv4.sgw_interface_name_for_S5_S8_up = strdup(sgw_interface_name_for_S5_S8_up); cidr = strdup(sgw_ipv4_address_for_S5_S8_up); address = strtok(cidr, "/"); mask = strtok(NULL, "/"); IPV4_STR_ADDR_TO_INT_NWBO ( address, config_pP->sgw_config.ipv4.sgw_ipv4_address_for_S5_S8_up, "BAD IP ADDRESS FORMAT FOR S5_S8 !\n" ) config_pP->sgw_config.ipv4.sgw_ip_netmask_for_S5_S8_up = atoi(mask); free(cidr); config_pP->sgw_config.ipv4.sgw_interface_name_for_S11 = strdup(sgw_interface_name_for_S11); cidr = strdup(sgw_ipv4_address_for_S11); address = strtok(cidr, "/"); mask = strtok(NULL, "/"); IPV4_STR_ADDR_TO_INT_NWBO ( address, config_pP->sgw_config.ipv4.sgw_ipv4_address_for_S11, "BAD IP ADDRESS FORMAT FOR S11 !\n" ) config_pP->sgw_config.ipv4.sgw_ip_netmask_for_S11 = atoi(mask); free(cidr); } } } setting_pgw = config_lookup(&cfg, PGW_CONFIG_STRING_PGW_CONFIG); if(setting_pgw != NULL) { subsetting = config_setting_get_member (setting_pgw, SGW_CONFIG_STRING_NETWORK_INTERFACES_CONFIG); if(subsetting != NULL) { if( ( config_setting_lookup_string(subsetting, PGW_CONFIG_STRING_PGW_INTERFACE_NAME_FOR_S5_S8, (const char **)&pgw_interface_name_for_S5_S8) && config_setting_lookup_string(subsetting, PGW_CONFIG_STRING_PGW_IPV4_ADDRESS_FOR_S5_S8, (const char **)&pgw_ipv4_address_for_S5_S8) && config_setting_lookup_string(subsetting, PGW_CONFIG_STRING_PGW_INTERFACE_NAME_FOR_SGI, (const char **)&pgw_interface_name_for_SGI) && config_setting_lookup_string(subsetting, PGW_CONFIG_STRING_PGW_IPV4_ADDR_FOR_SGI, (const char **)&pgw_ipv4_address_for_SGI) ) ) { config_pP->pgw_config.ipv4.pgw_interface_name_for_S5_S8 = strdup(pgw_interface_name_for_S5_S8); cidr = strdup(pgw_ipv4_address_for_S5_S8); address = strtok(cidr, "/"); mask = strtok(NULL, "/"); IPV4_STR_ADDR_TO_INT_NWBO ( address, config_pP->pgw_config.ipv4.pgw_ipv4_address_for_S5_S8, "BAD IP ADDRESS FORMAT FOR S5_S8 !\n" ) config_pP->pgw_config.ipv4.pgw_ip_netmask_for_S5_S8 = atoi(mask); free(cidr); config_pP->pgw_config.ipv4.pgw_interface_name_for_SGI = strdup(pgw_interface_name_for_SGI); cidr = strdup(pgw_ipv4_address_for_SGI); address = strtok(cidr, "/"); mask = strtok(NULL, "/"); IPV4_STR_ADDR_TO_INT_NWBO ( address, config_pP->pgw_config.ipv4.pgw_ipv4_address_for_SGI, "BAD IP ADDRESS FORMAT FOR SGI !\n" ) config_pP->pgw_config.ipv4.pgw_ip_netmask_for_SGI = atoi(mask); free(cidr); } } subsetting = config_setting_get_member (setting_pgw, PGW_CONFIG_STRING_IP_ADDRESS_POOL); if(subsetting != NULL) { sub2setting = config_setting_get_member (subsetting, PGW_CONFIG_STRING_IPV4_ADDRESS_LIST); if(sub2setting != NULL) { num = config_setting_length(sub2setting); for (i = 0; i < num; i++) { astring = config_setting_get_string_elem(sub2setting,i); if (astring != NULL) { trim(astring, strlen(astring)+1); if (inet_pton(AF_INET, astring, buf_in_addr) < 1) { // failure, test if there is a range specified in the string atoken = strtok(astring, PGW_CONFIG_STRING_IP_ADDRESS_RANGE_DELIMITERS); if (inet_pton(AF_INET, astring, buf_in_addr) == 1) { memcpy (&addr_start, buf_in_addr, sizeof(struct in_addr)); // valid address atoken2 = strtok(NULL, PGW_CONFIG_STRING_IP_ADDRESS_RANGE_DELIMITERS); if (inet_pton(AF_INET, atoken2, buf_in_addr) == 1) { memcpy (&addr_end, buf_in_addr, sizeof(struct in_addr)); // valid address for (jh = ntohl(addr_start.s_addr); jh <= ntohl(addr_end.s_addr); jh++) { DevAssert(PGW_MAX_ALLOCATED_PDN_ADDRESSES > config_pP->pgw_config.pool_pdn_addresses.num_ipv4_addresses); jn = htonl(jh); if (IN_CLASSA(addr_start.s_addr)) { if ((jh & 0xFF) && (jh & 0xFF) != 0xFF) { config_pP->pgw_config.pool_pdn_addresses.ipv4_addresses[config_pP->pgw_config.pool_pdn_addresses.num_ipv4_addresses++].s_addr = jn; } } else if (IN_CLASSB(addr_start.s_addr)) { if ((jh & 0xFF) && (jh & 0xFF) != 0xFF) { config_pP->pgw_config.pool_pdn_addresses.ipv4_addresses[config_pP->pgw_config.pool_pdn_addresses.num_ipv4_addresses++].s_addr = jn; } } else if (IN_CLASSC(addr_start.s_addr)) { if ((jh & 0xFF) && (jh & 0xFF) != 0xFF) { config_pP->pgw_config.pool_pdn_addresses.ipv4_addresses[config_pP->pgw_config.pool_pdn_addresses.num_ipv4_addresses++].s_addr = jn; } } else { printf("ERROR ON ADDRESS CLASS %d.%d.%d.%d\n", NIPADDR(jn)); } } } } } else { DevAssert(PGW_MAX_ALLOCATED_PDN_ADDRESSES > config_pP->pgw_config.pool_pdn_addresses.num_ipv4_addresses); memcpy (&addr_start, buf_in_addr, sizeof(struct in_addr)); config_pP->pgw_config.pool_pdn_addresses.ipv4_addresses[config_pP->pgw_config.pool_pdn_addresses.num_ipv4_addresses++].s_addr = addr_start.s_addr; } } } } sub2setting = config_setting_get_member (subsetting, PGW_CONFIG_STRING_IPV6_ADDRESS_LIST); if(sub2setting != NULL) { num = config_setting_length(sub2setting); for (i = 0; i < num; i++) { astring = config_setting_get_string_elem(sub2setting,i); if (astring != NULL) { trim(astring, strlen(astring)+1); if (inet_pton(AF_INET6, astring, buf_in6_addr) < 1) { // failure, test if there is a range specified in the string atoken = strtok(astring, PGW_CONFIG_STRING_IPV6_PREFIX_DELIMITER); if (inet_pton(AF_INET6, astring, buf_in6_addr) == 1) { atoken2 = strtok(NULL, PGW_CONFIG_STRING_IPV6_PREFIX_DELIMITER); prefix_mask = atoi(atoken2); // arbitrary values DevAssert((prefix_mask < 128) && (prefix_mask >= 64)); memcpy (&addr6_start, buf_in6_addr, sizeof(struct in6_addr)); memcpy (&addr6_mask, buf_in6_addr, sizeof(struct in6_addr)); sgw_ipv6_mask_in6_addr(&addr6_mask, prefix_mask); if (memcmp(&addr6_start, &addr6_mask, sizeof(struct in6_addr)) != 0) { AssertFatal(0, "BAD IPV6 ADDR CONFIG/MASK PAIRING %s/%d\n", astring, prefix_mask); } counter64 = 0xFFFFFFFFFFFFFFFF >> prefix_mask; // address Prefix_mask/0..0 not valid do { addr6_start.s6_addr32[3] = addr6_start.s6_addr32[3] + htonl(1); if (addr6_start.s6_addr32[3] == 0) { addr6_start.s6_addr32[2] = addr6_start.s6_addr32[2] + htonl(1); if (addr6_start.s6_addr32[2] == 0) { // should not happen since mask is no less than 64 addr6_start.s6_addr32[1] = addr6_start.s6_addr32[1] + htonl(1); if (addr6_start.s6_addr32[1] == 0) { addr6_start.s6_addr32[0] = addr6_start.s6_addr32[0] + htonl(1); } } } memcpy (&config_pP->pgw_config.pool_pdn_addresses.ipv6_addresses[config_pP->pgw_config.pool_pdn_addresses.num_ipv6_addresses++], &addr6_start, sizeof(struct in6_addr)); counter64 = counter64 - 1; } while (counter64 > 0); } } else {