Navigation


Changeset 114:5b3868944e2b in freeDiameter


Ignore:
Timestamp:
Dec 8, 2009, 4:55:18 PM (14 years ago)
Author:
Sebastien Decugis <sdecugis@nict.go.jp>
Branch:
default
Phase:
public
Message:

Reporting errors in parse_dict function

Files:
5 edited

Legend:

Unmodified
Added
Removed
  • freeDiameter/messages.c

    r103 r114  
    293293        /* Parse the message against our dictionary */
    294294        ret = fd_msg_parse_rules ( m, fd_g_config->cnf_dict, &pei);
    295         if (ret != EBADMSG)
     295        if      ((ret != EBADMSG)       /* Parsing grouped AVP failed / Conflicting rule found */
     296                && (ret != ENOTSUP))    /* Command is not supported / Mandatory AVP is not supported */
    296297                return ret;
    297298       
    298         fd_log_debug("The following message does not comply to the dictionary and rules (%s):\n", pei.pei_errcode);
     299        fd_log_debug("The following message does not comply to the dictionary and/or rules (%s):\n", pei.pei_errcode);
    299300        fd_msg_dump_walk(NONE, m);
    300301       
  • freeDiameter/routing.c

    r104 r114  
    385385                                                case AC_DESTINATION_HOST:
    386386                                                        /* Parse this AVP */
    387                                                         CHECK_FCT_DO( fd_msg_parse_dict ( avp, fd_g_config->cnf_dict ), goto fatal_error );
     387                                                        CHECK_FCT_DO( fd_msg_parse_dict ( avp, fd_g_config->cnf_dict, NULL ), goto fatal_error );
    388388                                                        ASSERT( ahdr->avp_value );
    389389                                                        /* Compare the Destination-Host AVP of the message with our identity */
     
    398398                                                case AC_DESTINATION_REALM:
    399399                                                        /* Parse this AVP */
    400                                                         CHECK_FCT_DO( fd_msg_parse_dict ( avp, fd_g_config->cnf_dict ), goto fatal_error );
     400                                                        CHECK_FCT_DO( fd_msg_parse_dict ( avp, fd_g_config->cnf_dict, NULL ), goto fatal_error );
    401401                                                        ASSERT( ahdr->avp_value );
    402402                                                        dr_val = ahdr->avp_value;
     
    412412                                                case AC_USER_NAME:
    413413                                                        /* Parse this AVP */
    414                                                         CHECK_FCT_DO( fd_msg_parse_dict ( avp, fd_g_config->cnf_dict ), goto fatal_error );
     414                                                        CHECK_FCT_DO( fd_msg_parse_dict ( avp, fd_g_config->cnf_dict, NULL ), goto fatal_error );
    415415                                                        ASSERT( ahdr->avp_value );
    416416                                                        un = avp;
     
    656656                                if ((ahdr->avp_code == AC_ROUTE_RECORD) && (! (ahdr->avp_flags & AVP_FLAG_VENDOR)) ) {
    657657                                        /* Parse this AVP */
    658                                         CHECK_FCT_DO( fd_msg_parse_dict ( avp, fd_g_config->cnf_dict ), goto fatal_error );
     658                                        CHECK_FCT_DO( fd_msg_parse_dict ( avp, fd_g_config->cnf_dict, NULL ), goto fatal_error );
    659659                                        ASSERT( ahdr->avp_value );
    660660                                        /* Remove this value from the list */
     
    796796                                case AC_DESTINATION_HOST:
    797797                                        /* Parse this AVP */
    798                                         CHECK_FCT( fd_msg_parse_dict ( avp, fd_g_config->cnf_dict ) );
     798                                        CHECK_FCT( fd_msg_parse_dict ( avp, fd_g_config->cnf_dict, NULL ) );
    799799                                        ASSERT( ahdr->avp_value );
    800800                                        dh = ahdr->avp_value;
     
    803803                                case AC_DESTINATION_REALM:
    804804                                        /* Parse this AVP */
    805                                         CHECK_FCT( fd_msg_parse_dict ( avp, fd_g_config->cnf_dict ) );
     805                                        CHECK_FCT( fd_msg_parse_dict ( avp, fd_g_config->cnf_dict, NULL ) );
    806806                                        ASSERT( ahdr->avp_value );
    807807                                        dr = ahdr->avp_value;
  • freeDiameter/tests/testmesg.c

    r35 r114  
    687687                                buf_cpy[5] = 0x11;
    688688                                CHECK( 0, fd_msg_parse_buffer( &buf_cpy, 344, &msg) );
    689                                 CHECK( ENOTSUP, fd_msg_parse_dict( msg, fd_g_config->cnf_dict ) );
     689                                CHECK( ENOTSUP, fd_msg_parse_dict( msg, fd_g_config->cnf_dict, NULL ) );
    690690                               
    691691                                /* reset */
     
    702702                                /* Check that we cannot support this message now */
    703703                                CHECK( 0, fd_msg_parse_buffer( &buf_cpy, 344, &msg) );
    704                                 CHECK( ENOTSUP, fd_msg_parse_dict( msg, fd_g_config->cnf_dict ) );
     704                                CHECK( ENOTSUP, fd_msg_parse_dict( msg, fd_g_config->cnf_dict, NULL ) );
    705705                               
    706706                                /* reset */
     
    716716                                /* Check that we can support this message now */
    717717                                CHECK( 0, fd_msg_parse_buffer( &buf_cpy, 344, &msg) );
    718                                 CHECK( 0, fd_msg_parse_dict( msg, fd_g_config->cnf_dict ) );
     718                                CHECK( 0, fd_msg_parse_dict( msg, fd_g_config->cnf_dict, NULL ) );
    719719                               
    720720                                #if 0
     
    727727                       
    728728                        CHECK( 0, fd_msg_parse_buffer( &buf, 344, &msg) );
    729                         CHECK( 0, fd_msg_parse_dict( msg, fd_g_config->cnf_dict ) );
     729                        CHECK( 0, fd_msg_parse_dict( msg, fd_g_config->cnf_dict, NULL ) );
    730730                        #if 0
    731731                        fd_msg_dump_walk(0, msg);
     
    964964                /* Ok, now let's recreate the message */
    965965                CHECK( 0, fd_msg_parse_buffer( &buf, 64, &cer) );
    966                 CHECK( 0, fd_msg_parse_dict( cer, fd_g_config->cnf_dict ) );
     966                CHECK( 0, fd_msg_parse_dict( cer, fd_g_config->cnf_dict, NULL ) );
    967967               
    968968                /* Get the pointers to the first and last AVP */
     
    11941194                       
    11951195                        CHECK( 0, fd_msg_parse_buffer( &buf, 148, &msg) );
    1196                         CHECK( 0, fd_msg_parse_dict( msg, fd_g_config->cnf_dict ) );
     1196                        CHECK( 0, fd_msg_parse_dict( msg, fd_g_config->cnf_dict, NULL ) );
    11971197                        #if 0
    11981198                        fd_msg_dump_walk(0, msg);
  • include/freeDiameter/libfreeDiameter.h

    r112 r114  
    21802180int fd_msg_parse_buffer ( unsigned char ** buffer, size_t buflen, struct msg ** msg );
    21812181
     2182/* Parsing Error Information structure */
     2183struct fd_pei {
     2184        char *          pei_errcode;    /* name of the error code to use */
     2185        struct avp *    pei_avp;        /* pointer to invalid or missing AVP (to be freed) */
     2186        char *          pei_message;    /* Overwrite default message if needed */
     2187        int             pei_protoerr;   /* do we set the 'E' bit in the error message ? */
     2188};
     2189
    21822190/*
    21832191 * FUNCTION:    fd_msg_parse_dict
     
    21862194 *  object      : A msg or AVP object as returned by fd_msg_parse_buffer.
    21872195 *  dict        : the dictionary containing the objects definitions to use for resolving all AVPs.
     2196 *  error_info  : If not NULL, will contain the detail about error upon return. May be used to generate an error reply.
    21882197 *
    21892198 * DESCRIPTION:
     
    22032212 *  ENOTSUP     : No dictionary definition for the command or one of the mandatory AVP was found.
    22042213 */
    2205 int fd_msg_parse_dict ( msg_or_avp * object, struct dictionary * dict );
    2206 
    2207 /* Parsing Error Information structure */
    2208 struct fd_pei {
    2209         char *          pei_errcode;    /* name of the error code to use */
    2210         struct avp *    pei_avp;        /* pointer to invalid or missing AVP (to be freed) */
    2211         char *          pei_message;    /* Overwrite default message if needed */
    2212         int             pei_protoerr;   /* do we set the 'E' bit in the error message ? */
    2213 };
     2214int fd_msg_parse_dict ( msg_or_avp * object, struct dictionary * dict, struct fd_pei *error_info );
    22142215
    22152216/*
  • libfreeDiameter/messages.c

    r112 r114  
    157157
    158158/* Forward declaration */
    159 static int parsedict_do_msg(struct dictionary * dict, struct msg * msg, int only_hdr);
     159static int parsedict_do_msg(struct dictionary * dict, struct msg * msg, int only_hdr, struct fd_pei *error_info);
    160160
    161161/***************************************************************************************************************/
     
    307307        } else {
    308308                /* The model is the answer corresponding to the query. It supposes that these are defined in the dictionary */
    309                 CHECK_FCT_DO(  parsedict_do_msg( dict, qry, 1), /* continue */  );
     309                CHECK_FCT_DO(  parsedict_do_msg( dict, qry, 1, NULL), /* continue */  );
    310310                if (qry->msg_model) {
    311311                        CHECK_FCT(  fd_dict_search ( dict, DICT_COMMAND, CMD_ANSWER, qry->msg_model, &model, EINVAL )  );
     
    551551                struct dictionary * dict;
    552552                CHECK_FCT( fd_dict_getdict( what, &dict) );
    553                 CHECK_FCT_DO( fd_msg_parse_dict( nextavp, dict ), /* nothing */ );
     553                CHECK_FCT_DO( fd_msg_parse_dict( nextavp, dict, NULL ), /* nothing */ );
    554554        }
    555555       
     
    11931193       
    11941194        if (!avp->avp_model) {
    1195                 CHECK_FCT( fd_msg_parse_dict ( avp, dict ) );
     1195                CHECK_FCT( fd_msg_parse_dict ( avp, dict, NULL ) );
    11961196        }
    11971197       
     
    16961696 */
    16971697
    1698 static int parsedict_do_chain(struct dictionary * dict, struct fd_list * head, int mandatory);
     1698static int parsedict_do_chain(struct dictionary * dict, struct fd_list * head, int mandatory, struct fd_pei *error_info);
    16991699
    17001700/* Process an AVP. If we are not in recheck, the avp_source must be set. */
    1701 static int parsedict_do_avp(struct dictionary * dict, struct avp * avp, int mandatory)
     1701static int parsedict_do_avp(struct dictionary * dict, struct avp * avp, int mandatory, struct fd_pei *error_info)
    17021702{
    17031703        struct dict_avp_data dictdata;
    17041704       
    1705         TRACE_ENTRY("%p %p %d", dict, avp, mandatory);
     1705        TRACE_ENTRY("%p %p %d %p", dict, avp, mandatory, error_info);
    17061706       
    17071707        /* First check we received an AVP as input */
     
    17151715                if ( avp->avp_public.avp_code == dictdata.avp_code  ) {
    17161716                        /* Ok then just process the children if any */
    1717                         return parsedict_do_chain(dict, &avp->avp_chain.children, mandatory && (avp->avp_public.avp_flags & AVP_FLAG_MANDATORY));
     1717                        return parsedict_do_chain(dict, &avp->avp_chain.children, mandatory && (avp->avp_public.avp_flags & AVP_FLAG_MANDATORY), error_info);
    17181718                } else {
    17191719                        /* We just erase the old model */
     
    17391739                        TRACE_DEBUG(INFO, "Unsupported mandatory AVP found:");
    17401740                        msg_dump_intern(INFO, avp, 2);
     1741                        if (error_info) {
     1742                                error_info->pei_errcode = "DIAMETER_AVP_UNSUPPORTED";
     1743                                error_info->pei_avp = avp;
     1744                        }
    17411745                        return ENOTSUP;
    17421746                }
     
    17741778        if ((avp_value_sizes[dictdata.avp_basetype] != 0) &&
    17751779            (avp->avp_public.avp_len - GETAVPHDRSZ( avp->avp_public.avp_flags ) != avp_value_sizes[dictdata.avp_basetype])) {
    1776                 TRACE_DEBUG(INFO, "The AVP size is not suitable for the type. EBADMSG.");
     1780                TRACE_DEBUG(INFO, "The AVP size is not suitable for the type.");
     1781                if (error_info) {
     1782                        error_info->pei_errcode = "DIAMETER_INVALID_AVP_LENGTH";
     1783                        error_info->pei_avp = avp;
     1784                }
    17771785                return EBADMSG;
    17781786        }
     
    17801788        /* Now get the value inside */
    17811789        switch (dictdata.avp_basetype) {
    1782                 case AVP_TYPE_GROUPED:
     1790                case AVP_TYPE_GROUPED: {
     1791                        int ret;
     1792                       
    17831793                        /* This is a grouped AVP, so let's parse the list of AVPs inside */
    1784                         CHECK_FCT(  parsebuf_list(avp->avp_source, avp->avp_public.avp_len - GETAVPHDRSZ( avp->avp_public.avp_flags ), &avp->avp_chain.children)  );
    1785                        
    1786                         return parsedict_do_chain(dict, &avp->avp_chain.children, mandatory && (avp->avp_public.avp_flags & AVP_FLAG_MANDATORY));
     1794                        CHECK_FCT_DO(  ret = parsebuf_list(avp->avp_source, avp->avp_public.avp_len - GETAVPHDRSZ( avp->avp_public.avp_flags ), &avp->avp_chain.children),
     1795                                {
     1796                                        if ((ret == EBADMSG) && (error_info)) {
     1797                                                error_info->pei_errcode = "DIAMETER_INVALID_AVP_VALUE";
     1798                                                error_info->pei_avp = avp;
     1799                                        }
     1800                                        return ret;
     1801                                }  );
     1802                       
     1803                        return parsedict_do_chain(dict, &avp->avp_chain.children, mandatory && (avp->avp_public.avp_flags & AVP_FLAG_MANDATORY), error_info);
     1804                }
    17871805                       
    17881806                case AVP_TYPE_OCTETSTRING:
    17891807                        /* We just have to copy the string into the storage area */
    1790                         CHECK_PARAMS( avp->avp_public.avp_len > GETAVPHDRSZ( avp->avp_public.avp_flags ) );
     1808                        CHECK_PARAMS_DO( avp->avp_public.avp_len > GETAVPHDRSZ( avp->avp_public.avp_flags ),
     1809                                {
     1810                                        if (error_info) {
     1811                                                error_info->pei_errcode = "DIAMETER_INVALID_AVP_LENGTH";
     1812                                                error_info->pei_avp = avp;
     1813                                        }
     1814                                        return EBADMSG;
     1815                                } );
    17911816                        avp->avp_storage.os.len = avp->avp_public.avp_len - GETAVPHDRSZ( avp->avp_public.avp_flags );
    17921817                        CHECK_MALLOC(  avp->avp_storage.os.data = malloc(avp->avp_storage.os.len)  );
     
    18211846
    18221847/* Process a list of AVPs */
    1823 static int parsedict_do_chain(struct dictionary * dict, struct fd_list * head, int mandatory)
     1848static int parsedict_do_chain(struct dictionary * dict, struct fd_list * head, int mandatory, struct fd_pei *error_info)
    18241849{
    18251850        struct fd_list * avpch;
    18261851       
    1827         TRACE_ENTRY("%p %p %d", dict, head, mandatory);
     1852        TRACE_ENTRY("%p %p %d %p", dict, head, mandatory, error_info);
    18281853       
    18291854        /* Sanity check */
     
    18321857        /* Now process the list */
    18331858        for (avpch=head->next; avpch != head; avpch = avpch->next) {
    1834                 CHECK_FCT(  parsedict_do_avp(dict, _A(avpch->o), mandatory)  );
     1859                CHECK_FCT(  parsedict_do_avp(dict, _A(avpch->o), mandatory, error_info)  );
    18351860        }
    18361861       
     
    18401865
    18411866/* Process a msg header. */
    1842 static int parsedict_do_msg(struct dictionary * dict, struct msg * msg, int only_hdr)
     1867static int parsedict_do_msg(struct dictionary * dict, struct msg * msg, int only_hdr, struct fd_pei *error_info)
    18431868{
    18441869        int ret = 0;
    18451870       
    1846         TRACE_ENTRY("%p %p %d", dict, msg, only_hdr);
     1871        TRACE_ENTRY("%p %p %d %p", dict, msg, only_hdr, error_info);
    18471872       
    18481873        CHECK_PARAMS(  CHECK_MSG(msg)  );
    18491874       
    18501875        /* Look for the model from the header */
    1851         CHECK_FCT( fd_dict_search ( dict, DICT_COMMAND,
     1876        CHECK_FCT_DO( ret = fd_dict_search ( dict, DICT_COMMAND,
    18521877                        (msg->msg_public.msg_flags & CMD_FLAG_REQUEST) ? CMD_BY_CODE_R : CMD_BY_CODE_A,
    18531878                        &msg->msg_public.msg_code,
    1854                         &msg->msg_model, ENOTSUP) );
     1879                        &msg->msg_model, ENOTSUP),
     1880                {
     1881                        if ((ret == ENOTSUP) && (error_info)) {
     1882                                error_info->pei_errcode = "DIAMETER_COMMAND_UNSUPPORTED";
     1883                                error_info->pei_protoerr = 1;
     1884                        }
     1885                        return ret;
     1886                } );
    18551887       
    18561888        if (!only_hdr) {
    18571889                /* Then process the children */
    1858                 ret = parsedict_do_chain(dict, &msg->msg_chain.children, 1);
     1890                ret = parsedict_do_chain(dict, &msg->msg_chain.children, 1, error_info);
    18591891
    18601892                /* Free the raw buffer if any */
     
    18681900}
    18691901
    1870 int fd_msg_parse_dict ( msg_or_avp * object, struct dictionary * dict )
    1871 {
    1872         TRACE_ENTRY("%p %p", dict, object);
     1902int fd_msg_parse_dict ( msg_or_avp * object, struct dictionary * dict, struct fd_pei *error_info )
     1903{
     1904        TRACE_ENTRY("%p %p %p", dict, object, error_info);
    18731905       
    18741906        CHECK_PARAMS(  VALIDATE_OBJ(object)  );
     1907       
     1908        if (error_info)
     1909                memset(error_info, 0, sizeof(struct fd_pei));
    18751910       
    18761911        switch (_C(object)->type) {
    18771912                case MSG_MSG:
    1878                         return parsedict_do_msg(dict, _M(object), 0);
     1913                        return parsedict_do_msg(dict, _M(object), 0, error_info);
    18791914               
    18801915                case MSG_AVP:
    1881                         return parsedict_do_avp(dict, _A(object), 0);
     1916                        return parsedict_do_avp(dict, _A(object), 0, error_info);
    18821917               
    18831918                default:
     
    21572192       
    21582193        /* Resolve the dictionary objects when missing. This also validates the object. */
    2159         CHECK_FCT(  fd_msg_parse_dict ( object, dict )  );
     2194        CHECK_FCT(  fd_msg_parse_dict ( object, dict, error_info )  );
    21602195       
    21612196        /* Call the recursive function */
Note: See TracChangeset for help on using the changeset viewer.