static inline
int s6a_parse_ambr(struct avp *avp_ambr, ambr_t *ambr)
{
    struct avp *avp = NULL;
    struct avp_hdr *hdr;

    CHECK_FCT(fd_msg_browse(avp_ambr, MSG_BRW_FIRST_CHILD, &avp, NULL));
    if (!avp) {
        /* Child avps for ambr are mandatory */
        return -1;
    }
    while(avp) {
        CHECK_FCT(fd_msg_avp_hdr(avp, &hdr));
        switch(hdr->avp_code) {
            case AVP_CODE_BANDWIDTH_UL:
                CHECK_FCT(s6a_parse_bitrate(hdr, &ambr->br_ul));
                break;
            case AVP_CODE_BANDWIDTH_DL:
                CHECK_FCT(s6a_parse_bitrate(hdr, &ambr->br_dl));
                break;
            default:
                return -1;
        }
        /* Go to next AVP in the grouped AVP */
        CHECK_FCT(fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL));
    }
    return 0;
}
Example #2
0
/* entry point */
static int acct_entry(char * conffile)
{
	struct disp_when data;
	
	TRACE_ENTRY("%p", conffile);
	
#ifndef TEST_DEBUG /* We do this differently in the test scenario */
	/* Initialize the configuration and parse the file */
	CHECK_FCT( acct_conf_init() );
	CHECK_FCT( acct_conf_parse(conffile) );
	CHECK_FCT( acct_conf_check(conffile) );
#endif /* TEST_DEBUG */
	
	/* Now initialize the database module */
	CHECK_FCT( acct_db_init() );
	
	/* Search the AVPs we will need in this file */
	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Accounting-Record-Number", &acct_dict.Accounting_Record_Number, ENOENT) );
	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Accounting-Record-Type", &acct_dict.Accounting_Record_Type, ENOENT) );
	
	/* Register the dispatch callbacks */
	memset(&data, 0, sizeof(data));
	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_APPLICATION, APPLICATION_BY_NAME, "Diameter Base Accounting", &data.app, ENOENT) );
	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Accounting-Request", &data.command, ENOENT) );
	CHECK_FCT( fd_disp_register( acct_cb, DISP_HOW_CC, &data, NULL, NULL ) );
	
	/* Advertise the support for the Diameter Base Accounting application in the peer */
	CHECK_FCT( fd_disp_app_support ( data.app, NULL, 0, 1 ) );
	
	return 0;
}
/* The callback for load balancing the requests across the peers */
static int rt_load_balancing(void * cbdata, struct msg ** pmsg, struct fd_list * candidates)
{
	struct fd_list *lic;
	struct msg * msg = *pmsg;
	
	TRACE_ENTRY("%p %p %p", cbdata, msg, candidates);
	
	CHECK_PARAMS(msg && candidates);
	
	/* Check if it is worth processing the message */
	if (FD_IS_LIST_EMPTY(candidates))
		return 0;

	/* load balancing */
	for (lic = candidates->next; lic != candidates; lic = lic->next) {
		struct rtd_candidate * cand = (struct rtd_candidate *) lic;
		struct peer_hdr *peer;
		long to_receive, to_send, load;
		int score;
		CHECK_FCT(fd_peer_getbyid(cand->diamid, cand->diamidlen, 0, &peer));
		CHECK_FCT(fd_peer_get_load_pending(peer, &to_receive, &to_send));
                load = to_receive + to_send;
		score = cand->score;
		if ((cand->score > 0) && (load >= cand->score))
			cand->score = 1;
		else
			cand->score -= load;
		TRACE_DEBUG(INFO, "evaluated peer `%.*s', score was %d, now %d", (int)cand->diamidlen, cand->diamid, score, cand->score);
	}

	return 0;
}
static inline
int s6a_parse_apn_configuration_profile(struct avp *avp_apn_conf_prof,
                                        apn_config_profile_t *apn_config_profile)
{
    struct avp *avp = NULL;
    struct avp_hdr *hdr;

    CHECK_FCT(fd_msg_browse(avp_apn_conf_prof, MSG_BRW_FIRST_CHILD, &avp, NULL));
    while(avp) {
        CHECK_FCT(fd_msg_avp_hdr(avp, &hdr));
        switch(hdr->avp_code) {
            case AVP_CODE_CONTEXT_IDENTIFIER:
                apn_config_profile->context_identifier = hdr->avp_value->u32;
                break;
            case AVP_CODE_ALL_APN_CONFIG_INC_IND:
                CHECK_FCT(s6a_parse_all_apn_conf_inc_ind(hdr, &apn_config_profile->all_apn_conf_ind));
                break;
            case AVP_CODE_APN_CONFIGURATION: {
                DevCheck(apn_config_profile->nb_apns < MAX_APN_PER_UE,
                         apn_config_profile->nb_apns, MAX_APN_PER_UE, 0);
                CHECK_FCT(s6a_parse_apn_configuration(
                    avp, &apn_config_profile->apn_configuration[apn_config_profile->nb_apns]));
                apn_config_profile->nb_apns++;
            } break;
        }
        /* Go to next AVP in the grouped AVP */
        CHECK_FCT(fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL));
    }
    return 0;
}
static inline
int s6a_parse_eps_subscribed_qos_profile(struct avp *avp_qos,
                                         eps_subscribed_qos_profile_t *ptr)
{
    struct avp *avp = NULL;
    struct avp_hdr *hdr;

    CHECK_FCT(fd_msg_browse(avp_qos, MSG_BRW_FIRST_CHILD, &avp, NULL));
    while(avp) {
        CHECK_FCT(fd_msg_avp_hdr(avp, &hdr));
        switch(hdr->avp_code) {
            case AVP_CODE_QCI:
                CHECK_FCT(s6a_parse_qci(hdr, &ptr->qci));
                break;
            case AVP_CODE_ALLOCATION_RETENTION_PRIORITY:
                CHECK_FCT(s6a_parse_allocation_retention_priority(avp, &ptr->allocation_retention_priority));
                break;
            default:
                return -1;
        }
        /* Go to next AVP in the grouped AVP */
        CHECK_FCT(fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL));
    }
    return 0;
}
Example #6
0
/* The callback called on new messages */
static int rtereg_out(void * cbdata, struct msg ** pmsg, struct fd_list * candidates)
{
	struct msg * msg = *pmsg;
	struct avp * avp = NULL;
	
	TRACE_ENTRY("%p %p %p", cbdata, msg, candidates);
	
	CHECK_PARAMS(msg && candidates);
	
	/* Check if it is worth processing the message */
	if (FD_IS_LIST_EMPTY(candidates)) {
		return 0;
	}
	
	/* Now search the AVP in the message */
	CHECK_FCT( fd_msg_search_avp ( msg, rtereg_conf.avp, &avp ) );
	if (avp != NULL) {
		struct avp_hdr * ahdr = NULL;
		CHECK_FCT( fd_msg_avp_hdr ( avp, &ahdr ) );
		if (ahdr->avp_value != NULL) {
#ifndef HAVE_REG_STARTEND
			int ret;
		
			/* Lock the buffer */
			CHECK_POSIX( pthread_mutex_lock(&mtx) );
			
			/* Augment the buffer if needed */
			if (ahdr->avp_value->os.len >= bufsz) {
				CHECK_MALLOC_DO( buf = realloc(buf, ahdr->avp_value->os.len + 1), 
					{ pthread_mutex_unlock(&mtx); return ENOMEM; } );
Example #7
0
int ui_gtk_initialize(int argc, char *argv[])
{
    GtkWidget *vbox;

    /* Create the main window */
    ui_main_data.window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    ui_init_filters (TRUE, FALSE);

    // gtk_window_set_default_icon_from_file ("../analyzer.png", NULL);
    gtk_window_set_default_icon_name (GTK_STOCK_FIND);

    gtk_window_set_position (GTK_WINDOW(ui_main_data.window), GTK_WIN_POS_CENTER);
    gtk_window_set_default_size (GTK_WINDOW(ui_main_data.window), 1024, 800);
    ui_set_title("");
    gtk_window_set_resizable (GTK_WINDOW(ui_main_data.window), TRUE);

    vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);

    CHECK_FCT(ui_menu_bar_create(vbox));
    CHECK_FCT(ui_toolbar_create(vbox));
    CHECK_FCT(ui_notebook_create(vbox));

    gtk_container_add (GTK_CONTAINER(ui_main_data.window), vbox);

    /* Assign the destroy event */
    g_signal_connect(ui_main_data.window, "destroy", ui_main_window_destroy, NULL);

    /* Show the application window */
    gtk_widget_show_all (ui_main_data.window);

    g_idle_add (ui_idle_callback, NULL);

    return RC_OK;
}
Example #8
0
int dcca_cb_read( struct msg ** msg, struct dict_object * avp, struct avp_hdr ** avp_dst )
{
    struct avp * a = NULL;
    CHECK_FCT( fd_msg_search_avp ( *msg, avp, &a) );
    if (a) {
        CHECK_FCT( fd_msg_avp_hdr( a, avp_dst )  );
    }

    return 0;
}
Example #9
0
int dcca_cb_put_value_to_avp(struct avp * msg, struct dict_object * avp, union avp_value * value)
{
    struct avp * a = NULL;

    CHECK_FCT( fd_msg_avp_new ( avp, 0, &a ) );
    CHECK_FCT( fd_msg_avp_setvalue( a, value ) );
    CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, a ) );

    return 0;
}
Example #10
0
/* freeDiameter starting point */
int main(int argc, char * argv[])
{
	int ret;
	sigset_t sig_all;
	
	/* Block all signals from the current thread and all its future children -- we will catch everything in catch_signals */
	sigfillset(&sig_all);
	ret = pthread_sigmask(SIG_BLOCK, &sig_all, NULL);
	ASSERT(ret == 0);
	
	/* Parse the command-line */
	ret = main_cmdline(argc, argv);
	if (ret != 0) {
		return ret;
	}
	
	/* Initialize the core library */
	ret = fd_core_initialize();
	if (ret != 0) {
		fprintf(stderr, "An error occurred during freeDiameter core library initialization.\n");
		return ret;
	}
	
	/* Set gnutls debug level ? */
	if (gnutls_debug) {
		gnutls_global_set_log_function((gnutls_log_func)fd_gnutls_debug);
		gnutls_global_set_log_level (gnutls_debug);
		TRACE_DEBUG(INFO, "Enabled GNUTLS debug at level %d", gnutls_debug);
	}
	
	/* Parse the configuration file */
	CHECK_FCT_DO( fd_core_parseconf(conffile), goto error );
	
	/* Start the servers */
	CHECK_FCT_DO( fd_core_start(), goto error );
	
	/* Allow SIGINT and SIGTERM from this point to terminate the application */
	CHECK_POSIX_DO( pthread_create(&signals_thr, NULL, catch_signals, NULL), goto error );
	
	TRACE_DEBUG(INFO, FD_PROJECT_BINARY " daemon initialized.");

	/* Now, just wait for termination */
	CHECK_FCT( fd_core_wait_shutdown_complete() );
	
	/* Just in case it was not the result of a signal, we cancel signals_thr */
	fd_thr_term(&signals_thr);
	
	return 0;
error:	
	CHECK_FCT_DO( fd_core_shutdown(),  );
	CHECK_FCT( fd_core_wait_shutdown_complete() );
	fd_thr_term(&signals_thr);
	return -1;
}
Example #11
0
/* The extension-specific initialization code */
static int sample_main(char * conffile)
{
	/* The debug macro from main tree can be used the same way */
	TRACE_ENTRY("%p", conffile);
	
	/* This is how we access daemon's global vars */
	fprintf(stdout, "I am extension " __FILE__ " running on host %s.", fd_g_config->cnf_diamid);
	
	/* The configuration file name is received in the conffile var. It's up to extension to parse it */
	if (conffile) {
		fprintf(stdout, "I should parse my configuration file there: %s\n", conffile);
	} else {
		fprintf(stdout, "I received no configuration file to parse\n");
	}
	
	/* Functions from the libfreediameter can also be used as demonstrated here: */
	TRACE_DEBUG(INFO, "Let's create that 'Example-AVP'...");
	{
		struct dict_object * origin_host_avp = NULL;
		struct dict_object * session_id_avp = NULL;
		struct dict_object * example_avp_avp = NULL;
		struct dict_rule_data rule_data = { NULL, RULE_REQUIRED, 0, -1, 1 };
		struct dict_avp_data example_avp_data = { 999999, 0, "Example-AVP", AVP_FLAG_VENDOR , 0, AVP_TYPE_GROUPED };

		CHECK_FCT( fd_dict_search ( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Origin-Host", &origin_host_avp, ENOENT));
		CHECK_FCT( fd_dict_search ( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Session-Id", &session_id_avp, ENOENT));
		
		CHECK_FCT( fd_dict_new ( fd_g_config->cnf_dict, DICT_AVP, &example_avp_data , NULL, &example_avp_avp ));
		
		rule_data.rule_avp = origin_host_avp;
		rule_data.rule_min = 1;
		rule_data.rule_max = 1;
		CHECK_FCT( fd_dict_new ( fd_g_config->cnf_dict, DICT_RULE, &rule_data, example_avp_avp, NULL ));
		
		rule_data.rule_avp = session_id_avp;
		rule_data.rule_min = 1;
		rule_data.rule_max = -1;
		CHECK_FCT( fd_dict_new ( fd_g_config->cnf_dict, DICT_RULE, &rule_data, example_avp_avp, NULL ));
		
	}
	TRACE_DEBUG(INFO, "'Example-AVP' created without error");
	
	/* Call the c++ function */
	mycppfunc();
	
	/* The initialization function returns an error code with the standard POSIX meaning (ENOMEM, and so on) */
	return 0;
}
/* entry point */
static int rt_load_balance_entry(char * conffile)
{
	/* Register the callback */
	CHECK_FCT(fd_rt_out_register(rt_load_balancing, NULL, 10, &rt_load_balancing_hdl));

	TRACE_DEBUG(INFO, "Extension 'Load Balancing' initialized");
	return 0;
}
Example #13
0
int get_imsi(struct msg * msg, struct avp ** avp)
{
    struct avp * nextavp = NULL, * a = NULL;
    struct avp_hdr * a_hdr = NULL;
    struct dict_avp_data dictdata;
	struct avp_hdr *avp_dst;

	*avp = NULL;

	CHECK_FCT(  fd_dict_getval(dcca_dict.Subscription_Id, &dictdata)  );

    CHECK_FCT(  fd_msg_browse(msg, MSG_BRW_FIRST_CHILD, (void *)&nextavp, NULL)  );
	while (nextavp) {
	    CHECK_FCT( fd_msg_avp_hdr( nextavp, &avp_dst )  );

		if ( (avp_dst->avp_code == dictdata.avp_code) && (avp_dst->avp_vendor == dictdata.avp_vendor) ) {
		    CHECK_FCT( avp_search_child ( nextavp, dcca_dict.Subscription_Id_Type, &a) );
		    if(a) {
		        CHECK_FCT( fd_msg_avp_hdr( a, &a_hdr )  );
		        if(a_hdr->avp_value->i32 == 1) {
		            CHECK_FCT( avp_search_child ( nextavp, dcca_dict.Subscription_Id_Data, avp) );
		            break;
		        }
		    }
		}

		/* Otherwise move to next AVP in the message */
		CHECK_FCT( fd_msg_browse(nextavp, MSG_BRW_NEXT, (void *)&nextavp, NULL) );
	}

	return 0;

}
/* Perform a conversion between ipv6 in BCD to AVP served-party-ip-address */
int
s6a_add_ipv6_address (
  struct avp *avp,
  const char *ipv6_addr)
{
  struct avp                             *child_avp;
  union avp_value                         value;
  uint8_t                                 ipv6[18];
  struct in6_addr                         sin6;

  if (ipv6_addr == NULL) {
    return -1;
  }

  memset (&sin6, 0, sizeof (struct in6_addr));
  /*
   * This is an IPv6 family -> ipv6 buffer should start with 0x0002
   */
  ipv6[0] = 0x00;
  ipv6[1] = 0x02;

  if (inet_pton (AF_INET6, ipv6_addr, &sin6) == -1) {
    fprintf (stderr, "INET6 address conversion has failed\n");
    return -1;
  }

  /*
   * If the IPV6 address is 0:0:0:0:0:0:0:0 then we don't add it to the
   * * * * served-party ip address and consider the ip address can be dynamically
   * * * * allocated.
   */
  if (!IN6_IS_ADDR_UNSPECIFIED (sin6.s6_addr32)) {
    memcpy (&ipv6[2], &sin6.s6_addr, 16);
    CHECK_FCT (fd_msg_avp_new (s6a_cnf.dataobj_s6a_served_party_ip_addr, 0, &child_avp));
    value.os.data = ipv6;
    value.os.len = 18;
    CHECK_FCT (fd_msg_avp_setvalue (child_avp, &value));
    CHECK_FCT (fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, child_avp));
    return 0;
  }

  return -1;
}
Example #15
0
/* The entry point */
static int diameap_main(char * conffile)
{
	TRACE_ENTRY("%p", conffile);

	memset(diameap_config, 0, sizeof(struct diameap_conf));

	/* Initialize configuration */
	CHECK_FCT(diameap_init(conffile));

	/* Start Diameter EAP Application (Back-end Authenticator ) */
	CHECK_FCT(diameap_start_server());

	/* Announce the support of Diameter EAP Application to other peers */
	CHECK_FCT(fd_disp_app_support(dataobj_diameap_app, dataobj_diameap_ven, 1, 0));

	LOG_D("%sDiameter EAP Application Extension started successfully.",DIAMEAP_EXTENSION);

	return 0;
}
int s6a_parse_experimental_result(struct avp *avp, s6a_experimental_result_t *ptr)
{
  struct avp_hdr *hdr;
  struct avp *child_avp = NULL;

  if (!avp) {
    return EINVAL;
  }

  CHECK_FCT(fd_msg_avp_hdr(avp, &hdr));
  DevAssert(hdr->avp_code == AVP_CODE_EXPERIMENTAL_RESULT);
  CHECK_FCT(fd_msg_browse(avp, MSG_BRW_FIRST_CHILD, &child_avp, NULL));

  while(child_avp) {
    CHECK_FCT(fd_msg_avp_hdr(child_avp, &hdr));

    switch(hdr->avp_code) {
    case AVP_CODE_EXPERIMENTAL_RESULT_CODE:
      S6A_ERROR("Got experimental error %u:%s\n", hdr->avp_value->u32,
                experimental_retcode_2_string(hdr->avp_value->u32));

      if (ptr) {
        *ptr = (s6a_experimental_result_t)hdr->avp_value->u32;
      }

      break;

    case AVP_CODE_VENDOR_ID:
      DevCheck(hdr->avp_value->u32 == 10415, hdr->avp_value->u32,
               AVP_CODE_VENDOR_ID, 10415);
      break;

    default:
      return -1;
    }

    /* Go to next AVP in the grouped AVP */
    CHECK_FCT(fd_msg_browse(child_avp, MSG_BRW_NEXT, &child_avp, NULL));
  }

  return 0;
}
Example #17
0
int ta_serv_init(void)
{
    CHECK_FCT( fd_sess_handler_create(&ta_cli_reg, (void *)free, NULL, NULL) );
    
	struct disp_when data;
	
	TRACE_DEBUG(FULL, "Initializing dispatch callbacks for test");
	
	memset(&data, 0, sizeof(data));
	data.app = ta_appli;
	data.command = ta_cmd_r;
	
	/* fallback CB if command != Test-Request received */
	CHECK_FCT( fd_disp_register( ta_fb_cb, DISP_HOW_APPID, &data, NULL, &ta_hdl_fb ) );
	
	/* Now specific handler for Test-Request */
	CHECK_FCT( fd_disp_register( ta_tr_cb, DISP_HOW_CC, &data, NULL, &ta_hdl_tr ) );
	
	return 0;
}
Example #18
0
static int diameap_ba_policygetnextmethod(struct eap_state_machine * eap_sm,
		eap_type * eaptype, u32 * vendor)
{
	TRACE_ENTRY("%p %p %p",eap_sm,eaptype,vendor);
	*vendor = 0;
	*eaptype = TYPE_NONE;
	if (eap_sm == NULL)
	{
		return EINVAL;
	}

	eap_sm->selectedMethod = NULL;

	if (eap_sm->user.userid == NULL)
	{
		if ((eap_sm->currentMethod == TYPE_NONE))
		{
			*vendor = VENDOR_IETF;
			*eaptype = TYPE_IDENTITY;
			if (eap_sm->selectedMethod != NULL)
			{
				(*eap_sm->selectedMethod->eap_method_free)(eap_sm->methodData);
				eap_sm->methodData = NULL;
			}
			CHECK_FCT(diameap_plugin_get(VENDOR_IETF,TYPE_IDENTITY,&eap_sm->selectedMethod));
			return 0;
		}

		eap_sm->selectedMethod = NULL;
		*vendor = 0;
		*eaptype = TYPE_NONE;
		return 0;
	}

	if (eap_sm->user.methodId == -1)
	{
		if (eap_sm->user.proposed_eap_method >= TYPE_EAP_MD5)
		{
			*vendor = eap_sm->user.proposed_eap_method_vendor;
			if (*vendor == VENDOR_IETF)
			{
				*eaptype = eap_sm->user.proposed_eap_method;
			}
			else
			{
				*eaptype = TYPE_EXPANDED_TYPES;
			}
			if (eap_sm->selectedMethod != NULL)
			{
				(*eap_sm->selectedMethod->eap_method_free)(eap_sm->methodData);
				eap_sm->methodData = NULL;
			}
			CHECK_FCT_DO(diameap_plugin_get(*vendor,*eaptype,&eap_sm->selectedMethod),
					{	TRACE_DEBUG(INFO,"%s [EAP Protocol] Invalid EAP-TYPE %d (vendor %d)",DIAMEAP_EXTENSION,*eaptype,*vendor);return 1;});
Example #19
0
/* entry point */
static int rtd_entry(char * conffile)
{
	TRACE_ENTRY("%p", conffile);
	
	/* Initialize the repo */
	CHECK_FCT( rtd_init() );
	
	/* Parse the configuration file */
	CHECK_FCT( rtd_conf_handle(conffile) );
	
#if 0
	/* Dump the rules */
	rtd_dump();
#endif /* 0 */
	
	/* Register the callback */
	CHECK_FCT( fd_rt_out_register( rtd_out, NULL, 5, &rtd_hdl ) );
	
	/* We're done */
	return 0;
}
Example #20
0
/* Alloc / reinit a peer structure. if *ptr is not NULL, it must already point to a valid struct fd_peer. */
int fd_peer_alloc(struct fd_peer ** ptr)
{
	struct fd_peer *p;
	
	TRACE_ENTRY("%p", ptr);
	CHECK_PARAMS(ptr);
	
	if (*ptr) {
		p = *ptr;
	} else {
		CHECK_MALLOC( p = malloc(sizeof(struct fd_peer)) );
		*ptr = p;
	}
	
	/* Now initialize the content */
	memset(p, 0, sizeof(struct fd_peer));
	
	fd_list_init(&p->p_hdr.chain, p);
	
	fd_list_init(&p->p_hdr.info.pi_endpoints, p);
	fd_list_init(&p->p_hdr.info.runtime.pir_apps, p);
	
	p->p_eyec = EYEC_PEER;
	CHECK_POSIX( pthread_mutex_init(&p->p_state_mtx, NULL) );
	
	fd_list_init(&p->p_actives, p);
	fd_list_init(&p->p_expiry, p);
	CHECK_FCT( fd_fifo_new(&p->p_tosend, 5) );
	CHECK_FCT( fd_fifo_new(&p->p_tofailover, 0) );
	p->p_hbh = lrand48();
	
	fd_list_init(&p->p_sr.srs, p);
	fd_list_init(&p->p_sr.exp, p);
	CHECK_POSIX( pthread_mutex_init(&p->p_sr.mtx, NULL) );
	CHECK_POSIX( pthread_cond_init(&p->p_sr.cnd, NULL) );
	
	fd_list_init(&p->p_connparams, p);
	
	return 0;
}
Example #21
0
int avp_search_child ( struct avp * msg, struct dict_object * what, struct avp ** avp )
{
	struct avp * nextavp;
	struct dict_avp_data 	dictdata;
	struct avp_hdr *avp_dst;

	TRACE_ENTRY("%p %p %p", msg, what, avp);

	*avp = NULL;

	CHECK_FCT(  fd_dict_getval(what, &dictdata)  );

	/* Loop on all top AVPs */
	CHECK_FCT(  fd_msg_browse(msg, MSG_BRW_FIRST_CHILD, (void *)&nextavp, NULL)  );
	while (nextavp) {
	    CHECK_FCT( fd_msg_avp_hdr( nextavp, &avp_dst )  );

		if ( (avp_dst->avp_code == dictdata.avp_code) && (avp_dst->avp_vendor == dictdata.avp_vendor) ) {
		    break;
		}

		/* Otherwise move to next AVP in the message */
		CHECK_FCT( fd_msg_browse(nextavp, MSG_BRW_NEXT, (void *)&nextavp, NULL) );
	}

	if (avp)
		*avp = nextavp;

	if (avp && nextavp) {
		struct dictionary * dict;
		CHECK_FCT( fd_dict_getdict( what, &dict) );
		CHECK_FCT_DO( fd_msg_parse_dict( nextavp, dict, NULL ), /* nothing */ );
	}

	if (avp || nextavp)
		return 0;
	else
		return ENOENT;
}
/* Perform a conversion between ipv4 in BCD to AVP served-party-ip-address */
int
s6a_add_ipv4_address (
  struct avp *avp,
  const char *ipv4_addr)
{
  struct avp                             *child_avp;
  union avp_value                         value;
  uint8_t                                 ipv4[6];      /* Converted IPv4 address with family */
  in_addr_t                               sin;

  if (ipv4_addr == NULL) {
    return -1;
  }

  /*
   * This is an IPv4 family -> ipv4 buffer should start with 0x0001
   */
  ipv4[0] = 0x00;
  ipv4[1] = 0x01;
  sin = inet_addr (ipv4_addr);

  /*
   * No need to add the address if it is an any address
   */
  if (sin != INADDR_ANY) {
    memcpy (&ipv4[2], &sin, 4);
    CHECK_FCT (fd_msg_avp_new (s6a_cnf.dataobj_s6a_served_party_ip_addr, 0, &child_avp));
    value.os.data = ipv4;
    value.os.len = 6;
    CHECK_FCT (fd_msg_avp_setvalue (child_avp, &value));
    CHECK_FCT (fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, child_avp));
    return 0;
  }

  /*
   * No IP address added to AVP
   */
  return -1;
}
Example #23
0
int main(int argc, char *argv[])
{
    int ret = 0;

    GLogLevelFlags log_flags;

    log_flags = (GLogLevelFlags)
        (G_LOG_LEVEL_ERROR      |
        G_LOG_LEVEL_CRITICAL    |
        G_LOG_LEVEL_WARNING     |
        G_LOG_LEVEL_MESSAGE     |
        G_LOG_LEVEL_INFO        |
        G_LOG_LEVEL_DEBUG);

    /* This initialize the library and check potential ABI mismatches
     * between the version it was compiled for and the actual shared
     * library used.
     */
    LIBXML_TEST_VERSION;
    xmlInitParser();

    /* Initialize the widget set */
    gtk_init(&argc, &argv);

    /* Parse command line options */
    ui_gtk_parse_arg (argc, argv);

    /* Set log handlers:
     *                 Domain,      Levels,    Handler,             Domain enabled levels */
    g_log_set_handler( NULL,        log_flags, console_log_handler, (gpointer) (G_LOG_LEVELS));
    g_log_set_handler("BUFFERS",    log_flags, console_log_handler, (gpointer) (G_LOG_LEVELS & (~(G_LOG_LEVEL_DEBUG))));
    g_log_set_handler("PARSER",     log_flags, console_log_handler, (gpointer) (G_LOG_LEVELS & (~(G_LOG_LEVEL_DEBUG))));
    g_log_set_handler("RESOLVER",   log_flags, console_log_handler, (gpointer) (G_LOG_LEVELS & (~(G_LOG_LEVEL_DEBUG))));
    g_log_set_handler("UI",         log_flags, console_log_handler, (gpointer) (G_LOG_LEVELS & (~(G_LOG_LEVEL_DEBUG))));
    g_log_set_handler("UI_CB",      log_flags, console_log_handler, (gpointer) (G_LOG_LEVELS));
    g_log_set_handler("UI_FILTER",  log_flags, console_log_handler, (gpointer) (G_LOG_LEVELS & (~(G_LOG_LEVEL_DEBUG))));
    g_log_set_handler("UI_INTER",   log_flags, console_log_handler, (gpointer) (G_LOG_LEVELS));
    g_log_set_handler("UI_TREE",    log_flags, console_log_handler, (gpointer) (G_LOG_LEVELS & (~(G_LOG_LEVEL_DEBUG))));

    CHECK_FCT(ui_gtk_initialize(argc, argv));

    /* Enter the main event loop, and wait for user interaction */
    gtk_main ();

    /* Free the global variables that may
     * have been allocated by the parser.
     */
    xmlCleanupParser ();

    return ret;
}
Example #24
0
int file_read_dump(buffer_t **buffer, const char *filename)
{
    int fd = -1;
    buffer_t *new_buf = NULL;
    uint8_t   data[READ_BUFFER_SIZE];
    ssize_t   current_read;

    if (!filename)
        return RC_BAD_PARAM;

    if ((fd = open(filename, O_RDONLY)) == -1) {
        g_warning("Cannot open %s for reading, returned %d:%s\n",
                  filename, errno, strerror(errno));
        return RC_FAIL;
    }

    CHECK_FCT(buffer_new_from_data(&new_buf, NULL, 0, 0));

    do {
        current_read = read(fd, data, READ_BUFFER_SIZE);
        if (current_read == -1)
        {
            g_warning("Failed to read data from file, returned %d:%s\n",
                      errno, strerror(errno));
            return RC_FAIL;
        }
        CHECK_FCT(buffer_append_data(new_buf, data, current_read));
    } while(current_read == READ_BUFFER_SIZE);

    *buffer = new_buf;

    buffer_dump(new_buf, stdout);

    close(fd);

    return RC_OK;
}
int s6a_parse_subscription_data(struct avp *avp_subscription_data,
                                subscription_data_t *subscription_data)
{
    struct avp *avp = NULL;
    struct avp_hdr *hdr;

    CHECK_FCT(fd_msg_browse(avp_subscription_data, MSG_BRW_FIRST_CHILD, &avp, NULL));
    while(avp) {
        CHECK_FCT(fd_msg_avp_hdr(avp, &hdr));

        switch(hdr->avp_code) {
            case AVP_CODE_SUBSCRIBER_STATUS:
                CHECK_FCT(s6a_parse_subscriber_status(hdr, &subscription_data->subscriber_status));
                break;
            case AVP_CODE_MSISDN:
                CHECK_FCT(s6a_parse_msisdn(hdr, subscription_data->msisdn,
                                           &subscription_data->msisdn_length));
                break;
            case AVP_CODE_NETWORK_ACCESS_MODE:
                CHECK_FCT(s6a_parse_network_access_mode(hdr, &subscription_data->access_mode));
                break;
            case AVP_CODE_ACCESS_RESTRICTION_DATA:
                CHECK_FCT(s6a_parse_access_restriction_data(hdr, &subscription_data->access_restriction));
                break;
            case AVP_CODE_AMBR:
                CHECK_FCT(s6a_parse_ambr(avp, &subscription_data->subscribed_ambr));
                break;
            case AVP_CODE_APN_CONFIGURATION_PROFILE:
                CHECK_FCT(s6a_parse_apn_configuration_profile(avp, &subscription_data->apn_config_profile));
                break;
            case AVP_CODE_SUBSCRIBED_PERIODIC_RAU_TAU_TIMER:
                subscription_data->rau_tau_timer = hdr->avp_value->u32;
                break;
            default:
                return -1;
        }
        /* Go to next AVP in the grouped AVP */
        CHECK_FCT(fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL));
    }
    return 0;
}
static inline
int s6a_parse_apn_configuration(struct avp *avp_apn_conf_prof, apn_configuration_t *apn_config)
{
    struct avp *avp = NULL;
    struct avp_hdr *hdr;

    CHECK_FCT(fd_msg_browse(avp_apn_conf_prof, MSG_BRW_FIRST_CHILD, &avp, NULL));
    while(avp) {
        CHECK_FCT(fd_msg_avp_hdr(avp, &hdr));
        switch(hdr->avp_code) {
            case AVP_CODE_CONTEXT_IDENTIFIER:
                apn_config->context_identifier = hdr->avp_value->u32;
                break;
            case AVP_CODE_SERVED_PARTY_IP_ADDRESS:
                if (apn_config->nb_ip_address == 2) {
                    DevMessage("Only two IP addresses can be provided");
                }
                CHECK_FCT(s6a_parse_ip_address(hdr, &apn_config->ip_address[apn_config->nb_ip_address]));
                apn_config->nb_ip_address++;
                break;
            case AVP_CODE_PDN_TYPE:
                CHECK_FCT(s6a_parse_pdn_type(hdr, &apn_config->pdn_type));
                break;
            case AVP_CODE_SERVICE_SELECTION:
                CHECK_FCT(s6a_parse_service_selection(hdr, apn_config->service_selection,
                                                      &apn_config->service_selection_length));
                break;
            case AVP_CODE_EPS_SUBSCRIBED_QOS_PROFILE:
                CHECK_FCT(s6a_parse_eps_subscribed_qos_profile(avp, &apn_config->subscribed_qos));
                break;
            case AVP_CODE_AMBR:
                CHECK_FCT(s6a_parse_ambr(avp, &apn_config->ambr));
                break;
        }
        /* Go to next AVP in the grouped AVP */
        CHECK_FCT(fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL));
    }
    return 0;
}
Example #27
0
// Remove a peer entry.
int fd_peer_remove ( DiamId_t diamid, size_t diamidlen )
{
	struct fd_list * li;

	// Find the peer in the peer list from its pi_diamid.
	CHECK_POSIX( pthread_rwlock_wrlock(&fd_g_peers_rw) );
	for (li = fd_g_peers.next; li != &fd_g_peers; li = li->next) {
		struct fd_peer * peer = (struct fd_peer *)li;
		int cmp = fd_os_cmp( diamid, diamidlen, peer->p_hdr.info.pi_diamid, peer->p_hdr.info.pi_diamidlen );

		if (cmp == 0) {
			/* update the peer lifetime, set the expiry flag and call fd_p_expi_update so that the
			 * p_exp_timer value is updated and the peer expires immediately. */
			peer->p_hdr.info.config.pic_flags.exp = PI_EXP_INACTIVE;
			peer->p_hdr.info.config.pic_lft = 0;
			CHECK_FCT( fd_p_expi_update(peer) );
			break;
		}
	}

	CHECK_POSIX( pthread_rwlock_unlock(&fd_g_peers_rw) );

	return 0;
}
static inline
int s6a_parse_allocation_retention_priority(struct avp *avp_arp,
                                            allocation_retention_priority_t *ptr)
{
    struct avp *avp = NULL;
    struct avp_hdr *hdr;

    /* If the Pre-emption-Capability AVP is not present in the
     * Allocation-Retention-Priority AVP, the default value shall be
     * PRE-EMPTION_CAPABILITY_DISABLED (1).
     */
    ptr->pre_emp_capability = PRE_EMPTION_CAPABILITY_DISABLED;

    /* If the Pre-emption-Vulnerability AVP is not present in the
     * Allocation-Retention-Priority AVP, the default value shall be
     * PRE-EMPTION_VULNERABILITY_ENABLED (0).
     */
    ptr->pre_emp_vulnerability = PRE_EMPTION_VULNERABILITY_ENABLED;

    CHECK_FCT(fd_msg_browse(avp_arp, MSG_BRW_FIRST_CHILD, &avp, NULL));
    while(avp) {
        CHECK_FCT(fd_msg_avp_hdr(avp, &hdr));
        switch(hdr->avp_code) {
            case AVP_CODE_PRIORITY_LEVEL:
                CHECK_FCT(s6a_parse_priority_level(hdr, &ptr->priority_level));
                break;
            case AVP_CODE_PRE_EMPTION_CAPABILITY:
                CHECK_FCT(s6a_parse_pre_emp_capability(hdr, &ptr->pre_emp_capability));
                break;
            case AVP_CODE_PRE_EMPTION_VULNERABILITY:
                CHECK_FCT(s6a_parse_pre_emp_vulnerability(hdr, &ptr->pre_emp_vulnerability));
                break;
            default:
                return -1;
        }
        /* Go to next AVP in the grouped AVP */
        CHECK_FCT(fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL));
    }
    return 0;
}
Example #29
0
/* Add a new peer entry */
int fd_peer_add ( struct peer_info * info, const char * orig_dbg, void (*cb)(struct peer_info *, void *), void * cb_data )
{
	struct fd_peer *p = NULL;
	struct fd_list * li, *li_inf;
	int ret = 0;
	
	TRACE_ENTRY("%p %p %p %p", info, orig_dbg, cb, cb_data);
	CHECK_PARAMS(info && info->pi_diamid);
	
	if (info->config.pic_realm) {
		if (!fd_os_is_valid_DiameterIdentity((os0_t)info->config.pic_realm, strlen(info->config.pic_realm))) {
			TRACE_DEBUG(INFO, "'%s' is not a valid DiameterIdentity.", info->config.pic_realm);
			return EINVAL;
		}
	}
	
	/* Create a structure to contain the new peer information */
	CHECK_FCT( fd_peer_alloc(&p) );
	
	/* Copy the informations from the parameters received */
	p->p_hdr.info.pi_diamid = info->pi_diamid;
	CHECK_FCT( fd_os_validate_DiameterIdentity(&p->p_hdr.info.pi_diamid, &p->p_hdr.info.pi_diamidlen, 1) );
	
	memcpy( &p->p_hdr.info.config, &info->config, sizeof(p->p_hdr.info.config) );
	
	/* Duplicate the strings if provided */
	if (info->config.pic_realm) {
		CHECK_MALLOC( p->p_hdr.info.config.pic_realm = strdup(info->config.pic_realm) );
	}
	if (info->config.pic_priority) {
		CHECK_MALLOC( p->p_hdr.info.config.pic_priority = strdup(info->config.pic_priority) );
	}
	
	/* Move the list of endpoints into the peer */
	if (info->pi_endpoints.next)
		while (!FD_IS_LIST_EMPTY( &info->pi_endpoints ) ) {
			li = info->pi_endpoints.next;
			fd_list_unlink(li);
			fd_list_insert_before(&p->p_hdr.info.pi_endpoints, li);
		}
	
	/* The internal data */
	if (orig_dbg) {
		CHECK_MALLOC( p->p_dbgorig = strdup(orig_dbg) );
	} else {
		CHECK_MALLOC( p->p_dbgorig = strdup("unspecified") );
	}
	p->p_cb = cb;
	p->p_cb_data = cb_data;
	
	/* Ok, now check if we don't already have an entry with the same Diameter Id, and insert this one */
	CHECK_POSIX( pthread_rwlock_wrlock(&fd_g_peers_rw) );
	li_inf = &fd_g_peers;
	for (li = fd_g_peers.next; li != &fd_g_peers; li = li->next) {
		struct fd_peer * next = (struct fd_peer *)li;
		int cont;
		int cmp = fd_os_almostcasesrch( p->p_hdr.info.pi_diamid, p->p_hdr.info.pi_diamidlen, 
						next->p_hdr.info.pi_diamid, next->p_hdr.info.pi_diamidlen,
						&cont );
		if (cmp > 0)
			li_inf = li; /* it will come after this element, for sure */
		
		if (cmp == 0) {
			ret = EEXIST; /* we have a duplicate */
			break;
		}
		if (!cont)
			break;
	}
	
	/* We can insert the new peer object */
	if (! ret)
		do {
			/* Update expiry list */
			CHECK_FCT_DO( ret = fd_p_expi_update( p ), break );

			/* Insert the new element in the list */
			fd_list_insert_after( li_inf, &p->p_hdr.chain );
		} while (0);

	CHECK_POSIX( pthread_rwlock_unlock(&fd_g_peers_rw) );
	if (ret) {
		CHECK_FCT( fd_peer_free(&p) );
	} else {
		CHECK_FCT( fd_psm_begin(p) );
	}
	return ret;
}
int
s6a_add_subscription_data_avp (
  struct msg *message,
  mysql_ul_ans_t * mysql_ans)
{
  int                                     ret = -1,
    i = 0;
  mysql_pdn_t                            *pdns = NULL;
  uint8_t                                 nb_pdns = 0;
  struct avp                             *avp = NULL,
    *child_avp = NULL;
  union avp_value                         value;

  if (mysql_ans == NULL) {
    return -1;
  }

  ret = hss_mysql_query_pdns (mysql_ans->imsi, &pdns, &nb_pdns);

  if (ret != 0) {
    /*
     * mysql query failed:
     * * * * - maybe no more memory
     * * * * - maybe user is not known (should have failed before)
     * * * * - maybe imsi has no EPS subscribed
     */
    goto out;
  }

  if (nb_pdns == 0) {
    /*
     * No PDN for this user -> DIAMETER_ERROR_UNKNOWN_EPS_SUBSCRIPTION
     */
    return -1;
  }

  /*
   * Create the Subscription-Data AVP
   */
  CHECK_FCT (fd_msg_avp_new (s6a_cnf.dataobj_s6a_subscription_data, 0, &avp));
  {
    uint8_t                                 msisdn_len = strlen (mysql_ans->msisdn);

    /*
     * The MSISDN is known in the HSS, add it to the subscription data
     */
    if (msisdn_len > 0) {
      CHECK_FCT (fd_msg_avp_new (s6a_cnf.dataobj_s6a_msisdn, 0, &child_avp));
      value.os.data = (uint8_t *) mysql_ans->msisdn;
      value.os.len = msisdn_len;
      CHECK_FCT (fd_msg_avp_setvalue (child_avp, &value));
      CHECK_FCT (fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, child_avp));
    }
  }

  /*
   * We have to include the acess-restriction-data if the value stored in DB
   * * * * indicates that at least one restriction is applied to the USER.
   */
  if (mysql_ans->access_restriction != 0) {
    CHECK_FCT (fd_msg_avp_new (s6a_cnf.dataobj_s6a_access_restriction_data, 0, &child_avp));
    value.u32 = (uint32_t) mysql_ans->access_restriction;
    CHECK_FCT (fd_msg_avp_setvalue (child_avp, &value));
    CHECK_FCT (fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, child_avp));
  }

  /*
   * Add the Subscriber-Status to the list of AVP.
   * * * * It shall indicate if the service is barred or granted.
   * * * * TODO: normally this parameter comes from DB...
   */
  CHECK_FCT (fd_msg_avp_new (s6a_cnf.dataobj_s6a_subscriber_status, 0, &child_avp));
  /*
   * SERVICE_GRANTED
   */
  value.u32 = 0;
  CHECK_FCT (fd_msg_avp_setvalue (child_avp, &value));
  CHECK_FCT (fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, child_avp));
  /*
   * Add the Network-Access-Mode to the list of AVP.
   * * * * LTE Standalone HSS/MME: ONLY_PACKET.
   */
  CHECK_FCT (fd_msg_avp_new (s6a_cnf.dataobj_s6a_network_access_mode, 0, &child_avp));
  /*
   * SERVICE_GRANTED
   */
  value.u32 = 2;
  CHECK_FCT (fd_msg_avp_setvalue (child_avp, &value));
  CHECK_FCT (fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, child_avp));
  /*
   * Add the AMBR to list of AVPs
   */
  {
    struct avp                             *bandwidth;

    CHECK_FCT (fd_msg_avp_new (s6a_cnf.dataobj_s6a_ambr, 0, &child_avp));
    /*
     * Uplink bandwidth
     */
    CHECK_FCT (fd_msg_avp_new (s6a_cnf.dataobj_s6a_max_bandwidth_ul, 0, &bandwidth));
    value.u32 = mysql_ans->aggr_ul;
    CHECK_FCT (fd_msg_avp_setvalue (bandwidth, &value));
    CHECK_FCT (fd_msg_avp_add (child_avp, MSG_BRW_LAST_CHILD, bandwidth));
    /*
     * Downlink bandwidth
     */
    CHECK_FCT (fd_msg_avp_new (s6a_cnf.dataobj_s6a_max_bandwidth_dl, 0, &bandwidth));
    value.u32 = mysql_ans->aggr_dl;
    CHECK_FCT (fd_msg_avp_setvalue (bandwidth, &value));
    CHECK_FCT (fd_msg_avp_add (child_avp, MSG_BRW_LAST_CHILD, bandwidth));
    CHECK_FCT (fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, child_avp));
  }

  /*
   * Add the APN-Configuration-Profile only if at least one APN is subscribed
   */
  if (nb_pdns > 0) {
    struct avp                             *apn_profile;

    CHECK_FCT (fd_msg_avp_new (s6a_cnf.dataobj_s6a_apn_configuration_profile, 0, &apn_profile));
    /*
     * Context-Identifier
     */
    CHECK_FCT (fd_msg_avp_new (s6a_cnf.dataobj_s6a_context_identifier, 0, &child_avp));
    value.u32 = 0;
    /*
     * TODO: this is the reference to the default APN...
     */
    CHECK_FCT (fd_msg_avp_setvalue (child_avp, &value));
    CHECK_FCT (fd_msg_avp_add (apn_profile, MSG_BRW_LAST_CHILD, child_avp));
    /*
     * All-APN-Configurations-Included-Indicator
     */
    CHECK_FCT (fd_msg_avp_new (s6a_cnf.dataobj_s6a_all_apn_conf_inc_ind, 0, &child_avp));
    value.u32 = 0;
    CHECK_FCT (fd_msg_avp_setvalue (child_avp, &value));
    CHECK_FCT (fd_msg_avp_add (apn_profile, MSG_BRW_LAST_CHILD, child_avp));

    for (i = 0; i < nb_pdns; i++) {
      struct avp                             *apn_configuration;
      mysql_pdn_t                            *pdn_elm;

      pdn_elm = &pdns[i];
      /*
       * APN-Configuration
       */
      CHECK_FCT (fd_msg_avp_new (s6a_cnf.dataobj_s6a_apn_configuration, 0, &apn_configuration));
      /*
       * Context-Identifier
       */
      CHECK_FCT (fd_msg_avp_new (s6a_cnf.dataobj_s6a_context_identifier, 0, &child_avp));
      value.u32 = i;
      CHECK_FCT (fd_msg_avp_setvalue (child_avp, &value));
      CHECK_FCT (fd_msg_avp_add (apn_configuration, MSG_BRW_LAST_CHILD, child_avp));
      /*
       * PDN-Type
       */
      CHECK_FCT (fd_msg_avp_new (s6a_cnf.dataobj_s6a_pdn_type, 0, &child_avp));
      value.u32 = pdn_elm->pdn_type;
      CHECK_FCT (fd_msg_avp_setvalue (child_avp, &value));
      CHECK_FCT (fd_msg_avp_add (apn_configuration, MSG_BRW_LAST_CHILD, child_avp));

      if ((pdn_elm->pdn_type == IPV4) || (pdn_elm->pdn_type == IPV4_OR_IPV6) || (pdn_elm->pdn_type == IPV4V6)) {
        s6a_add_ipv4_address (apn_configuration, pdn_elm->pdn_address.ipv4_address);
      }

      if ((pdn_elm->pdn_type == IPV6) || (pdn_elm->pdn_type == IPV4_OR_IPV6) || (pdn_elm->pdn_type == IPV4V6)) {
        s6a_add_ipv6_address (apn_configuration, pdn_elm->pdn_address.ipv6_address);
      }

      /*
       * Service-Selection
       */
      CHECK_FCT (fd_msg_avp_new (s6a_cnf.dataobj_s6a_service_selection, 0, &child_avp));
      value.os.data = (uint8_t *) pdn_elm->apn;
      value.os.len = strlen (pdn_elm->apn);
      CHECK_FCT (fd_msg_avp_setvalue (child_avp, &value));
      CHECK_FCT (fd_msg_avp_add (apn_configuration, MSG_BRW_LAST_CHILD, child_avp));
      /*
       * Add the eps subscribed qos profile
       */
      {
        struct avp                             *qos_profile,
                                               *allocation_priority;

        CHECK_FCT (fd_msg_avp_new (s6a_cnf.dataobj_s6a_eps_subscribed_qos_profile, 0, &qos_profile));
        CHECK_FCT (fd_msg_avp_new (s6a_cnf.dataobj_s6a_qos_class_identifier, 0, &child_avp));
        /*
         * For a QCI_1
         */
        value.u32 = (uint32_t) pdn_elm->qci;
        CHECK_FCT (fd_msg_avp_setvalue (child_avp, &value));
        CHECK_FCT (fd_msg_avp_add (qos_profile, MSG_BRW_LAST_CHILD, child_avp));
        /*
         * Allocation retention priority
         */
        {
          CHECK_FCT (fd_msg_avp_new (s6a_cnf.dataobj_s6a_allocation_retention_priority, 0, &allocation_priority));
          /*
           * Priority level
           */
          CHECK_FCT (fd_msg_avp_new (s6a_cnf.dataobj_s6a_priority_level, 0, &child_avp));
          value.u32 = (uint32_t) pdn_elm->priority_level;
          CHECK_FCT (fd_msg_avp_setvalue (child_avp, &value));
          CHECK_FCT (fd_msg_avp_add (allocation_priority, MSG_BRW_LAST_CHILD, child_avp));
          /*
           * Pre-emption-capability
           */
          CHECK_FCT (fd_msg_avp_new (s6a_cnf.dataobj_s6a_pre_emption_capability, 0, &child_avp));
          value.u32 = (uint32_t) pdn_elm->pre_emp_cap;
          CHECK_FCT (fd_msg_avp_setvalue (child_avp, &value));
          CHECK_FCT (fd_msg_avp_add (allocation_priority, MSG_BRW_LAST_CHILD, child_avp));
          /*
           * Pre-emption-vulnerability
           */
          CHECK_FCT (fd_msg_avp_new (s6a_cnf.dataobj_s6a_pre_emption_vulnerability, 0, &child_avp));
          value.u32 = (uint32_t) pdn_elm->pre_emp_vul;
          CHECK_FCT (fd_msg_avp_setvalue (child_avp, &value));
          CHECK_FCT (fd_msg_avp_add (allocation_priority, MSG_BRW_LAST_CHILD, child_avp));
          CHECK_FCT (fd_msg_avp_add (qos_profile, MSG_BRW_LAST_CHILD, allocation_priority));
        }
        CHECK_FCT (fd_msg_avp_add (apn_configuration, MSG_BRW_LAST_CHILD, qos_profile));
      }
      /*
       * Add the AMBR to list of AVPs
       */
      {
        struct avp                             *bandwidth;

        CHECK_FCT (fd_msg_avp_new (s6a_cnf.dataobj_s6a_ambr, 0, &bandwidth));
        /*
         * Uplink bandwidth
         */
        CHECK_FCT (fd_msg_avp_new (s6a_cnf.dataobj_s6a_max_bandwidth_ul, 0, &child_avp));
        value.u32 = (uint32_t) pdn_elm->aggr_ul;
        CHECK_FCT (fd_msg_avp_setvalue (child_avp, &value));
        CHECK_FCT (fd_msg_avp_add (bandwidth, MSG_BRW_LAST_CHILD, child_avp));
        /*
         * Downlink bandwidth
         */
        CHECK_FCT (fd_msg_avp_new (s6a_cnf.dataobj_s6a_max_bandwidth_dl, 0, &child_avp));
        value.u32 = (uint32_t) pdn_elm->aggr_dl;
        CHECK_FCT (fd_msg_avp_setvalue (child_avp, &value));
        CHECK_FCT (fd_msg_avp_add (bandwidth, MSG_BRW_LAST_CHILD, child_avp));
        CHECK_FCT (fd_msg_avp_add (apn_configuration, MSG_BRW_LAST_CHILD, bandwidth));
      }
      CHECK_FCT (fd_msg_avp_add (apn_profile, MSG_BRW_LAST_CHILD, apn_configuration));
    }

    CHECK_FCT (fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, apn_profile));
  }

  /*
   * Subscribed-Periodic-RAU-TAU-Timer
   */
  CHECK_FCT (fd_msg_avp_new (s6a_cnf.dataobj_s6a_subscribed_rau_tau_timer, 0, &child_avp));
  /*
   * Request an RAU/TAU update every x seconds
   */
  value.u32 = (uint32_t) mysql_ans->rau_tau;
  CHECK_FCT (fd_msg_avp_setvalue (child_avp, &value));
  CHECK_FCT (fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, child_avp));
  /*
   * Add the AVP to the message
   */
  CHECK_FCT (fd_msg_avp_add (message, MSG_BRW_LAST_CHILD, avp));
out:

  if (pdns) {
    free (pdns);
  }

  return ret;
}