int decode_tracking_area_identity_list(TrackingAreaIdentityList *trackingareaidentitylist, uint8_t iei, uint8_t *buffer, uint32_t len)
{
  int decoded = 0;
  uint8_t ielen = 0;

  if (iei > 0) {
    CHECK_IEI_DECODER(iei, *buffer);
    decoded++;
  }

  ielen = *(buffer + decoded);
  decoded++;
  CHECK_LENGTH_DECODER(len - decoded, ielen);
  trackingareaidentitylist->typeoflist = (*(buffer + decoded) >> 5) & 0x3;
  trackingareaidentitylist->numberofelements = *(buffer + decoded) & 0x1f;
  decoded++;
  trackingareaidentitylist->mccdigit2 = (*(buffer + decoded) >> 4) & 0xf;
  trackingareaidentitylist->mccdigit1 = *(buffer + decoded) & 0xf;
  decoded++;
  trackingareaidentitylist->mncdigit3 = (*(buffer + decoded) >> 4) & 0xf;
  trackingareaidentitylist->mccdigit3 = *(buffer + decoded) & 0xf;
  decoded++;
  trackingareaidentitylist->mncdigit2 = (*(buffer + decoded) >> 4) & 0xf;
  trackingareaidentitylist->mncdigit1 = *(buffer + decoded) & 0xf;
  decoded++;
  //IES_DECODE_U16(trackingareaidentitylist->tac, *(buffer + decoded));
  IES_DECODE_U16(buffer, decoded, trackingareaidentitylist->tac);
#if defined (NAS_DEBUG)
  dump_tracking_area_identity_list_xml(trackingareaidentitylist, iei);
#endif
  return decoded;
}
int decode_tracking_area_identity(TrackingAreaIdentity *trackingareaidentity, uint8_t iei, uint8_t *buffer, uint32_t len)
{
  int decoded = 0;

  if (iei > 0) {
    CHECK_IEI_DECODER(iei, *buffer);
    decoded++;
  }

  trackingareaidentity->mccdigit2 = (*(buffer + decoded) >> 4) & 0xf;
  trackingareaidentity->mccdigit1 = *(buffer + decoded) & 0xf;
  decoded++;
  trackingareaidentity->mncdigit3 = (*(buffer + decoded) >> 4) & 0xf;
  trackingareaidentity->mccdigit3 = *(buffer + decoded) & 0xf;
  decoded++;
  trackingareaidentity->mncdigit2 = (*(buffer + decoded) >> 4) & 0xf;
  trackingareaidentity->mncdigit1 = *(buffer + decoded) & 0xf;
  decoded++;
  //IES_DECODE_U16(trackingareaidentity->tac, *(buffer + decoded));
  IES_DECODE_U16(buffer, decoded, trackingareaidentity->tac);
#if defined (NAS_DEBUG)
  dump_tracking_area_identity_xml(trackingareaidentity, iei);
#endif
  return decoded;
}
示例#3
0
int decode_short_mac(ShortMac *shortmac, uint8_t iei, uint8_t *buffer, uint32_t len)
{
  int decoded = 0;

  if (iei > 0) {
    CHECK_IEI_DECODER(iei, *buffer);
    decoded++;
  }

  //IES_DECODE_U16(*shortmac, *(buffer + decoded));
  IES_DECODE_U16(buffer, decoded, *shortmac);
#if defined (NAS_DEBUG)
  dump_short_mac_xml(shortmac, iei);
#endif
  return decoded;
}
int decode_location_area_identification(LocationAreaIdentification *locationareaidentification, uint8_t iei, uint8_t *buffer, uint32_t len)
{
    int decoded = 0;
    if (iei > 0)
    {
        CHECK_IEI_DECODER(iei, *buffer);
        decoded++;
    }
    locationareaidentification->mccdigit2 = (*(buffer + decoded) >> 4) & 0xf;
    locationareaidentification->mccdigit1 = *(buffer + decoded) & 0xf;
    decoded++;
    locationareaidentification->mncdigit3 = (*(buffer + decoded) >> 4) & 0xf;
    locationareaidentification->mccdigit3 = *(buffer + decoded) & 0xf;
    decoded++;
    locationareaidentification->mncdigit2 = (*(buffer + decoded) >> 4) & 0xf;
    locationareaidentification->mncdigit1 = *(buffer + decoded) & 0xf;
    decoded++;
    //IES_DECODE_U16(locationareaidentification->lac, *(buffer + decoded));
    IES_DECODE_U16(buffer, decoded, locationareaidentification->lac);
#if defined (NAS_DEBUG)
    dump_location_area_identification_xml(locationareaidentification, iei);
#endif
    return decoded;
}
static int decode_traffic_flow_template_packet_filters(PacketFilters* packetfilters, uint8_t nbpacketfilters, uint8_t *buffer, uint32_t len)
{
    int decoded = 0, i, j;

    for (i = 0; (i < nbpacketfilters); i++)
    {
	if (len - decoded <= 0) {
	    /* Mismatch between the number of packet filters subfield,
	     * and the number of packet filters in the packet filter list */
	    return (TLV_DECODE_VALUE_DOESNT_MATCH);
	}
	/* Initialize the packet filter presence flag indicator */
	(*packetfilters)[i].packetfilter.flags = 0;
	/* Packet filter direction */
	(*packetfilters)[i].direction = *(buffer + decoded) >> 4;
	/* Packet filter identifier */
	(*packetfilters)[i].identifier = *(buffer + decoded) & 0x0f;
	decoded++;
	/* Packet filter evaluation precedence  */
	IES_DECODE_U8(buffer, decoded, (*packetfilters)[i].eval_precedence);
	/* Length of the Packet filter contents field  */
	uint8_t pkflen;
	IES_DECODE_U8(buffer, decoded, pkflen);
	/* Packet filter contents */
	int pkfstart = decoded;
	while (decoded - pkfstart < pkflen)
	{
	    /* Packet filter component type identifier */
	    uint8_t component_type;
	    IES_DECODE_U8(buffer, decoded, component_type);

	    switch (component_type)
	    {
		case TRAFFIC_FLOW_TEMPLATE_IPV4_REMOTE_ADDR:
		    /* IPv4 remote address type */
		    (*packetfilters)[i].packetfilter.flags |= TRAFFIC_FLOW_TEMPLATE_IPV4_REMOTE_ADDR_FLAG;
		    for (j = 0; j < TRAFFIC_FLOW_TEMPLATE_IPV4_ADDR_SIZE; j++)
		    {
			(*packetfilters)[i].packetfilter.ipv4remoteaddr[j].addr = *(buffer + decoded);
			(*packetfilters)[i].packetfilter.ipv4remoteaddr[j].mask = *(buffer + decoded + TRAFFIC_FLOW_TEMPLATE_IPV4_ADDR_SIZE);
			decoded++;
		    }
		    decoded += TRAFFIC_FLOW_TEMPLATE_IPV4_ADDR_SIZE;
		    break;

		case TRAFFIC_FLOW_TEMPLATE_IPV6_REMOTE_ADDR:
		    /* IPv6 remote address type */
		    (*packetfilters)[i].packetfilter.flags |= TRAFFIC_FLOW_TEMPLATE_IPV6_REMOTE_ADDR_FLAG;
		    for (j = 0; j < TRAFFIC_FLOW_TEMPLATE_IPV6_ADDR_SIZE; j++)
		    {
			(*packetfilters)[i].packetfilter.ipv6remoteaddr[j].addr = *(buffer + decoded);
			(*packetfilters)[i].packetfilter.ipv6remoteaddr[j].mask = *(buffer + decoded + TRAFFIC_FLOW_TEMPLATE_IPV6_ADDR_SIZE);
			decoded++;
		    }
		    decoded += TRAFFIC_FLOW_TEMPLATE_IPV6_ADDR_SIZE;
		    break;

		case TRAFFIC_FLOW_TEMPLATE_PROTOCOL_NEXT_HEADER:
		    /* Protocol identifier/Next header type */
		    (*packetfilters)[i].packetfilter.flags |= TRAFFIC_FLOW_TEMPLATE_PROTOCOL_NEXT_HEADER_FLAG;
		    IES_DECODE_U8(buffer, decoded, (*packetfilters)[i].packetfilter.protocolidentifier_nextheader);
		    break;

		case TRAFFIC_FLOW_TEMPLATE_SINGLE_LOCAL_PORT:
		    /* Single local port type */
		    (*packetfilters)[i].packetfilter.flags |= TRAFFIC_FLOW_TEMPLATE_SINGLE_LOCAL_PORT_FLAG;
		    IES_DECODE_U16(buffer, decoded, (*packetfilters)[i].packetfilter.singlelocalport);
		    break;

		case TRAFFIC_FLOW_TEMPLATE_LOCAL_PORT_RANGE:
		    /* Local port range type */
		    (*packetfilters)[i].packetfilter.flags |= TRAFFIC_FLOW_TEMPLATE_LOCAL_PORT_RANGE_FLAG;
		    IES_DECODE_U16(buffer, decoded, (*packetfilters)[i].packetfilter.localportrange.lowlimit);
		    IES_DECODE_U16(buffer, decoded, (*packetfilters)[i].packetfilter.localportrange.highlimit);
		    break;

		case TRAFFIC_FLOW_TEMPLATE_SINGLE_REMOTE_PORT:
		    /* Single remote port type */
		    (*packetfilters)[i].packetfilter.flags |=TRAFFIC_FLOW_TEMPLATE_SINGLE_REMOTE_PORT_FLAG ;
		    IES_DECODE_U16(buffer, decoded, (*packetfilters)[i].packetfilter.singleremoteport);
		    break;

		case TRAFFIC_FLOW_TEMPLATE_REMOTE_PORT_RANGE:
		    /* Remote port range type */
		    (*packetfilters)[i].packetfilter.flags |= TRAFFIC_FLOW_TEMPLATE_REMOTE_PORT_RANGE_FLAG;
		    IES_DECODE_U16(buffer, decoded, (*packetfilters)[i].packetfilter.remoteportrange.lowlimit);
		    IES_DECODE_U16(buffer, decoded, (*packetfilters)[i].packetfilter.remoteportrange.highlimit);
		    break;

		case TRAFFIC_FLOW_TEMPLATE_SECURITY_PARAMETER_INDEX:
		    /* Security parameter index type */
		    (*packetfilters)[i].packetfilter.flags |= TRAFFIC_FLOW_TEMPLATE_SECURITY_PARAMETER_INDEX_FLAG;
		    IES_DECODE_U32(buffer, decoded, (*packetfilters)[i].packetfilter.securityparameterindex);
		    break;

		case TRAFFIC_FLOW_TEMPLATE_TYPE_OF_SERVICE_TRAFFIC_CLASS:
		    /* Type of service/Traffic class type */
		    (*packetfilters)[i].packetfilter.flags |= TRAFFIC_FLOW_TEMPLATE_TYPE_OF_SERVICE_TRAFFIC_CLASS_FLAG;
		    IES_DECODE_U8(buffer, decoded, (*packetfilters)[i].packetfilter.typdeofservice_trafficclass.value);
		    IES_DECODE_U8(buffer, decoded, (*packetfilters)[i].packetfilter.typdeofservice_trafficclass.mask);
		    break;

		case TRAFFIC_FLOW_TEMPLATE_FLOW_LABEL:
		    /* Flow label type */
		    (*packetfilters)[i].packetfilter.flags |= TRAFFIC_FLOW_TEMPLATE_FLOW_LABEL_FLAG;
		    IES_DECODE_U24(buffer, decoded, (*packetfilters)[i].packetfilter.flowlabel);
		    break;

		default:
		    /* Packet filter component type identifier is not valid */
		    return (TLV_DECODE_UNEXPECTED_IEI);
		    break;
	    }
	}
    }

    if (len - decoded != 0) {
	/* Mismatch between the number of packet filters subfield,
	 * and the number of packet filters in the packet filter list */
	return (TLV_DECODE_VALUE_DOESNT_MATCH);
    }
    return decoded;
}