Changeset 114:5b3868944e2b in freeDiameter
- Timestamp:
- Dec 8, 2009, 4:55:18 PM (14 years ago)
- Branch:
- default
- Phase:
- public
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
freeDiameter/messages.c
r103 r114 293 293 /* Parse the message against our dictionary */ 294 294 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 */ 296 297 return ret; 297 298 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); 299 300 fd_msg_dump_walk(NONE, m); 300 301 -
freeDiameter/routing.c
r104 r114 385 385 case AC_DESTINATION_HOST: 386 386 /* 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 ); 388 388 ASSERT( ahdr->avp_value ); 389 389 /* Compare the Destination-Host AVP of the message with our identity */ … … 398 398 case AC_DESTINATION_REALM: 399 399 /* 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 ); 401 401 ASSERT( ahdr->avp_value ); 402 402 dr_val = ahdr->avp_value; … … 412 412 case AC_USER_NAME: 413 413 /* 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 ); 415 415 ASSERT( ahdr->avp_value ); 416 416 un = avp; … … 656 656 if ((ahdr->avp_code == AC_ROUTE_RECORD) && (! (ahdr->avp_flags & AVP_FLAG_VENDOR)) ) { 657 657 /* 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 ); 659 659 ASSERT( ahdr->avp_value ); 660 660 /* Remove this value from the list */ … … 796 796 case AC_DESTINATION_HOST: 797 797 /* 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 ) ); 799 799 ASSERT( ahdr->avp_value ); 800 800 dh = ahdr->avp_value; … … 803 803 case AC_DESTINATION_REALM: 804 804 /* 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 ) ); 806 806 ASSERT( ahdr->avp_value ); 807 807 dr = ahdr->avp_value; -
freeDiameter/tests/testmesg.c
r35 r114 687 687 buf_cpy[5] = 0x11; 688 688 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 ) ); 690 690 691 691 /* reset */ … … 702 702 /* Check that we cannot support this message now */ 703 703 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 ) ); 705 705 706 706 /* reset */ … … 716 716 /* Check that we can support this message now */ 717 717 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 ) ); 719 719 720 720 #if 0 … … 727 727 728 728 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 ) ); 730 730 #if 0 731 731 fd_msg_dump_walk(0, msg); … … 964 964 /* Ok, now let's recreate the message */ 965 965 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 ) ); 967 967 968 968 /* Get the pointers to the first and last AVP */ … … 1194 1194 1195 1195 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 ) ); 1197 1197 #if 0 1198 1198 fd_msg_dump_walk(0, msg); -
include/freeDiameter/libfreeDiameter.h
r112 r114 2180 2180 int fd_msg_parse_buffer ( unsigned char ** buffer, size_t buflen, struct msg ** msg ); 2181 2181 2182 /* Parsing Error Information structure */ 2183 struct 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 2182 2190 /* 2183 2191 * FUNCTION: fd_msg_parse_dict … … 2186 2194 * object : A msg or AVP object as returned by fd_msg_parse_buffer. 2187 2195 * 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. 2188 2197 * 2189 2198 * DESCRIPTION: … … 2203 2212 * ENOTSUP : No dictionary definition for the command or one of the mandatory AVP was found. 2204 2213 */ 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 }; 2214 int fd_msg_parse_dict ( msg_or_avp * object, struct dictionary * dict, struct fd_pei *error_info ); 2214 2215 2215 2216 /* -
libfreeDiameter/messages.c
r112 r114 157 157 158 158 /* Forward declaration */ 159 static int parsedict_do_msg(struct dictionary * dict, struct msg * msg, int only_hdr );159 static int parsedict_do_msg(struct dictionary * dict, struct msg * msg, int only_hdr, struct fd_pei *error_info); 160 160 161 161 /***************************************************************************************************************/ … … 307 307 } else { 308 308 /* 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 */ ); 310 310 if (qry->msg_model) { 311 311 CHECK_FCT( fd_dict_search ( dict, DICT_COMMAND, CMD_ANSWER, qry->msg_model, &model, EINVAL ) ); … … 551 551 struct dictionary * dict; 552 552 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 */ ); 554 554 } 555 555 … … 1193 1193 1194 1194 if (!avp->avp_model) { 1195 CHECK_FCT( fd_msg_parse_dict ( avp, dict ) );1195 CHECK_FCT( fd_msg_parse_dict ( avp, dict, NULL ) ); 1196 1196 } 1197 1197 … … 1696 1696 */ 1697 1697 1698 static int parsedict_do_chain(struct dictionary * dict, struct fd_list * head, int mandatory );1698 static int parsedict_do_chain(struct dictionary * dict, struct fd_list * head, int mandatory, struct fd_pei *error_info); 1699 1699 1700 1700 /* 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 )1701 static int parsedict_do_avp(struct dictionary * dict, struct avp * avp, int mandatory, struct fd_pei *error_info) 1702 1702 { 1703 1703 struct dict_avp_data dictdata; 1704 1704 1705 TRACE_ENTRY("%p %p %d ", dict, avp, mandatory);1705 TRACE_ENTRY("%p %p %d %p", dict, avp, mandatory, error_info); 1706 1706 1707 1707 /* First check we received an AVP as input */ … … 1715 1715 if ( avp->avp_public.avp_code == dictdata.avp_code ) { 1716 1716 /* 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); 1718 1718 } else { 1719 1719 /* We just erase the old model */ … … 1739 1739 TRACE_DEBUG(INFO, "Unsupported mandatory AVP found:"); 1740 1740 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 } 1741 1745 return ENOTSUP; 1742 1746 } … … 1774 1778 if ((avp_value_sizes[dictdata.avp_basetype] != 0) && 1775 1779 (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 } 1777 1785 return EBADMSG; 1778 1786 } … … 1780 1788 /* Now get the value inside */ 1781 1789 switch (dictdata.avp_basetype) { 1782 case AVP_TYPE_GROUPED: 1790 case AVP_TYPE_GROUPED: { 1791 int ret; 1792 1783 1793 /* 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 } 1787 1805 1788 1806 case AVP_TYPE_OCTETSTRING: 1789 1807 /* 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 } ); 1791 1816 avp->avp_storage.os.len = avp->avp_public.avp_len - GETAVPHDRSZ( avp->avp_public.avp_flags ); 1792 1817 CHECK_MALLOC( avp->avp_storage.os.data = malloc(avp->avp_storage.os.len) ); … … 1821 1846 1822 1847 /* Process a list of AVPs */ 1823 static int parsedict_do_chain(struct dictionary * dict, struct fd_list * head, int mandatory )1848 static int parsedict_do_chain(struct dictionary * dict, struct fd_list * head, int mandatory, struct fd_pei *error_info) 1824 1849 { 1825 1850 struct fd_list * avpch; 1826 1851 1827 TRACE_ENTRY("%p %p %d ", dict, head, mandatory);1852 TRACE_ENTRY("%p %p %d %p", dict, head, mandatory, error_info); 1828 1853 1829 1854 /* Sanity check */ … … 1832 1857 /* Now process the list */ 1833 1858 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) ); 1835 1860 } 1836 1861 … … 1840 1865 1841 1866 /* Process a msg header. */ 1842 static int parsedict_do_msg(struct dictionary * dict, struct msg * msg, int only_hdr )1867 static int parsedict_do_msg(struct dictionary * dict, struct msg * msg, int only_hdr, struct fd_pei *error_info) 1843 1868 { 1844 1869 int ret = 0; 1845 1870 1846 TRACE_ENTRY("%p %p %d ", dict, msg, only_hdr);1871 TRACE_ENTRY("%p %p %d %p", dict, msg, only_hdr, error_info); 1847 1872 1848 1873 CHECK_PARAMS( CHECK_MSG(msg) ); 1849 1874 1850 1875 /* 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, 1852 1877 (msg->msg_public.msg_flags & CMD_FLAG_REQUEST) ? CMD_BY_CODE_R : CMD_BY_CODE_A, 1853 1878 &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 } ); 1855 1887 1856 1888 if (!only_hdr) { 1857 1889 /* 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); 1859 1891 1860 1892 /* Free the raw buffer if any */ … … 1868 1900 } 1869 1901 1870 int fd_msg_parse_dict ( msg_or_avp * object, struct dictionary * dict )1871 { 1872 TRACE_ENTRY("%p %p ", dict, object);1902 int 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); 1873 1905 1874 1906 CHECK_PARAMS( VALIDATE_OBJ(object) ); 1907 1908 if (error_info) 1909 memset(error_info, 0, sizeof(struct fd_pei)); 1875 1910 1876 1911 switch (_C(object)->type) { 1877 1912 case MSG_MSG: 1878 return parsedict_do_msg(dict, _M(object), 0 );1913 return parsedict_do_msg(dict, _M(object), 0, error_info); 1879 1914 1880 1915 case MSG_AVP: 1881 return parsedict_do_avp(dict, _A(object), 0 );1916 return parsedict_do_avp(dict, _A(object), 0, error_info); 1882 1917 1883 1918 default: … … 2157 2192 2158 2193 /* 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 ) ); 2160 2195 2161 2196 /* Call the recursive function */
Note: See TracChangeset
for help on using the changeset viewer.