"Fossies" - the Fresh Open Source Software Archive

Member "snort-2.9.17/src/dynamic-preprocessors/appid/service_plugins/service_base.c" (16 Oct 2020, 94854 Bytes) of package /linux/misc/snort-2.9.17.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "service_base.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.9.16.1_vs_2.9.17.

    1 /*
    2 ** Copyright (C) 2014-2020 Cisco and/or its affiliates. All rights reserved.
    3 ** Copyright (C) 2005-2013 Sourcefire, Inc.
    4 **
    5 ** This program is free software; you can redistribute it and/or modify
    6 ** it under the terms of the GNU General Public License Version 2 as
    7 ** published by the Free Software Foundation.  You may not use, modify or
    8 ** distribute this program under any other version of the GNU General
    9 ** Public License.
   10 **
   11 ** This program is distributed in the hope that it will be useful,
   12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
   13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14 ** GNU General Public License for more details.
   15 **
   16 ** You should have received a copy of the GNU General Public License
   17 ** along with this program; if not, write to the Free Software
   18 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   19 */
   20 
   21 
   22 /**
   23  * @file   service_base.c
   24  * @author Ron Dempster <Ron.Dempster@sourcefire.com>
   25  *
   26  */
   27 
   28 #include <time.h>
   29 #include <string.h>
   30 #include <stdlib.h>
   31 #include <limits.h>
   32 #include <sys/socket.h>
   33 #include <netinet/in.h>
   34 #include <arpa/inet.h>
   35 
   36 #include "common_util.h"
   37 #include "service_base.h"
   38 #include "service_state.h"
   39 #include "service_api.h"
   40 #include "service_bgp.h"
   41 #include "service_bootp.h"
   42 #include "detector_cip.h"
   43 #include "service_dcerpc.h"
   44 #include "service_flap.h"
   45 #include "service_ftp.h"
   46 #include "service_irc.h"
   47 #include "service_lpr.h"
   48 #include "service_mysql.h"
   49 #include "service_netbios.h"
   50 #include "service_nntp.h"
   51 #include "service_ntp.h"
   52 #include "service_radius.h"
   53 #include "service_rexec.h"
   54 #include "service_rfb.h"
   55 #include "service_rlogin.h"
   56 #include "service_rpc.h"
   57 #include "service_rshell.h"
   58 #include "service_rsync.h"
   59 #include "service_rtmp.h"
   60 #include "service_snmp.h"
   61 #include "service_ssh.h"
   62 #include "service_ssl.h"
   63 #include "service_telnet.h"
   64 #include "service_tftp.h"
   65 #include "detector_dns.h"
   66 #include "detector_sip.h"
   67 #include "service_direct_connect.h"
   68 #include "service_battle_field.h"
   69 #include "service_MDNS.h"
   70 #include "detector_pattern.h"
   71 #include "luaDetectorModule.h"
   72 #include "cpuclock.h"
   73 #include "commonAppMatcher.h"
   74 #include "fw_appid.h"
   75 #include "flow.h"
   76 #include "appIdConfig.h"
   77 #include "ip_funcs.h"
   78 #include "luaDetectorApi.h"
   79 
   80 /*#define SERVICE_DEBUG 1 */
   81 /*#define SERVICE_DEBUG_PORT  0 */
   82 
   83 #define BUFSIZE         512
   84 
   85 #define STATE_ID_INCONCLUSIVE_SERVICE_WEIGHT 3
   86 #define STATE_ID_INVALID_CLIENT_THRESHOLD    9
   87 #define STATE_ID_MAX_VALID_COUNT             5
   88 #define STATE_ID_NEEDED_DUPE_DETRACT_COUNT   3
   89 
   90 
   91 static void *service_flowdata_get(tAppIdData *flow, unsigned service_id);
   92 static int service_flowdata_add(tAppIdData *flow, void *data, unsigned service_id, AppIdFreeFCN fcn);
   93 static void AppIdAddHostInfo(tAppIdData *flow, SERVICE_HOST_INFO_CODE code, const void *info);
   94 static int AppIdAddDHCP(tAppIdData *flowp, unsigned op55_len, const uint8_t *op55, unsigned op60_len, const uint8_t *op60, const uint8_t *mac);
   95 static void AppIdAddHostIP(tAppIdData *flow, const uint8_t *mac, uint32_t ip4,
   96                                       int32_t zone, uint32_t subnetmask, uint32_t leaseSecs, uint32_t router);
   97 static void AppIdAddSMBData(tAppIdData *flow, unsigned major, unsigned minor, uint32_t flags);
   98 static void AppIdServiceAddMisc(tAppIdData* flow, tAppId miscId);
   99 
  100 const ServiceApi serviceapi =
  101 {
  102     .data_get = &service_flowdata_get,
  103     .data_add = &service_flowdata_add,
  104     .flow_new = &AppIdEarlySessionCreate,
  105     .data_add_id = &AppIdFlowdataAddId,
  106     .data_add_dhcp = &AppIdAddDHCP,
  107     .dhcpNewLease = &AppIdAddHostIP,
  108     .analyzefp = &AppIdAddSMBData,
  109     .add_service = &AppIdServiceAddService,
  110     .fail_service = &AppIdServiceFailService,
  111     .service_inprocess = &AppIdServiceInProcess,
  112     .incompatible_data = &AppIdServiceIncompatibleData,
  113     .add_host_info = &AppIdAddHostInfo,
  114     .add_payload = &AppIdAddPayload,
  115     .add_multipayload = &AppIdAddMultiPayload,
  116     .add_user = &AppIdAddUser,
  117     .add_service_consume_subtype = &AppIdServiceAddServiceSubtype,
  118     .add_misc = &AppIdServiceAddMisc,
  119     .add_dns_query_info = &AppIdAddDnsQueryInfo,
  120     .add_dns_response_info = &AppIdAddDnsResponseInfo,
  121     .reset_dns_info = &AppIdResetDnsInfo,
  122 };
  123 
  124 #ifdef SERVICE_DEBUG
  125 static const char *serviceIdStateName[] =
  126 {
  127     "NEW",
  128     "VALID",
  129     "PORT",
  130     "PATTERN",
  131     "BRUTE_FORCE"
  132 };
  133 #endif
  134 
  135 static tRNAServiceElement *ftp_service = NULL;
  136 
  137 static tServicePatternData *free_pattern_data;
  138 
  139 /*C service API */
  140 static void ServiceRegisterPattern(RNAServiceValidationFCN fcn,
  141                                    u_int8_t proto, const u_int8_t *pattern, unsigned size,
  142                                    int position, struct _Detector *userdata, int provides_user,
  143                                    const char *name, tServiceConfig *pServiceConfig);
  144 static void CServiceRegisterPattern(RNAServiceValidationFCN fcn, uint8_t proto,
  145                                    const uint8_t *pattern, unsigned size,
  146                                    int position, const char *name, tAppIdConfig *pConfig);
  147 static void ServiceRegisterPatternUser(RNAServiceValidationFCN fcn, uint8_t proto,
  148                                        const uint8_t *pattern, unsigned size,
  149                                        int position, const char *name, tAppIdConfig *pConfig);
  150 static int CServiceAddPort(RNAServiceValidationPort *pp, tRNAServiceValidationModule *svm, tAppIdConfig *pConfig);
  151 static void CServiceRemovePorts(RNAServiceValidationFCN validate, tAppIdConfig *pConfig);
  152 
  153 static InitServiceAPI svc_init_api =
  154 {
  155     .RegisterPattern = &CServiceRegisterPattern,
  156     .AddPort = &CServiceAddPort,
  157     .RemovePorts = CServiceRemovePorts,
  158     .RegisterPatternUser = &ServiceRegisterPatternUser,
  159     .RegisterAppId = &appSetServiceValidator,
  160     .RegisterDetectorCallback = &appSetServiceDetectorCallback,
  161 };
  162 
  163 static CleanServiceAPI svc_clean_api =
  164 {
  165 };
  166 
  167 extern tRNAServiceValidationModule timbuktu_service_mod;
  168 extern tRNAServiceValidationModule bit_service_mod;
  169 extern tRNAServiceValidationModule tns_service_mod;
  170 extern tRNAServiceValidationModule http_service_mod;
  171 
  172 static tRNAServiceValidationModule *static_service_list[] =
  173 {
  174     &bgp_service_mod,
  175     &bootp_service_mod,
  176     &dcerpc_service_mod,
  177     &cip_service_mod,
  178     &dns_service_mod,
  179     &enip_service_mod,
  180     &flap_service_mod,
  181     &ftp_service_mod,
  182     &irc_service_mod,
  183     &lpr_service_mod,
  184     &mysql_service_mod,
  185     &netbios_service_mod,
  186     &nntp_service_mod,
  187     &ntp_service_mod,
  188     &radius_service_mod,
  189     &rexec_service_mod,
  190     &rfb_service_mod,
  191     &rlogin_service_mod,
  192     &rpc_service_mod,
  193     &rshell_service_mod,
  194     &rsync_service_mod,
  195     &rtmp_service_mod,
  196     &snmp_service_mod,
  197     &ssh_service_mod,
  198     &ssl_service_mod,
  199     &telnet_service_mod,
  200     &tftp_service_mod,
  201     &sip_service_mod,
  202     &directconnect_service_mod,
  203     &battlefield_service_mod,
  204     &mdns_service_mod,
  205     &timbuktu_service_mod,
  206     &bit_service_mod,
  207     &tns_service_mod,
  208     &pattern_service_mod,
  209     &http_service_mod
  210 };
  211 
  212 typedef struct _SERVICE_MATCH
  213 {
  214     struct _SERVICE_MATCH *next;
  215     unsigned count;
  216     unsigned size;
  217     tRNAServiceElement *svc;
  218 } ServiceMatch;
  219 
  220 static DHCPInfo *dhcp_info_free_list;
  221 static FpSMBData *smb_data_free_list;
  222 static unsigned smOrderedListSize = 0;
  223 static ServiceMatch **smOrderedList = NULL;
  224 static ServiceMatch *free_service_match;
  225 static const uint8_t zeromac[6] = {0, 0, 0, 0, 0, 0};
  226 
  227 /**free ServiceMatch List.
  228  */
  229 void AppIdFreeServiceMatchList(ServiceMatch* sm)
  230 {
  231     ServiceMatch *tmpSm;
  232 
  233     if (!sm)
  234         return;
  235 
  236     for (tmpSm = sm; tmpSm->next; tmpSm = tmpSm->next);
  237     tmpSm->next = free_service_match;
  238     free_service_match = sm;
  239 }
  240 
  241 void cleanupFreeServiceMatch(void)
  242 {
  243     ServiceMatch *match;
  244     while ((match=free_service_match) != NULL)
  245     {
  246         free_service_match = match->next;
  247         free(match);
  248     }
  249 }
  250 
  251 int AddFTPServiceState(tAppIdData *fp)
  252 {
  253     if (!ftp_service)
  254         return -1;
  255     return AppIdFlowdataAddId(fp, 21, ftp_service);
  256 }
  257 
  258 /**allocate one ServiceMatch element.
  259  */
  260 static inline ServiceMatch* allocServiceMatch(void)
  261 {
  262     ServiceMatch *sm;
  263 
  264     if ((sm = free_service_match))
  265     {
  266         free_service_match = sm->next;
  267         memset(sm, 0, sizeof(*sm));
  268         return sm;
  269     }
  270     return (ServiceMatch *)calloc(1, sizeof(ServiceMatch));
  271 }
  272 
  273 static int pattern_match(void* id, void *unused_tree, int index, void* data, void *unused_neg)
  274 {
  275     ServiceMatch **matches = (ServiceMatch **)data;
  276     tServicePatternData *pd = (tServicePatternData *)id;
  277     ServiceMatch *sm;
  278 
  279     if (pd->position >= 0 && pd->position != index)
  280         return 0;
  281 
  282     for (sm=*matches; sm; sm=sm->next)
  283         if (sm->svc == pd->svc)
  284             break;
  285     if (sm)
  286         sm->count++;
  287     else
  288     {
  289         if ((sm=allocServiceMatch()) == NULL)
  290         {
  291             _dpd.errMsg( "Error allocating a service match");
  292             return 0;
  293         }
  294         sm->count++;
  295         sm->svc = pd->svc;
  296         sm->size = pd->size;
  297         sm->next = *matches;
  298         *matches = sm;
  299     }
  300     return 0;
  301 }
  302 
  303 tAppId getPortServiceId(uint8_t proto, uint16_t port, const tAppIdConfig *pConfig)
  304 {
  305     tAppId appId;
  306 
  307     if (proto == IPPROTO_TCP)
  308         appId = pConfig->tcp_port_only[port];
  309     else
  310         appId = pConfig->udp_port_only[port];
  311 
  312     checkSandboxDetection(appId);
  313 
  314     return appId;
  315 }
  316 
  317 tAppId getProtocolServiceId(uint8_t proto, const tAppIdConfig *pConfig)
  318 {
  319     tAppId appId;
  320 
  321     appId = pConfig->ip_protocol[proto];
  322 
  323     checkSandboxDetection(appId);
  324 
  325     return appId;
  326 }
  327 
  328 static inline uint16_t sslPortRemap(
  329         uint16_t port
  330         )
  331 {
  332     switch (port)
  333     {
  334     case 465:
  335         return 25;
  336     case 563:
  337         return 119;
  338     case 585:
  339     case 993:
  340         return 143;
  341     case 990:
  342         return 21;
  343     case 992:
  344         return 23;
  345     case 994:
  346         return 6667;
  347     case 995:
  348         return 110;
  349     default:
  350         return 0;
  351     }
  352 }
  353 
  354 static inline tRNAServiceElement *AppIdGetNextServiceByPort(
  355         uint8_t protocol,
  356         uint16_t port,
  357         const tRNAServiceElement * const lastService,
  358         tAppIdData *rnaData,
  359         const tAppIdConfig *pConfig
  360         )
  361 {
  362     tRNAServiceElement *service = NULL;
  363     SF_LIST *list = NULL;
  364 
  365     if (AppIdServiceDetectionLevel(rnaData))
  366     {
  367         unsigned remappedPort = sslPortRemap(port);
  368         if (remappedPort)
  369             list = pConfig->serviceConfig.tcp_services[remappedPort];
  370     }
  371     else if (protocol == IPPROTO_TCP)
  372     {
  373         list = pConfig->serviceConfig.tcp_services[port];
  374     }
  375     else
  376     {
  377         list = pConfig->serviceConfig.udp_services[port];
  378     }
  379 
  380     if (list)
  381     {
  382         service = sflist_first(list);
  383 
  384         if (lastService)
  385         {
  386             while ( service && ((service->validate != lastService->validate) || (service->userdata != lastService->userdata)))
  387                 service = sflist_next(list);
  388             if (service)
  389                 service = sflist_next(list);
  390         }
  391     }
  392 
  393 #ifdef SERVICE_DEBUG
  394 #if SERVICE_DEBUG_PORT
  395     if (port == SERVICE_DEBUG_PORT)
  396 #endif
  397         fprintf(SF_DEBUG_FILE, "Port service for protocol %u port %u, service %s\n",
  398                 (unsigned)protocol, (unsigned)port, (service && service->name) ? service->name:"UNKNOWN");
  399 #endif
  400 
  401     return service;
  402 }
  403 
  404 static inline tRNAServiceElement *AppIdNextServiceByPattern(struct _SERVICE_MATCH **currentService
  405 #ifdef SERVICE_DEBUG
  406 #if SERVICE_DEBUG_PORT
  407                                                            , uint16_t port
  408 #endif
  409 #endif
  410                                                            )
  411 {
  412     tRNAServiceElement *service = NULL;
  413 
  414     while (*currentService)
  415     {
  416         *currentService = (*currentService)->next;
  417         if (*currentService && (*currentService)->svc->current_ref_count)
  418         {
  419             service = (*currentService)->svc;
  420             break;
  421         }
  422     }
  423 
  424 #ifdef SERVICE_DEBUG
  425 #if SERVICE_DEBUG_PORT
  426     if (port == SERVICE_DEBUG_PORT)
  427 #endif
  428         fprintf(SF_DEBUG_FILE, "Next pattern service %s\n",
  429                 (service && service->name) ? service->name:"UNKNOWN");
  430 #endif
  431 
  432     return service;
  433 }
  434 
  435 tRNAServiceElement *ServiceGetServiceElement(RNAServiceValidationFCN fcn, struct _Detector *userdata,
  436                                                   tAppIdConfig *pConfig)
  437 {
  438     tRNAServiceElement *li;
  439 
  440     for (li=pConfig->serviceConfig.tcp_service_list; li; li=li->next)
  441     {
  442         if ((li->validate == fcn) && (li->userdata == userdata))
  443             return li;
  444     }
  445 
  446     for (li=pConfig->serviceConfig.udp_service_list; li; li=li->next)
  447     {
  448         if ((li->validate == fcn) && (li->userdata == userdata))
  449             return li;
  450     }
  451     return NULL;
  452 }
  453 
  454 static void ServiceRegisterPattern(RNAServiceValidationFCN fcn,
  455                                    u_int8_t proto, const u_int8_t *pattern, unsigned size,
  456                                    int position, struct _Detector *userdata, int provides_user,
  457                                    const char *name, tServiceConfig *pServiceConfig)
  458 {
  459     void **patterns;
  460     tServicePatternData **pd_list;
  461     int *count;
  462     tServicePatternData *pd;
  463     tRNAServiceElement * *list;
  464     tRNAServiceElement *li;
  465 
  466     if (proto == IPPROTO_TCP)
  467     {
  468         patterns = &pServiceConfig->tcp_patterns;
  469         pd_list = &pServiceConfig->tcp_pattern_data;
  470 
  471         count = &pServiceConfig->tcp_pattern_count;
  472         list = &pServiceConfig->tcp_service_list;
  473     }
  474     else if (proto == IPPROTO_UDP)
  475     {
  476         patterns = &pServiceConfig->udp_patterns;
  477         pd_list = &pServiceConfig->udp_pattern_data;
  478 
  479         count = &pServiceConfig->udp_pattern_count;
  480         list = &pServiceConfig->udp_service_list;
  481     }
  482     else
  483     {
  484         _dpd.errMsg("Invalid protocol when registering a pattern: %u\n",(unsigned)proto);
  485         return;
  486     }
  487 
  488     for (li=*list; li; li=li->next)
  489     {
  490         if ((li->validate == fcn) && (li->userdata == userdata))
  491             break;
  492     }
  493     if (!li)
  494     {
  495         if (!(li = calloc(1, sizeof(*li))))
  496         {
  497             _dpd.errMsg( "Could not allocate a service list element");
  498             return;
  499         }
  500         li->next = *list;
  501         *list = li;
  502         li->validate = fcn;
  503         li->userdata = userdata;
  504         li->detectorType = UINT_MAX;
  505         li->provides_user = provides_user;
  506         li->name = name;
  507     }
  508 
  509     if (!(*patterns))
  510     {
  511         *patterns = _dpd.searchAPI->search_instance_new_ex(MPSE_ACF);
  512         if (!(*patterns))
  513         {
  514             _dpd.errMsg("Error initializing the pattern table for protocol %u\n",(unsigned)proto);
  515             return;
  516         }
  517     }
  518 
  519     if (free_pattern_data)
  520     {
  521         pd = free_pattern_data;
  522         free_pattern_data = pd->next;
  523         memset(pd, 0, sizeof(*pd));
  524     }
  525     else if ((pd=(tServicePatternData *)calloc(1, sizeof(*pd))) == NULL)
  526     {
  527         _dpd.errMsg( "Error allocating pattern data");
  528         return;
  529     }
  530     pd->svc = li;
  531     pd->size = size;
  532     pd->position = position;
  533     _dpd.searchAPI->search_instance_add_ex(*patterns, (void *)pattern, size, pd, STR_SEARCH_CASE_SENSITIVE);
  534     (*count)++;
  535     pd->next = *pd_list;
  536     *pd_list = pd;
  537     li->ref_count++;
  538 }
  539 
  540 void ServiceRegisterPatternDetector(RNAServiceValidationFCN fcn,
  541                                     u_int8_t proto, const u_int8_t *pattern, unsigned size,
  542                                     int position, struct _Detector *userdata, const char *name)
  543 {
  544     ServiceRegisterPattern(fcn, proto, pattern, size, position, userdata, 0, name, &userdata->pAppidNewConfig->serviceConfig);
  545 }
  546 
  547 static void ServiceRegisterPatternUser(RNAServiceValidationFCN fcn, uint8_t proto,
  548                                        const uint8_t *pattern, unsigned size,
  549                                        int position, const char *name, tAppIdConfig *pConfig)
  550 {
  551     ServiceRegisterPattern(fcn, proto, pattern, size, position, NULL, 1, name, &pConfig->serviceConfig);
  552 }
  553 
  554 static void CServiceRegisterPattern(RNAServiceValidationFCN fcn, uint8_t proto,
  555                                     const uint8_t *pattern, unsigned size,
  556                                     int position, const char *name,
  557                                     tAppIdConfig *pConfig)
  558 {
  559     ServiceRegisterPattern(fcn, proto, pattern, size, position, NULL, 0, name, &pConfig->serviceConfig);
  560 }
  561 
  562 static void RemoveServicePortsByType(RNAServiceValidationFCN validate,
  563                                      SF_LIST **services,
  564                                      tRNAServiceElement *list,
  565                                      struct _Detector* userdata)
  566 {
  567     tRNAServiceElement *li, *liTmp;
  568     SF_LNODE *node;
  569     SF_LNODE *nextNode;
  570     unsigned i;
  571     SF_LIST *listTmp;
  572 
  573     for (li=list; li; li=li->next)
  574     {
  575         if (li->validate == validate && li->userdata == userdata)
  576             break;
  577     }
  578     if (li == NULL)
  579         return;
  580 
  581     for (i=0; i<RNA_SERVICE_MAX_PORT; i++)
  582     {
  583         if ((listTmp = services[i]))
  584         {
  585             node = sflist_first_node(listTmp);
  586             while (node)
  587             {
  588                 liTmp = (tRNAServiceElement *)SFLIST_NODE_TO_DATA(node);
  589                 if (liTmp == li)
  590                 {
  591                     nextNode = node->next;
  592                     li->ref_count--;
  593                     sflist_remove_node(listTmp, node);
  594                     node = nextNode;
  595                     continue;
  596                 }
  597 
  598                 node = node->next;
  599             }
  600         }
  601     }
  602 }
  603 
  604 /**
  605  * \brief Remove all ports registered for all services
  606  *
  607  * This function takes care of removing ports for all services including C service modules,
  608  * Lua detector modules and services associated with C detector modules.
  609  *
  610  * @param pServiceConfig - Service configuration from which all ports need to be removed
  611  * @return void
  612  */
  613 static void RemoveAllServicePorts(tServiceConfig *pServiceConfig)
  614 {
  615     int i;
  616 
  617     for (i=0; i<RNA_SERVICE_MAX_PORT; i++)
  618     {
  619         if (pServiceConfig->tcp_services[i])
  620         {
  621             sflist_free(pServiceConfig->tcp_services[i]);
  622             pServiceConfig->tcp_services[i] = NULL;
  623         }
  624     }
  625     for (i=0; i<RNA_SERVICE_MAX_PORT; i++)
  626     {
  627         if (pServiceConfig->udp_services[i])
  628         {
  629             sflist_free(pServiceConfig->udp_services[i]);
  630             pServiceConfig->udp_services[i] = NULL;
  631         }
  632     }
  633     for (i=0; i<RNA_SERVICE_MAX_PORT; i++)
  634     {
  635         if (pServiceConfig->udp_reversed_services[i])
  636         {
  637             sflist_free(pServiceConfig->udp_reversed_services[i]);
  638             pServiceConfig->udp_reversed_services[i] = NULL;
  639         }
  640     }
  641 }
  642 
  643 void ServiceRemovePorts(RNAServiceValidationFCN validate, struct _Detector* userdata, tAppIdConfig *pConfig)
  644 {
  645     RemoveServicePortsByType(validate, pConfig->serviceConfig.tcp_services, pConfig->serviceConfig.tcp_service_list, userdata);
  646     RemoveServicePortsByType(validate, pConfig->serviceConfig.udp_services, pConfig->serviceConfig.udp_service_list, userdata);
  647     RemoveServicePortsByType(validate, pConfig->serviceConfig.udp_reversed_services, pConfig->serviceConfig.udp_reversed_service_list, userdata);
  648 }
  649 
  650 static void CServiceRemovePorts(RNAServiceValidationFCN validate, tAppIdConfig *pConfig)
  651 {
  652     ServiceRemovePorts(validate, NULL, pConfig);
  653 }
  654 
  655 int ServiceAddPort(RNAServiceValidationPort *pp, tRNAServiceValidationModule *svm,
  656                    struct _Detector* userdata, tAppIdConfig *pConfig)
  657 {
  658     SF_LIST **services;
  659     tRNAServiceElement * *list = NULL;
  660     tRNAServiceElement *li;
  661     tRNAServiceElement *serviceElement;
  662     uint8_t isAllocated = 0;
  663 
  664     _dpd.debugMsg(DEBUG_LOG, "Adding service %s for protocol %u on port %u, %p",
  665             svm->name, (unsigned)pp->proto, (unsigned)pp->port, pp->validate);
  666     if (pp->proto == IPPROTO_TCP)
  667     {
  668         services = pConfig->serviceConfig.tcp_services;
  669         list = &pConfig->serviceConfig.tcp_service_list;
  670     }
  671     else if (pp->proto == IPPROTO_UDP)
  672     {
  673         if (!pp->reversed_validation)
  674         {
  675             services = pConfig->serviceConfig.udp_services;
  676             list = &pConfig->serviceConfig.udp_service_list;
  677         }
  678         else
  679         {
  680             services = pConfig->serviceConfig.udp_reversed_services;
  681             list = &pConfig->serviceConfig.udp_reversed_service_list;
  682         }
  683     }
  684     else
  685     {
  686         _dpd.errMsg( "Service %s did not have a valid protocol (%u)",
  687                svm->name, (unsigned)pp->proto);
  688         return 0;
  689     }
  690 
  691     for (li=*list; li; li=li->next)
  692     {
  693         if (li->validate == pp->validate && li->userdata == userdata)
  694             break;
  695     }
  696     if (!li)
  697     {
  698         if (!(li = calloc(1, sizeof(*li))))
  699         {
  700             _dpd.errMsg( "Could not allocate a service list element");
  701             return -1;
  702         }
  703 
  704         isAllocated = 1;
  705         li->next = *list;
  706         *list = li;
  707         li->validate = pp->validate;
  708         li->provides_user = svm->provides_user;
  709         li->userdata = userdata;
  710         li->detectorType = UINT_MAX;
  711         li->name = svm->name;
  712     }
  713 
  714     if (pp->proto == IPPROTO_TCP && pp->port == 21 && !ftp_service)
  715     {
  716         ftp_service = li;
  717         li->ref_count++;
  718     }
  719 
  720     /*allocate a new list if this is first detector for this port. */
  721     if (!services[pp->port])
  722     {
  723         if (!(services[pp->port] = malloc(sizeof(SF_LIST))))
  724         {
  725             if (isAllocated)
  726             {
  727                 *list = li->next;
  728                 free(li);
  729             }
  730             _dpd.errMsg( "Could not allocate a service list");
  731             return -1;
  732         }
  733         sflist_init(services[pp->port]);
  734     }
  735 
  736     /*search and add if not present. */
  737     for (serviceElement = sflist_first(services[pp->port]);
  738             serviceElement && (serviceElement != li);
  739             serviceElement = sflist_next(services[pp->port]));
  740 
  741     if (!serviceElement)
  742     {
  743         if (sflist_add_tail(services[pp->port], li))
  744         {
  745             _dpd.errMsg( "Could not add %s, service for protocol %u on port %u", svm->name,
  746                    (unsigned)pp->proto, (unsigned)pp->port);
  747             if (isAllocated)
  748             {
  749                 *list = li->next;
  750                 free(li);
  751             }
  752             return -1;
  753         }
  754     }
  755 
  756     li->ref_count++;
  757     return 0;
  758 }
  759 
  760 static int CServiceAddPort(RNAServiceValidationPort *pp, tRNAServiceValidationModule *svm, tAppIdConfig *pConfig)
  761 {
  762     return ServiceAddPort(pp, svm, NULL, pConfig);
  763 }
  764 
  765 int serviceLoadForConfigCallback(void *symbol, tAppIdConfig *pConfig)
  766 {
  767     static unsigned service_module_index = 0;
  768     tRNAServiceValidationModule *svm = (tRNAServiceValidationModule *)symbol;
  769     RNAServiceValidationPort *pp;
  770 
  771     if (service_module_index >= 65536)
  772     {
  773         _dpd.errMsg( "Maximum number of service modules exceeded");
  774         return -1;
  775     }
  776 
  777     svm->api = &serviceapi;
  778     pp = svm->pp;
  779     for (pp=svm->pp; pp && pp->validate; pp++)
  780     {
  781         if (CServiceAddPort(pp, svm, pConfig))
  782             return -1;
  783     }
  784 
  785     if (svm->init(&svc_init_api))
  786     {
  787         _dpd.errMsg("Error initializing service %s\n",svm->name);
  788     }
  789 
  790     svm->next = pConfig->serviceConfig.active_service_list;
  791     pConfig->serviceConfig.active_service_list = svm;
  792 
  793     svm->flow_data_index = service_module_index | APPID_SESSION_DATA_SERVICE_MODSTATE_BIT;
  794     service_module_index++;
  795 
  796     return 0;
  797 }
  798 
  799 int serviceLoadCallback(void *symbol)
  800 {
  801     return serviceLoadForConfigCallback(symbol, pAppidActiveConfig);
  802 }
  803 
  804 int LoadServiceModules(const char **dir_list, uint32_t instance_id, tAppIdConfig *pConfig)
  805 {
  806     unsigned i;
  807 
  808     svc_init_api.instance_id = instance_id;
  809     svc_init_api.debug = appidStaticConfig->app_id_debug;
  810     svc_init_api.dpd = &_dpd;
  811     svc_init_api.pAppidConfig = pConfig;
  812 
  813     for (i=0; i<sizeof(static_service_list)/sizeof(*static_service_list); i++)
  814     {
  815         if (serviceLoadForConfigCallback(static_service_list[i], pConfig))
  816             return -1;
  817     }
  818 
  819     return 0;
  820 }
  821 
  822 int ReloadServiceModules(tAppIdConfig *pConfig)
  823 {
  824     tRNAServiceValidationModule  *svm;
  825     RNAServiceValidationPort    *pp;
  826 
  827     svc_init_api.debug = app_id_debug;
  828     svc_init_api.pAppidConfig = pConfig;
  829 
  830     // active_service_list contains both service modules and services associated with
  831     // detector modules
  832     for (svm=pConfig->serviceConfig.active_service_list; svm; svm=svm->next)
  833     {
  834         // processing only non-lua service detectors.
  835         if (svm->init)
  836         {
  837             pp = svm->pp;
  838             for (pp=svm->pp; pp && pp->validate; pp++)
  839             {
  840                 if (CServiceAddPort(pp, svm, pConfig))
  841                     return -1;
  842             }
  843         }
  844     }
  845 
  846     return 0;
  847 }
  848 
  849 void ServiceInit(tAppIdConfig *pConfig)
  850 {
  851     luaModuleInitAllServices();
  852 }
  853 
  854 void ServiceFinalize(tAppIdConfig *pConfig)
  855 {
  856     if (pConfig->serviceConfig.tcp_patterns)
  857     {
  858         _dpd.searchAPI->search_instance_prep(pConfig->serviceConfig.tcp_patterns);
  859     }
  860     if (pConfig->serviceConfig.udp_patterns)
  861     {
  862         _dpd.searchAPI->search_instance_prep(pConfig->serviceConfig.udp_patterns);
  863     }
  864 }
  865 
  866 void UnconfigureServices(tAppIdConfig *pConfig)
  867 {
  868     tRNAServiceElement *li;
  869     tServicePatternData *pd;
  870     tRNAServiceValidationModule *svm;
  871 
  872     svc_clean_api.pAppidConfig = pConfig;
  873 
  874     if (pConfig->serviceConfig.tcp_patterns)
  875     {
  876         _dpd.searchAPI->search_instance_free(pConfig->serviceConfig.tcp_patterns);
  877         pConfig->serviceConfig.tcp_patterns = NULL;
  878     }
  879     // Do not free memory for the pattern; this can be later reclaimed when a
  880     // new pattern needs to be created. Memory for these patterns will be freed
  881     // on exit.
  882     while (pConfig->serviceConfig.tcp_pattern_data)
  883     {
  884         pd = pConfig->serviceConfig.tcp_pattern_data;
  885         if ((li = pd->svc) != NULL)
  886             li->ref_count--;
  887         pConfig->serviceConfig.tcp_pattern_data = pd->next;
  888         pd->next = free_pattern_data;
  889         free_pattern_data = pd;
  890     }
  891     if (pConfig->serviceConfig.udp_patterns)
  892     {
  893         _dpd.searchAPI->search_instance_free(pConfig->serviceConfig.udp_patterns);
  894         pConfig->serviceConfig.udp_patterns = NULL;
  895     }
  896     while (pConfig->serviceConfig.udp_pattern_data)
  897     {
  898         pd = pConfig->serviceConfig.udp_pattern_data;
  899         if ((li = pd->svc) != NULL)
  900             li->ref_count--;
  901         pConfig->serviceConfig.udp_pattern_data = pd->next;
  902         pd->next = free_pattern_data;
  903         free_pattern_data = pd;
  904     }
  905 
  906     RemoveAllServicePorts(&pConfig->serviceConfig);
  907 
  908     for (svm=pConfig->serviceConfig.active_service_list; svm; svm=svm->next)
  909     {
  910         if (svm->clean)
  911             svm->clean(&svc_clean_api);
  912     }
  913 
  914     CleanServicePortPatternList(pConfig);
  915 }
  916 
  917 void ReconfigureServices(tAppIdConfig *pConfig)
  918 {
  919     tRNAServiceValidationModule *svm;
  920 
  921     for (svm=pConfig->serviceConfig.active_service_list; svm; svm=svm->next)
  922     {
  923         /*processing only non-lua service detectors. */
  924         if (svm->init)
  925         {
  926             if (svm->init(&svc_init_api))
  927             {
  928                 _dpd.errMsg("Error initializing service %s\n",svm->name);
  929             }
  930             else
  931             {
  932                 _dpd.debugMsg(DEBUG_LOG,"Initialized service %s\n",svm->name);
  933             }
  934         }
  935     }
  936 
  937     ServiceInit(pConfig);
  938 }
  939 
  940 void CleanupServices(tAppIdConfig *pConfig)
  941 {
  942 #ifdef APPID_FULL_CLEANUP
  943     tServicePatternData *pattern;
  944     tRNAServiceElement *se;
  945     ServiceMatch *sm;
  946     tRNAServiceValidationModule *svm;
  947     FpSMBData *sd;
  948     DHCPInfo *info;
  949 
  950     svc_clean_api.pAppidConfig = pConfig;
  951 
  952     if (pConfig->serviceConfig.tcp_patterns)
  953     {
  954         _dpd.searchAPI->search_instance_free(pConfig->serviceConfig.tcp_patterns);
  955         pConfig->serviceConfig.tcp_patterns = NULL;
  956     }
  957     if (pConfig->serviceConfig.udp_patterns)
  958     {
  959         _dpd.searchAPI->search_instance_free(pConfig->serviceConfig.udp_patterns);
  960         pConfig->serviceConfig.udp_patterns = NULL;
  961     }
  962     while ((pattern=pConfig->serviceConfig.tcp_pattern_data))
  963     {
  964         pConfig->serviceConfig.tcp_pattern_data = pattern->next;
  965         free(pattern);
  966     }
  967     while ((pattern=pConfig->serviceConfig.udp_pattern_data))
  968     {
  969         pConfig->serviceConfig.udp_pattern_data = pattern->next;
  970         free(pattern);
  971     }
  972     while ((pattern=free_pattern_data))
  973     {
  974         free_pattern_data = pattern->next;
  975         free(pattern);
  976     }
  977     while ((se=pConfig->serviceConfig.tcp_service_list))
  978     {
  979         pConfig->serviceConfig.tcp_service_list = se->next;
  980         free(se);
  981     }
  982     while ((se=pConfig->serviceConfig.udp_service_list))
  983     {
  984         pConfig->serviceConfig.udp_service_list = se->next;
  985         free(se);
  986     }
  987     while ((se=pConfig->serviceConfig.udp_reversed_service_list))
  988     {
  989         pConfig->serviceConfig.udp_reversed_service_list = se->next;
  990         free(se);
  991     }
  992     while ((sd = smb_data_free_list))
  993     {
  994         smb_data_free_list = sd->next;
  995         free(sd);
  996     }
  997     while ((info = dhcp_info_free_list))
  998     {
  999         dhcp_info_free_list = info->next;
 1000         free(info);
 1001     }
 1002     while ((sm = free_service_match))
 1003     {
 1004         free_service_match = sm->next;
 1005         free(sm);
 1006     }
 1007     if (smOrderedList)
 1008      {
 1009         free(smOrderedList);
 1010         smOrderedListSize = 0;
 1011      }
 1012 
 1013     RemoveAllServicePorts(&pConfig->serviceConfig);
 1014 
 1015     for (svm=pConfig->serviceConfig.active_service_list; svm; svm=svm->next)
 1016     {
 1017         if (svm->clean)
 1018             svm->clean(&svc_clean_api);
 1019     }
 1020 
 1021     CleanServicePortPatternList(pConfig);
 1022 #endif
 1023 }
 1024 
 1025 static int AppIdPatternPrecedence(const void *a, const void *b)
 1026 {
 1027     const ServiceMatch *sm1 = (ServiceMatch*)a;
 1028     const ServiceMatch *sm2 = (ServiceMatch*)b;
 1029 
 1030     /*higher precedence should be before lower precedence */
 1031     if (sm1->count != sm2->count)
 1032         return (sm2->count - sm1->count);
 1033     else
 1034         return (sm2->size - sm1->size);
 1035 }
 1036 
 1037 /**Perform pattern match of a packet and construct a list of services sorted in order of
 1038  * precedence criteria. Criteria is count and then size. The first service in the list is
 1039  * returned. The list itself is saved in AppIdServiceIDState. If
 1040  * appId is already identified, then use it instead of searching again. RNA will capability
 1041  * to try out other inferior matches. If appId is unknown i.e. searched and not found by FRE then
 1042  * dont do any pattern match. This is a way degrades RNA detector selection if FRE is running on
 1043  * this sensor.
 1044 */
 1045 static inline tRNAServiceElement *AppIdGetServiceByPattern(const SFSnortPacket *pkt, uint8_t proto,
 1046                                                           const int dir, const tServiceConfig *pServiceConfig,
 1047                                                           struct _SERVICE_MATCH **serviceList, struct _SERVICE_MATCH **currentService)
 1048 {
 1049     void *patterns = NULL;
 1050     ServiceMatch *match_list;
 1051     ServiceMatch *sm;
 1052     uint32_t count;
 1053     uint32_t i;
 1054     tRNAServiceElement *service = NULL;
 1055 
 1056     if (proto == IPPROTO_TCP)
 1057         patterns = pServiceConfig->tcp_patterns;
 1058     else
 1059         patterns = pServiceConfig->udp_patterns;
 1060 
 1061     if (!patterns)
 1062     {
 1063 #ifdef SERVICE_DEBUG
 1064 #if SERVICE_DEBUG_PORT
 1065     if (pkt->dst_port == SERVICE_DEBUG_PORT || pkt->src_port == SERVICE_DEBUG_PORT)
 1066 #endif
 1067         fprintf(SF_DEBUG_FILE, "Pattern bailing due to no patterns\n");
 1068 #endif
 1069         return NULL;
 1070     }
 1071 
 1072     if (!smOrderedList)
 1073     {
 1074         smOrderedListSize = 32;
 1075         if (!(smOrderedList = calloc(smOrderedListSize, sizeof(*smOrderedList))))
 1076         {
 1077             _dpd.errMsg( "Pattern bailing due to failed allocation");
 1078             return NULL;
 1079         }
 1080     }
 1081 
 1082 #ifdef SERVICE_DEBUG
 1083 #if SERVICE_DEBUG_PORT
 1084     if (pkt->dst_port == SERVICE_DEBUG_PORT || pkt->src_port == SERVICE_DEBUG_PORT)
 1085     {
 1086 #endif
 1087         fprintf(SF_DEBUG_FILE, "Matching\n");
 1088         DumpHex(SF_DEBUG_FILE, pkt->payload, pkt->payload_size);
 1089 #if SERVICE_DEBUG_PORT
 1090     }
 1091 #endif
 1092 #endif
 1093     /*FRE didn't search */
 1094     match_list = NULL;
 1095     _dpd.searchAPI->search_instance_find_all(patterns, (char *)pkt->payload,
 1096             pkt->payload_size, 0, &pattern_match, (void*)&match_list);
 1097 
 1098     count = 0;
 1099     for (sm=match_list; sm; sm=sm->next)
 1100     {
 1101         if (count >= smOrderedListSize)
 1102         {
 1103             ServiceMatch **tmp;
 1104             smOrderedListSize *= 2;
 1105             tmp = realloc(smOrderedList, smOrderedListSize * sizeof(*smOrderedList));
 1106             if (!tmp)
 1107             {
 1108                 /*log realloc failure */
 1109                 _dpd.errMsg("Realloc failure %u\n",smOrderedListSize);
 1110                 smOrderedListSize /= 2;
 1111 
 1112                 /*free the remaining elements. */
 1113                 AppIdFreeServiceMatchList(sm);
 1114 
 1115                 break;
 1116             }
 1117             _dpd.errMsg("Realloc %u\n",smOrderedListSize);
 1118 
 1119             smOrderedList = tmp;
 1120         }
 1121 
 1122         smOrderedList[count++] = sm;
 1123     }
 1124 
 1125     if (!count)
 1126         return NULL;
 1127 
 1128     qsort(smOrderedList, count, sizeof(*smOrderedList), AppIdPatternPrecedence);
 1129 
 1130     /*rearrange the matchlist now */
 1131     for (i = 0; i < (count-1); i++)
 1132         smOrderedList[i]->next = smOrderedList[i+1];
 1133     smOrderedList[i]->next = NULL;
 1134 
 1135     service = smOrderedList[0]->svc;
 1136     if (*serviceList)
 1137         AppIdFreeServiceMatchList(*serviceList);
 1138     *serviceList = smOrderedList[0];
 1139     *currentService = smOrderedList[0];
 1140 
 1141 #ifdef SERVICE_DEBUG
 1142 #if SERVICE_DEBUG_PORT
 1143     if (pkt->dst_port == SERVICE_DEBUG_PORT || pkt->src_port == SERVICE_DEBUG_PORT)
 1144 #endif
 1145         fprintf(SF_DEBUG_FILE, "Pattern service for protocol %u (%u->%u), %s\n",
 1146                 (unsigned)proto, (unsigned)pkt->src_port, (unsigned)pkt->dst_port,
 1147                 (service && service->name) ? service->name:"UNKNOWN");
 1148 #endif
 1149     return service;
 1150 }
 1151 
 1152 static inline tRNAServiceElement * AppIdGetServiceByBruteForce(
 1153         uint32_t protocol,
 1154         const tRNAServiceElement *lastService,
 1155         const tAppIdConfig *pConfig
 1156         )
 1157 {
 1158     tRNAServiceElement *service;
 1159 
 1160     if (lastService)
 1161         service = lastService->next;
 1162     else
 1163         service = ((protocol == IPPROTO_TCP) ? pConfig->serviceConfig.tcp_service_list:pConfig->serviceConfig.udp_service_list);
 1164 
 1165     while (service && !service->current_ref_count)
 1166         service = service->next;
 1167 
 1168     return service;
 1169 }
 1170 
 1171 static void AppIdAddHostInfo(tAppIdData *flow, SERVICE_HOST_INFO_CODE code, const void *info)
 1172 {
 1173 }
 1174 void AppIdFreeDhcpData(DhcpFPData *dd)
 1175 {
 1176     free(dd);
 1177 }
 1178 
 1179 static int AppIdAddDHCP(tAppIdData *flowp, unsigned op55_len, const uint8_t *op55, unsigned op60_len, const uint8_t *op60, const uint8_t *mac)
 1180 
 1181 
 1182 {
 1183     if(op55_len && op55_len <= DHCP_OPTION55_LEN_MAX && !getAppIdFlag(flowp, APPID_SESSION_HAS_DHCP_FP))
 1184     {
 1185         DhcpFPData *rdd;
 1186 
 1187         rdd = malloc(sizeof(*rdd));
 1188         if (!rdd)
 1189             return -1;
 1190 
 1191         if (AppIdFlowdataAdd(flowp, rdd, APPID_SESSION_DATA_DHCP_FP_DATA, (AppIdFreeFCN)AppIdFreeDhcpData))
 1192         {
 1193             AppIdFreeDhcpData(rdd);
 1194             return -1;
 1195         }
 1196 
 1197         setAppIdFlag(flowp, APPID_SESSION_HAS_DHCP_FP);
 1198         rdd->op55_len = (op55_len > DHCP_OP55_MAX_SIZE) ? DHCP_OP55_MAX_SIZE:op55_len;
 1199         memcpy(rdd->op55, op55, rdd->op55_len);
 1200         rdd->op60_len =  (op60_len > DHCP_OP60_MAX_SIZE) ? DHCP_OP60_MAX_SIZE:op60_len;
 1201         if(op60_len)
 1202             memcpy(rdd->op60, op60, rdd->op60_len);
 1203         memcpy(rdd->mac, mac, sizeof(rdd->mac));
 1204     }
 1205     return 0;
 1206 }
 1207 
 1208 void AppIdFreeDhcpInfo(DHCPInfo *dd)
 1209 {
 1210     if (dd)
 1211     {
 1212         dd->next = dhcp_info_free_list;
 1213         dhcp_info_free_list = dd;
 1214     }
 1215 }
 1216 
 1217 static void AppIdAddHostIP(tAppIdData *flow, const uint8_t *mac, uint32_t ip, int32_t zone,
 1218                                       uint32_t subnetmask, uint32_t leaseSecs, uint32_t router)
 1219 {
 1220     DHCPInfo *info;
 1221     unsigned flags;
 1222 
 1223     if (memcmp(mac, zeromac, 6) == 0 || ip == 0)
 1224          return;
 1225 
 1226     if (!getAppIdFlag(flow, APPID_SESSION_DO_RNA) || getAppIdFlag(flow, APPID_SESSION_HAS_DHCP_INFO))
 1227         return;
 1228 
 1229     flags = isIPv4HostMonitored(ntohl(ip), zone);
 1230     if (!(flags & IPFUNCS_HOSTS_IP)) return;
 1231 
 1232 
 1233     if (dhcp_info_free_list)
 1234     {
 1235         info = dhcp_info_free_list;
 1236         dhcp_info_free_list = info->next;
 1237     }
 1238     else if (!(info = malloc(sizeof(*info))))
 1239         return;
 1240 
 1241     if (AppIdFlowdataAdd(flow, info, APPID_SESSION_DATA_DHCP_INFO, (AppIdFreeFCN)AppIdFreeDhcpInfo))
 1242     {
 1243         AppIdFreeDhcpInfo(info);
 1244         return;
 1245     }
 1246     setAppIdFlag(flow, APPID_SESSION_HAS_DHCP_INFO);
 1247     info->ipAddr = ip;
 1248     memcpy(info->macAddr, mac, sizeof(info->macAddr));
 1249     info->subnetmask = subnetmask;
 1250     info->leaseSecs = leaseSecs;
 1251     info->router = router;
 1252 }
 1253 
 1254 void AppIdFreeSMBData(FpSMBData *sd)
 1255 {
 1256     if (sd)
 1257     {
 1258         sd->next = smb_data_free_list;
 1259         smb_data_free_list = sd;
 1260     }
 1261 }
 1262 
 1263 static void AppIdAddSMBData(tAppIdData *flow, unsigned major, unsigned minor, uint32_t flags)
 1264 {
 1265     FpSMBData *sd;
 1266 
 1267     if (flags & FINGERPRINT_UDP_FLAGS_XENIX)
 1268         return;
 1269 
 1270     if (getAppIdFlag(flow, APPID_SESSION_HAS_SMB_INFO))
 1271         return;
 1272 
 1273     if (smb_data_free_list)
 1274     {
 1275         sd = smb_data_free_list;
 1276         smb_data_free_list = sd->next;
 1277     }
 1278     else
 1279         sd = malloc(sizeof(*sd));
 1280     if (!sd)
 1281         return;
 1282 
 1283     if (AppIdFlowdataAdd(flow, sd, APPID_SESSION_DATA_SMB_DATA, (AppIdFreeFCN)AppIdFreeSMBData))
 1284     {
 1285         AppIdFreeSMBData(sd);
 1286         return;
 1287     }
 1288 
 1289     setAppIdFlag(flow, APPID_SESSION_HAS_SMB_INFO);
 1290     sd->major = major;
 1291     sd->minor = minor;
 1292     sd->flags = flags & FINGERPRINT_UDP_FLAGS_MASK;
 1293 }
 1294 
 1295 static int AppIdServiceAddServiceEx(tAppIdData *flow, const SFSnortPacket *pkt, int dir,
 1296                                     const tRNAServiceElement *svc_element,
 1297                                     tAppId appId, const char *vendor, const char *version, AppIdServiceIDState *id_state)
 1298 {
 1299     uint16_t port;
 1300     sfaddr_t *ip;
 1301 
 1302 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)
 1303     uint32_t cid = pkt->pkt_header->carrier_id;
 1304 #endif
 1305 
 1306     if (!flow || !pkt || !svc_element)
 1307     {
 1308         _dpd.errMsg("Invalid arguments to absinthe_add_appId");
 1309         return SERVICE_EINVALID;
 1310     }
 1311 
 1312 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 1313     uint16_t asId; 
 1314 #endif
 1315 
 1316     tAppId tmpServiceAppId = flow->serviceAppId;
 1317     flow->serviceData = svc_element;
 1318 
 1319     if (vendor)
 1320     {
 1321         if (flow->serviceVendor)
 1322             free(flow->serviceVendor);
 1323         flow->serviceVendor = strdup(vendor);
 1324         if (!flow->serviceVendor)
 1325             _dpd.errMsg("failed to allocate service vendor name");
 1326     }
 1327     if (version)
 1328     {
 1329         if (flow->serviceVersion)
 1330             free(flow->serviceVersion);
 1331         flow->serviceVersion = strdup(version);
 1332         if (!flow->serviceVersion)
 1333             _dpd.errMsg("failed to allocate service version");
 1334     }
 1335     setAppIdFlag(flow, APPID_SESSION_SERVICE_DETECTED);
 1336     flow->serviceAppId = appId;
 1337 
 1338     checkSandboxDetection(appId);
 1339 
 1340     if (appId > APP_ID_NONE && tmpServiceAppId != appId)
 1341         CheckDetectorCallback(pkt, flow, (APPID_SESSION_DIRECTION) dir, appId, pAppidActiveConfig);
 1342 
 1343     if (getAppIdFlag(flow, APPID_SESSION_IGNORE_HOST))
 1344         return SERVICE_SUCCESS;
 1345 
 1346     if (!getAppIdFlag(flow, APPID_SESSION_UDP_REVERSED))
 1347     {
 1348         if (dir == APP_ID_FROM_INITIATOR)
 1349         {
 1350             ip = GET_DST_IP(pkt);
 1351             port = pkt->dst_port;
 1352 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 1353             asId = pkt->pkt_header->address_space_id_dst;
 1354 #endif
 1355         }
 1356         else
 1357         {
 1358             ip = GET_SRC_IP(pkt);
 1359             port = pkt->src_port;
 1360 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 1361             asId = pkt->pkt_header->address_space_id_src;
 1362 #endif
 1363         }
 1364         if (flow->service_port)
 1365             port = flow->service_port;
 1366     }
 1367     else
 1368     {
 1369         if (dir == APP_ID_FROM_INITIATOR)
 1370         {
 1371             ip = GET_SRC_IP(pkt);
 1372             port = pkt->src_port;
 1373 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 1374             asId = pkt->pkt_header->address_space_id_src;
 1375 #endif
 1376         }
 1377         else
 1378         {
 1379             ip = GET_DST_IP(pkt);
 1380             port = pkt->dst_port;
 1381 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 1382             asId = pkt->pkt_header->address_space_id_dst;
 1383 #endif
 1384         }
 1385     }
 1386     if (!id_state)
 1387     {
 1388 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)
 1389 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 1390         id_state = AppIdGetServiceIDState(ip, flow->proto, port,
 1391                                           AppIdServiceDetectionLevel(flow),
 1392                                           asId, cid);
 1393 #else
 1394         id_state = AppIdGetServiceIDState(ip, flow->proto, port, AppIdServiceDetectionLevel(flow), cid);
 1395 #endif
 1396 #else /* No carrier id */
 1397 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 1398         id_state = AppIdGetServiceIDState(ip, flow->proto, port,
 1399                                           AppIdServiceDetectionLevel(flow),
 1400                                           asId);
 1401 #else
 1402         id_state = AppIdGetServiceIDState(ip, flow->proto, port, AppIdServiceDetectionLevel(flow));
 1403 #endif
 1404 #endif
 1405     } 
 1406 
 1407 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)   
 1408 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 1409     if (!id_state && !(id_state = AppIdAddServiceIDState(ip, flow->proto, port,
 1410                                                          AppIdServiceDetectionLevel(flow), 
 1411                                                          asId, cid)))
 1412 #else
 1413     if (!id_state && !(id_state = AppIdAddServiceIDState(ip, flow->proto, port, AppIdServiceDetectionLevel(flow), cid)))
 1414 #endif
 1415 #else /* No carrier id */
 1416 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF) 
 1417     if (!id_state && !(id_state = AppIdAddServiceIDState(ip, flow->proto, port,
 1418                                                          AppIdServiceDetectionLevel(flow),
 1419                                                          asId)))
 1420 #else
 1421     if (!id_state && !(id_state = AppIdAddServiceIDState(ip, flow->proto, port, AppIdServiceDetectionLevel(flow))))
 1422 #endif
 1423 #endif
 1424     {
 1425         _dpd.errMsg("Add service failed to create state");
 1426         return SERVICE_ENOMEM;
 1427     }
 1428     flow->service_ip = *ip;
 1429     flow->service_port = port;
 1430 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 1431     flow->serviceAsId = asId;
 1432 #endif
 1433 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)
 1434     flow->carrierId = cid;
 1435 #endif
 1436 
 1437     id_state->reset_time = 0;
 1438     if (id_state->state != SERVICE_ID_VALID)
 1439     {
 1440         id_state->state = SERVICE_ID_VALID;
 1441         id_state->valid_count = 0;
 1442         id_state->detract_count = 0;
 1443         IP_CLEAR(id_state->last_detract);
 1444         id_state->invalid_client_count = 0;
 1445         IP_CLEAR(id_state->last_invalid_client);
 1446     }
 1447     id_state->svc = svc_element;
 1448 
 1449 #ifdef SERVICE_DEBUG
 1450 #if SERVICE_DEBUG_PORT
 1451     if (pkt->dst_port == SERVICE_DEBUG_PORT || pkt->src_port == SERVICE_DEBUG_PORT)
 1452 #endif
 1453     {
 1454         char ipstr[INET6_ADDRSTRLEN];
 1455 
 1456         ipstr[0] = 0;
 1457         inet_ntop(sfaddr_family(&flow->service_ip), (void *)sfaddr_get_ptr(&flow->service_ip), ipstr, sizeof(ipstr));
 1458 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)
 1459 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 1460         fprintf(SF_DEBUG_FILE, "Valid: %s:%u:%u AS %u CID:%u %p %d\n", ipstr,
 1461                 (unsigned)flow->proto, (unsigned)flow->service_port,
 1462                 asId, (unsigned)cid, id_state, (int)id_state->state);
 1463 #else
 1464         fprintf(SF_DEBUG_FILE, "Valid: %s:%u:%u CID:%u %p %d\n", ipstr, (unsigned)flow->proto,
 1465                 (unsigned)flow->service_port, (unsigned)cid, id_state, (int)id_state->state);
 1466 #endif
 1467 #else /* No carrierid support */
 1468 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 1469         fprintf(SF_DEBUG_FILE, "Valid: %s:%u:%u AS %u %p %d\n", ipstr,
 1470                 (unsigned)flow->proto, (unsigned)flow->service_port,
 1471                 asId, id_state, (int)id_state->state);
 1472 #else
 1473         fprintf(SF_DEBUG_FILE, "Valid: %s:%u:%u %p %d\n", ipstr, (unsigned)flow->proto,
 1474                 (unsigned)flow->service_port, id_state, (int)id_state->state);
 1475 #endif
 1476 #endif
 1477     }
 1478 #endif
 1479 
 1480     if (!id_state->valid_count)
 1481     {
 1482         id_state->valid_count++;
 1483         id_state->invalid_client_count = 0;
 1484         IP_CLEAR(id_state->last_invalid_client);
 1485         id_state->detract_count = 0;
 1486         IP_CLEAR(id_state->last_detract);
 1487     }
 1488     else if (id_state->valid_count < STATE_ID_MAX_VALID_COUNT)
 1489         id_state->valid_count++;
 1490 
 1491 #ifdef SERVICE_DEBUG
 1492 #if SERVICE_DEBUG_PORT
 1493     if (pkt->dst_port == SERVICE_DEBUG_PORT || pkt->src_port == SERVICE_DEBUG_PORT)
 1494 #endif
 1495     {
 1496 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)
 1497 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 1498         fprintf(SF_DEBUG_FILE, "Service %d for protocol %u on port %u (%u->%u) AS %u CID %u is valid\n",
 1499                 (int)appId, (unsigned)flow->proto, (unsigned)flow->service_port,
 1500                 (unsigned)pkt->src_port, (unsigned)pkt->dst_port, asId, (unsigned) cid);
 1501 #else
 1502         fprintf(SF_DEBUG_FILE, "Service %d for protocol %u on port %u (%u->%u) CID %u is valid\n",
 1503                 (int)appId, (unsigned)flow->proto, (unsigned)flow->service_port,
 1504                 (unsigned)pkt->src_port, (unsigned)pkt->dst_port, (unsigned) cid);
 1505 #endif
 1506 #else /* No carrier id support */
 1507 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 1508         fprintf(SF_DEBUG_FILE, "Service %d for protocol %u on port %u (%u->%u) AS %u is valid\n",
 1509                 (int)appId, (unsigned)flow->proto, (unsigned)flow->service_port,
 1510                 (unsigned)pkt->src_port, (unsigned)pkt->dst_port, asId);
 1511 #else
 1512         fprintf(SF_DEBUG_FILE, "Service %d for protocol %u on port %u (%u->%u) is valid\n",
 1513                 (int)appId, (unsigned)flow->proto, (unsigned)flow->service_port,
 1514                 (unsigned)pkt->src_port, (unsigned)pkt->dst_port);
 1515 #endif
 1516 #endif
 1517     }
 1518 #endif
 1519     return SERVICE_SUCCESS;
 1520 }
 1521 
 1522 int AppIdServiceAddServiceSubtype(tAppIdData *flow, const SFSnortPacket *pkt, int dir,
 1523                                   const tRNAServiceElement *svc_element,
 1524                                   tAppId appId, const char *vendor, const char *version,
 1525                                   RNAServiceSubtype *subtype, AppIdServiceIDState *id_state)
 1526 {
 1527     flow->subtype = subtype;
 1528     if (!svc_element->current_ref_count)
 1529     {
 1530 #ifdef SERVICE_DEBUG
 1531 #if SERVICE_DEBUG_PORT
 1532         if (pkt->dst_port == SERVICE_DEBUG_PORT || pkt->src_port == SERVICE_DEBUG_PORT)
 1533 #endif
 1534         {
 1535 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)
 1536 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 1537             fprintf(SF_DEBUG_FILE, "Service %d for protocol %u on port %u (%u->%u) AS %u CID %u is valid, but skipped\n",
 1538                     (int)appId, (unsigned)flow->proto, (unsigned)flow->service_port,
 1539                     (unsigned)pkt->src_port, (unsigned)pkt->dst_port, flow->serviceAsId, (unsigned)flow->carrierId); 
 1540 #else
 1541             fprintf(SF_DEBUG_FILE, "Service %d for protocol %u on port %u (%u->%u) CID %u is valid, but skipped\n",
 1542                     (int)appId, (unsigned)flow->proto, (unsigned)flow->service_port,
 1543                     (unsigned)pkt->src_port, (unsigned)pkt->dst_port, (unsigned)flow->carrierId);
 1544 #endif
 1545 #else /* No carrier id */
 1546 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 1547             fprintf(SF_DEBUG_FILE, "Service %d for protocol %u on port %u (%u->%u) AS %u is valid, but skipped\n",
 1548                     (int)appId, (unsigned)flow->proto, (unsigned)flow->service_port,
 1549                     (unsigned)pkt->src_port, (unsigned)pkt->dst_port, flow->serviceAsId);
 1550 #else
 1551             fprintf(SF_DEBUG_FILE, "Service %d for protocol %u on port %u (%u->%u) is valid, but skipped\n",
 1552                     (int)appId, (unsigned)flow->proto, (unsigned)flow->service_port,
 1553                     (unsigned)pkt->src_port, (unsigned)pkt->dst_port);
 1554 #endif
 1555 #endif
 1556         }
 1557 #endif
 1558         return SERVICE_SUCCESS;
 1559     }
 1560     return AppIdServiceAddServiceEx(flow, pkt, dir, svc_element, appId, vendor, version, id_state);
 1561 }
 1562 
 1563 int AppIdServiceAddService(tAppIdData *flow, const SFSnortPacket *pkt, int dir,
 1564                            const tRNAServiceElement *svc_element,
 1565                            tAppId appId, const char *vendor, const char *version,
 1566                            const RNAServiceSubtype *subtype, AppIdServiceIDState *id_state)
 1567 {
 1568     RNAServiceSubtype *new_subtype = NULL;
 1569     RNAServiceSubtype *tmp_subtype;
 1570 
 1571     if (!svc_element->current_ref_count)
 1572     {
 1573 #ifdef SERVICE_DEBUG
 1574 #if SERVICE_DEBUG_PORT
 1575         if (pkt->dst_port == SERVICE_DEBUG_PORT || pkt->src_port == SERVICE_DEBUG_PORT)
 1576 #endif
 1577         {
 1578 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)
 1579 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 1580             fprintf(SF_DEBUG_FILE, "Service %d for protocol %u on port %u (%u->%u) AS %u CID %u is valid, but skipped\n",
 1581                     (int)appId, (unsigned)flow->proto, (unsigned)flow->service_port,
 1582                     (unsigned)pkt->src_port, (unsigned)pkt->dst_port, flow->serviceAsId, (unsigned)flow->carrierId);
 1583 #else
 1584             fprintf(SF_DEBUG_FILE, "Service %d for protocol %u on port %u (%u->%u) CID %u is valid, but skipped\n",
 1585                     (int)appId, (unsigned)flow->proto, (unsigned)flow->service_port,
 1586                     (unsigned)pkt->src_port, (unsigned)pkt->dst_port, (unsigned)flow->carrierId);
 1587 #endif
 1588 #else /* No carrierid support */
 1589 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 1590             fprintf(SF_DEBUG_FILE, "Service %d for protocol %u on port %u (%u->%u) AS %u is valid, but skipped\n",
 1591                     (int)appId, (unsigned)flow->proto, (unsigned)flow->service_port,
 1592                     (unsigned)pkt->src_port, (unsigned)pkt->dst_port, flow->serviceAsId);
 1593 #else
 1594             fprintf(SF_DEBUG_FILE, "Service %d for protocol %u on port %u (%u->%u) is valid, but skipped\n",
 1595                     (int)appId, (unsigned)flow->proto, (unsigned)flow->service_port,
 1596                     (unsigned)pkt->src_port, (unsigned)pkt->dst_port);
 1597 #endif
 1598 #endif
 1599         }
 1600 #endif
 1601         return SERVICE_SUCCESS;
 1602     }
 1603 
 1604     for ( ; subtype; subtype = subtype->next)
 1605     {
 1606         tmp_subtype = calloc(1, sizeof(*tmp_subtype));
 1607         if (tmp_subtype)
 1608         {
 1609             if (subtype->service)
 1610             {
 1611                 tmp_subtype->service = strdup(subtype->service);
 1612                 if (!tmp_subtype->service)
 1613                     _dpd.errMsg("failed to allocate service subtype");
 1614             }
 1615             if (subtype->vendor)
 1616             {
 1617                 tmp_subtype->vendor = strdup(subtype->vendor);
 1618                 if (!tmp_subtype->vendor)
 1619                     _dpd.errMsg("failed to allocate service subtype vendor");
 1620             }
 1621             if (subtype->version)
 1622             {
 1623                 tmp_subtype->version = strdup(subtype->version);
 1624                 if (!tmp_subtype->version)
 1625                     _dpd.errMsg("failed to allocate service version");
 1626             }
 1627             tmp_subtype->next = new_subtype;
 1628             new_subtype = tmp_subtype;
 1629         }
 1630     }
 1631     flow->subtype = new_subtype;
 1632     return AppIdServiceAddServiceEx(flow, pkt, dir, svc_element, appId, vendor, version, id_state);
 1633 }
 1634 
 1635 int AppIdServiceInProcess(tAppIdData *flow, const SFSnortPacket *pkt, int dir,
 1636                           const tRNAServiceElement *svc_element,
 1637                           AppIdServiceIDState *id_state)
 1638 {
 1639     if (!flow || !pkt)
 1640     {
 1641         _dpd.errMsg( "Invalid arguments to service_in_process");
 1642         return SERVICE_EINVALID;
 1643     }
 1644 
 1645     if (dir == APP_ID_FROM_INITIATOR || getAppIdFlag(flow, APPID_SESSION_IGNORE_HOST|APPID_SESSION_UDP_REVERSED))
 1646         return SERVICE_SUCCESS;
 1647 
 1648     if (!sfaddr_is_set(&flow->service_ip))
 1649     {
 1650         sfaddr_t *ip;
 1651 
 1652         ip = GET_SRC_IP(pkt);
 1653         flow->service_ip = *ip;
 1654 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 1655         flow->serviceAsId = pkt->pkt_header->address_space_id_src;
 1656 #endif
 1657         if (!flow->service_port)
 1658             flow->service_port = pkt->src_port;
 1659 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)
 1660         flow->carrierId = pkt->pkt_header->carrier_id;
 1661 #endif
 1662     }
 1663 #ifdef SERVICE_DEBUG
 1664 #if SERVICE_DEBUG_PORT
 1665     if (pkt->dst_port == SERVICE_DEBUG_PORT || pkt->src_port == SERVICE_DEBUG_PORT)
 1666 #endif
 1667     {
 1668 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)
 1669 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 1670         fprintf(SF_DEBUG_FILE, "Service for protocol %u on port %u is in process (%u->%u) AS %u CID %u, %p %s",
 1671                 (unsigned)flow->proto, (unsigned)flow->service_port, (unsigned)pkt->src_port,
 1672                 (unsigned)pkt->dst_port, flow->serviceAsId, (unsigned)flow->carrierId, 
 1673                 svc_element->validate, svc_element->name ? :"UNKNOWN");
 1674 #else
 1675         fprintf(SF_DEBUG_FILE, "Service for protocol %u on port %u is in process (%u->%u) CID %u, %p %s",
 1676                 (unsigned)flow->proto, (unsigned)flow->service_port, (unsigned)pkt->src_port, (unsigned)pkt->dst_port,
 1677                 (unsigned)flow->carrierId, svc_element->validate, svc_element->name ? :"UNKNOWN");
 1678 #endif
 1679 #else /* No carrierid support */
 1680 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 1681         fprintf(SF_DEBUG_FILE, "Service for protocol %u on port %u is in process (%u->%u) AS %u, %p %s",
 1682                 (unsigned)flow->proto, (unsigned)flow->service_port, (unsigned)pkt->src_port,
 1683                 (unsigned)pkt->dst_port, flow->serviceAsId, 
 1684                 svc_element->validate, svc_element->name ? :"UNKNOWN");
 1685 #else
 1686         fprintf(SF_DEBUG_FILE, "Service for protocol %u on port %u is in process (%u->%u), %p %s",
 1687                 (unsigned)flow->proto, (unsigned)flow->service_port, (unsigned)pkt->src_port, (unsigned)pkt->dst_port,
 1688                 svc_element->validate, svc_element->name ? :"UNKNOWN");
 1689 #endif
 1690 #endif
 1691 
 1692     }
 1693 #endif
 1694 
 1695     return SERVICE_SUCCESS;
 1696 }
 1697 
 1698 /**Called when service can not be identified on a flow but the checks failed on client request
 1699  * rather than server response. When client request fails a check, it may be specific to a client
 1700  * therefore we should not fail the service right away. If the same behavior is seen from the same
 1701  * client ultimately we will have to fail the service. If the same behavior is seen from different
 1702  * clients going to same service then this most likely the service is something else.
 1703  */
 1704 int AppIdServiceIncompatibleData(tAppIdData *flow, const SFSnortPacket *pkt, int dir,
 1705                                  const tRNAServiceElement *svc_element, unsigned flow_data_index,
 1706                                  const tAppIdConfig *pConfig, AppIdServiceIDState *id_state)
 1707 {
 1708     if (!flow || !pkt)
 1709     {
 1710         _dpd.errMsg("Invalid arguments to service_incompatible_data");
 1711         return SERVICE_EINVALID;
 1712     }
 1713 
 1714     if (flow_data_index != APPID_SESSION_DATA_NONE)
 1715         AppIdFlowdataDelete(flow, flow_data_index);
 1716 
 1717     /* If we're still working on a port/pattern list of detectors, then ignore
 1718      * individual fails until we're done looking at everything. */
 1719     if (    (flow->serviceData == NULL)                                                /* we're working on a list of detectors, and... */
 1720          && (flow->candidate_service_list != NULL))
 1721     {
 1722         if (sflist_count(flow->candidate_service_list) != 0)                           /*     it's not empty */
 1723         {
 1724             return SERVICE_SUCCESS;
 1725         }
 1726     }
 1727 
 1728     setAppIdFlag(flow, APPID_SESSION_SERVICE_DETECTED);
 1729     clearAppIdFlag(flow, APPID_SESSION_CONTINUE);
 1730 
 1731     flow->serviceAppId = APP_ID_NONE;
 1732 
 1733     if (getAppIdFlag(flow, APPID_SESSION_IGNORE_HOST|APPID_SESSION_UDP_REVERSED) || (svc_element && !svc_element->current_ref_count))
 1734         return SERVICE_SUCCESS;
 1735 
 1736     if (dir == APP_ID_FROM_INITIATOR)
 1737     {
 1738         setAppIdFlag(flow, APPID_SESSION_INCOMPATIBLE);
 1739         return SERVICE_SUCCESS;
 1740     }
 1741 
 1742     uint16_t port;
 1743     sfaddr_t *ip;
 1744     ip = GET_SRC_IP(pkt);
 1745     port = flow->service_port ? flow->service_port : pkt->src_port;
 1746 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 1747     uint16_t asId = pkt->pkt_header->address_space_id_src;
 1748 #endif
 1749 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)
 1750     uint32_t cid = pkt->pkt_header->carrier_id;
 1751 #endif
 1752 
 1753     if (!id_state)
 1754     {    
 1755 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)
 1756 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 1757         id_state = AppIdGetServiceIDState(ip, flow->proto, port,
 1758                                           AppIdServiceDetectionLevel(flow),
 1759                                           asId, cid);
 1760 #else
 1761         id_state = AppIdGetServiceIDState(ip, flow->proto, port, AppIdServiceDetectionLevel(flow), cid);
 1762 #endif
 1763 #else /* No carrier id */
 1764 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 1765         id_state = AppIdGetServiceIDState(ip, flow->proto, port,
 1766                                           AppIdServiceDetectionLevel(flow),
 1767                                           asId);
 1768 #else
 1769         id_state = AppIdGetServiceIDState(ip, flow->proto, port, AppIdServiceDetectionLevel(flow));
 1770 #endif
 1771 #endif
 1772     }   
 1773 
 1774     if (!id_state)
 1775     {
 1776 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)
 1777 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 1778         if (!(id_state = AppIdAddServiceIDState(ip, flow->proto, port,
 1779                                                 AppIdServiceDetectionLevel(flow), 
 1780                                                 asId, cid)))
 1781 #else
 1782         if (!(id_state = AppIdAddServiceIDState(ip, flow->proto, port, AppIdServiceDetectionLevel(flow), cid)))
 1783 #endif
 1784 #else /* No carrier id */
 1785 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF) 
 1786         if (!(id_state = AppIdAddServiceIDState(ip, flow->proto, port,
 1787                                                 AppIdServiceDetectionLevel(flow),
 1788                                                 asId)))
 1789 #else
 1790         if (!(id_state = AppIdAddServiceIDState(ip, flow->proto, port, AppIdServiceDetectionLevel(flow))))
 1791 #endif
 1792 #endif
 1793         {
 1794             _dpd.errMsg("Incompatible service failed to create state");
 1795             return SERVICE_ENOMEM;
 1796         }
 1797         id_state->svc = svc_element;
 1798     }
 1799     else
 1800     {
 1801         id_state->reset_time = 0;
 1802     }
 1803     flow->service_ip = *ip;
 1804     flow->service_port = port;
 1805 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 1806     flow->serviceAsId = asId;
 1807 #endif
 1808 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)
 1809     flow->carrierId = cid;
 1810 #endif
 1811 #ifdef SERVICE_DEBUG
 1812 #if SERVICE_DEBUG_PORT
 1813     if (pkt->dst_port == SERVICE_DEBUG_PORT || pkt->src_port == SERVICE_DEBUG_PORT)
 1814 #endif
 1815     {
 1816 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)
 1817 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 1818        fprintf(SF_DEBUG_FILE, "service_IC: State %s for protocol %u on port %u (%u->%u) AS %u CID %u, count %u, %s\n",
 1819                serviceIdStateName[id_state->state], (unsigned)flow->proto, (unsigned)flow->service_port,
 1820                (unsigned)pkt->src_port, (unsigned)pkt->dst_port, asId, (unsigned)flow->carrierId,
 1821                id_state->invalid_client_count,
 1822                (id_state->svc && id_state->svc->name) ? id_state->svc->name:"UNKNOWN");
 1823 #else
 1824         fprintf(SF_DEBUG_FILE, "service_IC: State %s for protocol %u on port %u (%u->%u) CID %u, count %u, %s\n",
 1825                 serviceIdStateName[id_state->state], (unsigned)flow->proto, (unsigned)flow->service_port,
 1826                 (unsigned)pkt->src_port, (unsigned)pkt->dst_port, (unsigned) flow->carrierId, id_state->invalid_client_count,
 1827                 (id_state->svc && id_state->svc->name) ? id_state->svc->name:"UNKNOWN");
 1828 #endif
 1829 #else /* No carrier id */
 1830 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 1831        fprintf(SF_DEBUG_FILE, "service_IC: State %s for protocol %u on port %u (%u->%u) AS %u, count %u, %s\n",
 1832                serviceIdStateName[id_state->state], (unsigned)flow->proto, (unsigned)flow->service_port,
 1833                (unsigned)pkt->src_port, (unsigned)pkt->dst_port, asId, 
 1834                id_state->invalid_client_count,
 1835                (id_state->svc && id_state->svc->name) ? id_state->svc->name:"UNKNOWN");
 1836 #else
 1837         fprintf(SF_DEBUG_FILE, "service_IC: State %s for protocol %u on port %u (%u->%u), count %u, %s\n",
 1838                 serviceIdStateName[id_state->state], (unsigned)flow->proto, (unsigned)flow->service_port,
 1839                 (unsigned)pkt->src_port, (unsigned)pkt->dst_port, id_state->invalid_client_count,
 1840                 (id_state->svc && id_state->svc->name) ? id_state->svc->name:"UNKNOWN");
 1841 #endif
 1842 #endif
 1843     }
 1844 #endif
 1845 
 1846 #ifdef SERVICE_DEBUG
 1847 #if SERVICE_DEBUG_PORT
 1848 if (pkt->dst_port == SERVICE_DEBUG_PORT || pkt->src_port == SERVICE_DEBUG_PORT)
 1849 #endif
 1850 {
 1851     char ipstr[INET6_ADDRSTRLEN];
 1852 
 1853     ipstr[0] = 0;
 1854     inet_ntop(sfaddr_family(&flow->service_ip), (void *)sfaddr_get_ptr(&flow->service_ip), ipstr, sizeof(ipstr));
 1855     fprintf(SF_DEBUG_FILE, "Incompat: %s:%u:%u %p %d %s\n", ipstr, (unsigned)flow->proto, (unsigned)flow->service_port,
 1856             id_state, (int)id_state->state,
 1857             (id_state->svc && id_state->svc->name) ? id_state->svc->name:"UNKNOWN");
 1858 }
 1859 #endif
 1860 
 1861     return SERVICE_SUCCESS;
 1862 }
 1863 
 1864 int AppIdServiceFailService(tAppIdData* flow, const SFSnortPacket *pkt, int dir,
 1865                             const tRNAServiceElement *svc_element, unsigned flow_data_index,
 1866                             const tAppIdConfig *pConfig, AppIdServiceIDState *id_state)
 1867 {
 1868     if (flow_data_index != APPID_SESSION_DATA_NONE)
 1869         AppIdFlowdataDelete(flow, flow_data_index);
 1870 
 1871     /* If we're still working on a port/pattern list of detectors, then ignore
 1872      * individual fails until we're done looking at everything. */
 1873     if (    (flow->serviceData == NULL)                                                /* we're working on a list of detectors, and... */
 1874          && (flow->candidate_service_list != NULL))
 1875     {
 1876         if (sflist_count(flow->candidate_service_list) != 0)                           /*     it's not empty */
 1877         {
 1878             return SERVICE_SUCCESS;
 1879         }
 1880     }
 1881 
 1882     flow->serviceAppId = APP_ID_NONE;
 1883 
 1884     setAppIdFlag(flow, APPID_SESSION_SERVICE_DETECTED);
 1885     clearAppIdFlag(flow, APPID_SESSION_CONTINUE);
 1886 
 1887     /* detectors should be careful in marking flow UDP_REVERSED otherwise the same detector
 1888      * gets all future flows. UDP_REVERSE should be marked only when detector positively
 1889      * matches opposite direction patterns. */
 1890 
 1891     if (getAppIdFlag(flow, APPID_SESSION_IGNORE_HOST|APPID_SESSION_UDP_REVERSED) || (svc_element && !svc_element->current_ref_count))
 1892         return SERVICE_SUCCESS;
 1893 
 1894     /* For subsequent packets, avoid marking service failed on client packet,
 1895      * otherwise the service will show up on client side. */
 1896     if (dir == APP_ID_FROM_INITIATOR)
 1897     {
 1898         setAppIdFlag(flow, APPID_SESSION_INCOMPATIBLE);
 1899         return SERVICE_SUCCESS;
 1900     }
 1901 
 1902     uint16_t port;
 1903     sfaddr_t *ip;
 1904     ip = GET_SRC_IP(pkt);
 1905     port = flow->service_port ? flow->service_port : pkt->src_port;
 1906     flow->service_ip = *ip;
 1907     flow->service_port = port;
 1908 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 1909     flow->serviceAsId = pkt->pkt_header->address_space_id_src;
 1910 #endif
 1911 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)
 1912     flow->carrierId = pkt->pkt_header->carrier_id;
 1913 #endif
 1914     if (!id_state)
 1915     { 
 1916 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)   
 1917 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF) 
 1918        id_state = AppIdGetServiceIDState(ip, flow->proto, port,
 1919                                          AppIdServiceDetectionLevel(flow),
 1920                                          flow->serviceAsId, flow->carrierId);
 1921 #else
 1922        id_state = AppIdGetServiceIDState(ip, flow->proto, port, AppIdServiceDetectionLevel(flow), flow->carrierId);
 1923 #endif
 1924 #else /* No carrierid support */
 1925 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 1926        id_state = AppIdGetServiceIDState(ip, flow->proto, port,
 1927                                          AppIdServiceDetectionLevel(flow),
 1928                                          flow->serviceAsId);
 1929 #else
 1930        id_state = AppIdGetServiceIDState(ip, flow->proto, port, AppIdServiceDetectionLevel(flow));
 1931 #endif
 1932 #endif
 1933     }   
 1934 
 1935     if (!id_state)
 1936     {
 1937 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)
 1938 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 1939         if (!(id_state = AppIdAddServiceIDState(ip, flow->proto, port,
 1940                                                 AppIdServiceDetectionLevel(flow),
 1941                                                 flow->serviceAsId, flow->carrierId)))
 1942 #else
 1943         if (!(id_state = AppIdAddServiceIDState(ip, flow->proto, port, AppIdServiceDetectionLevel(flow), flow->carrierId)))
 1944 #endif
 1945 #else /* No carrierid support */
 1946 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF) 
 1947         if (!(id_state = AppIdAddServiceIDState(ip, flow->proto, port,
 1948                                                 AppIdServiceDetectionLevel(flow),
 1949                                                 flow->serviceAsId)))
 1950 #else
 1951         if (!(id_state = AppIdAddServiceIDState(ip, flow->proto, port, AppIdServiceDetectionLevel(flow))))
 1952 #endif
 1953 #endif
 1954         {
 1955             _dpd.errMsg("Fail service failed to create state");
 1956             return SERVICE_ENOMEM;
 1957         }
 1958         id_state->svc = svc_element;
 1959     }
 1960     id_state->reset_time = 0;
 1961 
 1962 #ifdef SERVICE_DEBUG
 1963 #if SERVICE_DEBUG_PORT
 1964     if (pkt->dst_port == SERVICE_DEBUG_PORT || pkt->src_port == SERVICE_DEBUG_PORT)
 1965 #endif
 1966     {
 1967 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)
 1968 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 1969        fprintf(SF_DEBUG_FILE, "service_fail: State %s for protocol %u on port %u (%u->%u) AS %u CID %u, count %u, valid count %u, currSvc %s\n",
 1970                serviceIdStateName[id_state->state], (unsigned)flow->proto, (unsigned)flow->service_port,
 1971                (unsigned)pkt->src_port, (unsigned)pkt->dst_port, flow->serviceAsId, (unsigned)flow->carrierId,
 1972                id_state->invalid_client_count, id_state->valid_count,
 1973                (svc_element && svc_element->name) ? svc_element->name:"UNKNOWN");
 1974 #else
 1975         fprintf(SF_DEBUG_FILE, "service_fail: State %s for protocol %u on port %u (%u->%u) CID %u, count %u, valid count %u, currSvc %s\n",
 1976                 serviceIdStateName[id_state->state], (unsigned)flow->proto, (unsigned)flow->service_port,
 1977                 (unsigned)pkt->src_port, (unsigned)pkt->dst_port, (unsigned)flow->carrierId, id_state->invalid_client_count, id_state->valid_count,
 1978                 (svc_element && svc_element->name) ? svc_element->name:"UNKNOWN");
 1979 #endif
 1980 #else /* No carrierid support */
 1981 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 1982        fprintf(SF_DEBUG_FILE, "service_fail: State %s for protocol %u on port %u (%u->%u) AS %u, count %u, valid count %u, currSvc %s\n",
 1983                serviceIdStateName[id_state->state], (unsigned)flow->proto, (unsigned)flow->service_port,
 1984                (unsigned)pkt->src_port, (unsigned)pkt->dst_port, flow->serviceAsId, 
 1985                id_state->invalid_client_count, id_state->valid_count,
 1986                (svc_element && svc_element->name) ? svc_element->name:"UNKNOWN");
 1987 #else
 1988         fprintf(SF_DEBUG_FILE, "service_fail: State %s for protocol %u on port %u (%u->%u), count %u, valid count %u, currSvc %s\n",
 1989                 serviceIdStateName[id_state->state], (unsigned)flow->proto, (unsigned)flow->service_port,
 1990                 (unsigned)pkt->src_port, (unsigned)pkt->dst_port, id_state->invalid_client_count, id_state->valid_count,
 1991                 (svc_element && svc_element->name) ? svc_element->name:"UNKNOWN");
 1992 #endif
 1993 #endif
 1994     }
 1995 #endif
 1996 
 1997 #ifdef SERVICE_DEBUG
 1998 #if SERVICE_DEBUG_PORT
 1999 if (pkt->dst_port == SERVICE_DEBUG_PORT || pkt->src_port == SERVICE_DEBUG_PORT)
 2000 #endif
 2001 {
 2002     char ipstr[INET6_ADDRSTRLEN];
 2003 
 2004     ipstr[0] = 0;
 2005     inet_ntop(sfaddr_family(&flow->service_ip), (void *)sfaddr_get_ptr(&flow->service_ip), ipstr, sizeof(ipstr));
 2006     fprintf(SF_DEBUG_FILE, "Fail: %s:%u:%u %p %d %s\n", ipstr, (unsigned)flow->proto, (unsigned)flow->service_port,
 2007             id_state, (int)id_state->state,
 2008             (id_state->svc && id_state->svc->name) ? id_state->svc->name:"UNKNOWN");
 2009 }
 2010 #endif
 2011 
 2012     return SERVICE_SUCCESS;
 2013 }
 2014 
 2015 /* Handle some exception cases on failure:
 2016  *  - valid_count: If we have a detector that should be valid, but it keeps
 2017  *    failing, consider restarting the detector search.
 2018  *  - invalid_client_count: If our service detector search had trouble
 2019  *    simply because of unrecognized client data, then consider retrying
 2020  *    the search again. */
 2021 static void HandleFailure(tAppIdData *flowp,
 2022                           AppIdServiceIDState *id_state,
 2023                           sfaddr_t *client_ip,
 2024                           SFSnortPacket *p)
 2025 {
 2026     if (!id_state)
 2027         return;
 2028 
 2029     /* If we had a valid detector, check for too many fails.  If so, start
 2030      * search sequence again. */
 2031     if (id_state->state == SERVICE_ID_VALID)
 2032     {
 2033         /* Too many invalid clients?  If so, count it as an invalid detect. */
 2034         if (id_state->invalid_client_count >= STATE_ID_INVALID_CLIENT_THRESHOLD)
 2035         {
 2036             if (id_state->valid_count <= 1)
 2037             {
 2038                 id_state->state = SERVICE_ID_NEW;
 2039                 id_state->invalid_client_count = 0;
 2040                 IP_CLEAR(id_state->last_invalid_client);
 2041                 id_state->valid_count = 0;
 2042                 id_state->detract_count = 0;
 2043                 IP_CLEAR(id_state->last_detract);
 2044                 id_state->svc = NULL;
 2045             }
 2046             else
 2047             {
 2048                 id_state->valid_count--;
 2049                 id_state->last_invalid_client = *client_ip;
 2050                 id_state->invalid_client_count = 0;
 2051 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 2052                 id_state->asId = flowp->serviceAsId;
 2053 #endif
 2054             }
 2055         }
 2056         /* Just a plain old fail.  If too many of these happen, start
 2057          * search process over. */
 2058         else if (id_state->invalid_client_count == 0)
 2059         {
 2060             if (sfip_fast_eq6(&id_state->last_detract, client_ip))
 2061                 id_state->detract_count++;
 2062             else 
 2063             {
 2064                 id_state->last_detract = *client_ip;
 2065 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 2066                 id_state->asId = flowp->serviceAsId;
 2067 #endif
 2068             }
 2069 
 2070             if (id_state->detract_count >= STATE_ID_NEEDED_DUPE_DETRACT_COUNT)
 2071             {
 2072                 if (id_state->valid_count <= 1)
 2073                 {
 2074                     id_state->state = SERVICE_ID_NEW;
 2075                     id_state->invalid_client_count = 0;
 2076                     IP_CLEAR(id_state->last_invalid_client);
 2077                     id_state->valid_count = 0;
 2078                     id_state->detract_count = 0;
 2079                     IP_CLEAR(id_state->last_detract);
 2080                     id_state->svc = NULL;
 2081                 }
 2082                 else
 2083                     id_state->valid_count--;
 2084             }
 2085         }
 2086     }
 2087     /* In SERVICE_ID_NEW, if port/pattern fails and not in a mid-stream, go to brute force. */
 2088     else if (id_state->state == SERVICE_ID_NEW &&
 2089             flowp->search_state == SERVICE_ID_PENDING &&
 2090             (sflist_count(flowp->candidate_service_list) == 0) &&
 2091             p && !(_dpd.sessionAPI->get_session_flags(p->stream_session) & SSNFLAG_MIDSTREAM))
 2092     {
 2093         id_state->state = SERVICE_ID_BRUTE_FORCE;
 2094     }
 2095 }
 2096 
 2097 /**Changes in_process service state to failed state when a flow is terminated.
 2098  *
 2099  * RNA used to repeat the same service detector if the detector remained in process till the flow terminated. Thus RNA
 2100  * got stuck on this one detector and never tried another service detector. This function will treat such a detector
 2101  * as returning incompatibleData when the flow is terminated. The intent here to make RNA try other service detectors but
 2102  * unlike incompatibleData status, we dont want to undermine confidence in the service.
 2103  *
 2104  * @note SFSnortPacket may be NULL when this function is called upon session timeout.
 2105  */
 2106 void FailInProcessService(tAppIdData *flowp, const tAppIdConfig *pConfig)
 2107 {
 2108     AppIdServiceIDState *id_state;
 2109     sfaddr_t *tmp_ip;
 2110 
 2111     if (getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED|APPID_SESSION_UDP_REVERSED))
 2112         return;
 2113 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)
 2114 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 2115     id_state = AppIdGetServiceIDState(&flowp->service_ip, flowp->proto, 
 2116                                       flowp->service_port, 
 2117                                       AppIdServiceDetectionLevel(flowp),
 2118                                       flowp->serviceAsId, flowp->carrierId);
 2119 #else
 2120     id_state = AppIdGetServiceIDState(&flowp->service_ip, flowp->proto,
 2121                                       flowp->service_port, 
 2122                                       AppIdServiceDetectionLevel(flowp), flowp->carrierId);
 2123 #endif
 2124 #else /* No carrier id support */
 2125 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF) 
 2126     id_state = AppIdGetServiceIDState(&flowp->service_ip, flowp->proto,
 2127                                       flowp->service_port, 
 2128                                       AppIdServiceDetectionLevel(flowp),
 2129                                       flowp->serviceAsId);
 2130 #else
 2131     id_state = AppIdGetServiceIDState(&flowp->service_ip, flowp->proto,
 2132                                       flowp->service_port, 
 2133                                       AppIdServiceDetectionLevel(flowp));
 2134 #endif
 2135 #endif
 2136 
 2137 #ifdef SERVICE_DEBUG
 2138 #if SERVICE_DEBUG_PORT
 2139     if (flowp->service_port == SERVICE_DEBUG_PORT)
 2140 #endif
 2141         fprintf(SF_DEBUG_FILE, "FailInProcess %" PRIx64 ", %08X:%u proto %u\n",
 2142                 flowp->common.flags, sfaddr_get_ip4_value(&flowp->common.initiator_ip),
 2143                 (unsigned)flowp->service_port, (unsigned)flowp->proto);
 2144 #endif
 2145 
 2146     if (!id_state || (id_state->svc && !id_state->svc->current_ref_count))
 2147         return;
 2148 
 2149 #ifdef SERVICE_DEBUG
 2150 #if SERVICE_DEBUG_PORT
 2151     if (flowp->service_port == SERVICE_DEBUG_PORT)
 2152 #endif
 2153         fprintf(SF_DEBUG_FILE, "FailInProcess: State %s for protocol %u on port %u, count %u, %s\n",
 2154                 serviceIdStateName[id_state->state], (unsigned)flowp->proto, (unsigned)flowp->service_port,
 2155                 id_state->invalid_client_count, (id_state->svc && id_state->svc->name) ? id_state->svc->name:"UNKNOWN");
 2156 #endif
 2157 
 2158     id_state->invalid_client_count += STATE_ID_INCONCLUSIVE_SERVICE_WEIGHT;
 2159 
 2160 #ifdef TARGET_BASED
 2161     tmp_ip = _dpd.sessionAPI->get_session_ip_address(flowp->ssn, SSN_DIR_FROM_SERVER);
 2162     if (sfip_fast_eq6(tmp_ip, &flowp->service_ip))
 2163         tmp_ip = _dpd.sessionAPI->get_session_ip_address(flowp->ssn, SSN_DIR_FROM_CLIENT);
 2164 #endif
 2165 
 2166     HandleFailure(flowp, id_state, tmp_ip, 0);
 2167 
 2168 #ifdef SERVICE_DEBUG
 2169 #if SERVICE_DEBUG_PORT
 2170     if (flowp->service_port == SERVICE_DEBUG_PORT)
 2171 #endif
 2172         fprintf(SF_DEBUG_FILE, "FailInProcess: Changed State to %s for protocol %u on port %u, count %u, %s\n",
 2173                 serviceIdStateName[id_state->state], (unsigned)flowp->proto, (unsigned)flowp->service_port,
 2174                 id_state->invalid_client_count, (id_state->svc && id_state->svc->name) ? id_state->svc->name:"UNKNOWN");
 2175 #endif
 2176 }
 2177 
 2178 /* This function should be called to find the next service detector to try when
 2179  * we have not yet found a valid detector in the host tracker.  It will try
 2180  * both port and/or pattern (but not brute force - that should be done outside
 2181  * of this function).  This includes UDP reversed services.  A valid id_state
 2182  * (even if just initialized to the NEW state) should exist before calling this
 2183  * function.  The state coming out of this function will reflect the state in
 2184  * which the next detector was found.  If nothing is found, it'll indicate that
 2185  * brute force should be tried next as a state (and return NULL).  This
 2186  * function can be called once or multiple times (to run multiple detectors in
 2187  * parallel) per flow.  Do not call this function if a detector has already
 2188  * been specified (serviceData).  Basically, this function handles going
 2189  * through the main port/pattern search (and returning which detector to add
 2190  * next to the list of detectors to try (even if only 1)). */
 2191 static const tRNAServiceElement * AppIdGetNextService(const SFSnortPacket *p,
 2192                                                       const int dir,
 2193                                                       tAppIdData *rnaData,
 2194                                                       const tAppIdConfig *pConfig,
 2195                                                       const tRNAServiceElement *lastService,
 2196                                                       struct _SERVICE_MATCH **serviceList,
 2197                                                       struct _SERVICE_MATCH **currentService)
 2198 {
 2199     tRNAServiceElement *svc = NULL;
 2200     uint8_t proto;
 2201 
 2202     proto = rnaData->proto;
 2203 
 2204     /* See if there are any port detectors to try.  If not, move onto patterns. */
 2205     if (rnaData->search_state == SERVICE_ID_PORT)
 2206     {
 2207         svc = AppIdGetNextServiceByPort(proto, (uint16_t)((dir == APP_ID_FROM_RESPONDER) ? p->src_port : p->dst_port), lastService, rnaData, pConfig);
 2208         if (svc)
 2209             return svc;
 2210         else
 2211             rnaData->search_state = SERVICE_ID_PATTERN;
 2212     }
 2213 
 2214     if (rnaData->search_state == SERVICE_ID_PATTERN)
 2215     {
 2216         /* If we haven't found anything yet, try to see if we get any hits
 2217          * first with UDP reversed services before moving onto pattern matches. */
 2218         if (dir == APP_ID_FROM_INITIATOR)
 2219         {
 2220             if (!getAppIdFlag(rnaData, APPID_SESSION_ADDITIONAL_PACKET) && (proto == IPPROTO_UDP)
 2221                  && !rnaData->tried_reverse_service )
 2222             {
 2223                 AppIdServiceIDState * reverse_id_state;
 2224                 const tRNAServiceElement * reverse_service = NULL;
 2225                 sfaddr_t * reverse_ip = GET_SRC_IP(p);
 2226                 rnaData->tried_reverse_service = true;
 2227 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)
 2228                 uint32_t cid = p->pkt_header->carrier_id;
 2229 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 2230                 if((reverse_id_state = AppIdGetServiceIDState(reverse_ip, proto, p->src_port, 
 2231                                                               AppIdServiceDetectionLevel(rnaData), 
 2232                                                               p->pkt_header->address_space_id_src, cid)))
 2233 #else
 2234                 if ((reverse_id_state = AppIdGetServiceIDState(reverse_ip, proto, p->src_port, AppIdServiceDetectionLevel(rnaData),
 2235                                                                cid)))
 2236 #endif
 2237 #else /* No carrierid support */
 2238 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF) 
 2239                 if((reverse_id_state = AppIdGetServiceIDState(reverse_ip, proto, p->src_port,
 2240                                                               AppIdServiceDetectionLevel(rnaData),
 2241                                                               p->pkt_header->address_space_id_src)))
 2242 #else
 2243                 if ((reverse_id_state = AppIdGetServiceIDState(reverse_ip, proto, p->src_port, AppIdServiceDetectionLevel(rnaData))))
 2244 #endif
 2245 #endif
 2246                 {
 2247                     reverse_service = reverse_id_state->svc;
 2248                 }
 2249                 if (    reverse_service
 2250                      || (pConfig->serviceConfig.udp_reversed_services[p->src_port] && (reverse_service = sflist_first(pConfig->serviceConfig.udp_reversed_services[p->src_port])))
 2251                      || (p->payload_size && (reverse_service = AppIdGetServiceByPattern(p, proto, dir, &pConfig->serviceConfig, serviceList, currentService))) )
 2252                 {
 2253                     return reverse_service;
 2254                 }
 2255             }
 2256             return NULL;
 2257         }
 2258         /* Try pattern match detectors. */
 2259         else    /* APP_ID_FROM_RESPONDER */
 2260         {
 2261             if (*serviceList == NULL) // no list yet (need to make one)
 2262                 svc = AppIdGetServiceByPattern(p, proto, dir, &pConfig->serviceConfig, serviceList, currentService);
 2263             else /* already have a pattern service list (just use it) */
 2264             {
 2265                 svc = AppIdNextServiceByPattern(currentService
 2266 #ifdef SERVICE_DEBUG
 2267 #if SERVICE_DEBUG_PORT
 2268                                                 , flow->service_port
 2269 #endif
 2270 #endif
 2271                                                 );
 2272             }
 2273             if (svc)
 2274                 return svc;
 2275             else
 2276                 rnaData->search_state = SERVICE_ID_PENDING; // We are done pattern matching
 2277         }
 2278     }
 2279 
 2280     /* If it was in VALID or BRUTE FORCE or no service found */
 2281     return NULL;
 2282 }
 2283 int AppIdDiscoverService(SFSnortPacket *p, const APPID_SESSION_DIRECTION dir, tAppIdData *rnaData, const tAppIdConfig *pConfig)
 2284 {
 2285     int ret = SERVICE_NOMATCH;
 2286     const tRNAServiceElement *service = NULL;
 2287     AppIdServiceIDState *id_state = NULL;
 2288     uint8_t proto = rnaData->proto;
 2289     SF_LNODE *node;
 2290     ServiceValidationArgs args;
 2291     bool bruteForceDone = false;
 2292     bool appIdFailServiceDone = false;
 2293     sfaddr_t *ip;
 2294     uint16_t port;
 2295 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 2296     uint16_t asId;
 2297 #endif
 2298 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)
 2299     uint32_t cid = 0;
 2300 #endif
 2301 
 2302     /* Get packet info. */
 2303     if (sfaddr_is_set(&rnaData->service_ip))
 2304     {
 2305         ip   = &rnaData->service_ip;
 2306         port = rnaData->service_port;
 2307 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 2308         asId = rnaData->serviceAsId;
 2309 #endif
 2310 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)
 2311         cid = rnaData->carrierId;
 2312 #endif
 2313     }
 2314     else
 2315     {
 2316         if (dir == APP_ID_FROM_RESPONDER)
 2317         {
 2318             ip   = GET_SRC_IP(p);
 2319             port = p->src_port;
 2320 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 2321             asId = p->pkt_header->address_space_id_src;
 2322 #endif
 2323         }
 2324         else
 2325         {
 2326             ip   = GET_DST_IP(p);
 2327             port = p->dst_port;
 2328 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 2329             asId = p->pkt_header->address_space_id_dst;
 2330 #endif
 2331         }
 2332         rnaData->service_ip = *ip;
 2333         rnaData->service_port = port;
 2334 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 2335         rnaData->serviceAsId = asId;
 2336 #endif
 2337 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)
 2338         rnaData->carrierId = p->pkt_header->carrier_id;
 2339 #endif
 2340     }
 2341 
 2342     /* When a new flow was initialized, rnaData->search_state = 0 (SERVICE_ID_START) */
 2343     if (rnaData->search_state == SERVICE_ID_START)
 2344     {
 2345         rnaData->search_state = SERVICE_ID_PORT; // Also ensures this block to be executed once per flow
 2346         /* Get host tracker state. */
 2347 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)
 2348 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF) 
 2349         id_state = AppIdGetServiceIDState(ip, proto, port, AppIdServiceDetectionLevel(rnaData),
 2350                                           asId, cid);
 2351 #else
 2352         id_state = AppIdGetServiceIDState(ip, proto, port, AppIdServiceDetectionLevel(rnaData), cid);
 2353 #endif        
 2354 #else /* No carrier id support */
 2355 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 2356         id_state = AppIdGetServiceIDState(ip, proto, port, AppIdServiceDetectionLevel(rnaData),
 2357                                           asId);
 2358 #else
 2359         id_state = AppIdGetServiceIDState(ip, proto, port, AppIdServiceDetectionLevel(rnaData));
 2360 #endif
 2361 #endif
 2362         /* Create it if it doesn't exist yet. */
 2363         if (id_state == NULL)
 2364         {
 2365             /* New one is memset to 0, hence id_state->state = 0 (SERVICE_ID_NEW) */
 2366 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)
 2367 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 2368             if (!(id_state = AppIdAddServiceIDState(ip, proto, port, AppIdServiceDetectionLevel(rnaData),
 2369                                                     asId, cid)))
 2370 #else 
 2371             if (!(id_state = AppIdAddServiceIDState(ip, proto, port, AppIdServiceDetectionLevel(rnaData), cid)))
 2372 #endif
 2373 #else /* No carrierid support */
 2374 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 2375             if (!(id_state = AppIdAddServiceIDState(ip, proto, port, AppIdServiceDetectionLevel(rnaData),
 2376                                                     asId)))
 2377 #else
 2378             if (!(id_state = AppIdAddServiceIDState(ip, proto, port, AppIdServiceDetectionLevel(rnaData))))
 2379 #endif
 2380 #endif
 2381             {
 2382                 _dpd.errMsg("Discover service failed to create state");
 2383                 return SERVICE_ENOMEM;
 2384             }
 2385         }
 2386         /* No more searching if brute force already walked the list unsuccessfully. */
 2387         else if (id_state->state == SERVICE_ID_BRUTE_FORCE_FAILED)
 2388         {
 2389             if (app_id_debug_session_flag)
 2390                 _dpd.logMsg("AppIdDbg %s brute-force failed state, no service match\n", app_id_debug_session);
 2391             AppIdServiceFailService(rnaData, p, dir, NULL, APPID_SESSION_DATA_NONE, pConfig, id_state);
 2392             return SERVICE_NOMATCH;
 2393         }
 2394 
 2395         if (rnaData->serviceData == NULL)
 2396         {
 2397             /* If a valid service already exists in host tracker, give it a try. */
 2398             if ((id_state->svc != NULL) && (id_state->state == SERVICE_ID_VALID))
 2399             {
 2400                 rnaData->serviceData = id_state->svc;
 2401             }
 2402             /* If we've gotten to brute force, give next detector a try. */
 2403             else if ( id_state->state == SERVICE_ID_BRUTE_FORCE &&
 2404                       (sflist_count(rnaData->candidate_service_list) == 0) )
 2405             {
 2406                 if (app_id_debug_session_flag)
 2407                     _dpd.logMsg("AppIdDbg %s brute-force state\n", app_id_debug_session);
 2408                 rnaData->serviceData = AppIdGetServiceByBruteForce(proto, id_state->svc, pConfig);
 2409                 id_state->svc = rnaData->serviceData;
 2410                 bruteForceDone = true;
 2411                 if (!rnaData->serviceData)
 2412                     id_state->state = SERVICE_ID_BRUTE_FORCE_FAILED;
 2413             }
 2414         }
 2415     }
 2416 
 2417     args.data = p->payload;
 2418     args.size = p->payload_size;
 2419     args.dir = dir;
 2420     args.flowp = rnaData;
 2421     args.pkt = p;
 2422     args.pConfig = pConfig;
 2423     args.app_id_debug_session_flag = app_id_debug_session_flag;
 2424     args.app_id_debug_session = app_id_debug_session;
 2425 
 2426     /* If we already have a service to try, then try it out. */
 2427     if (rnaData->serviceData != NULL)
 2428     {
 2429         service = rnaData->serviceData;
 2430         args.userdata = service->userdata;
 2431         ret = service->validate(&args);
 2432         if (ret == SERVICE_NOT_COMPATIBLE)
 2433             rnaData->got_incompatible_services = 1;
 2434         rnaData->search_state = SERVICE_ID_PENDING;
 2435         if (app_id_debug_session_flag)
 2436             _dpd.logMsg("AppIdDbg %s %s returned %d\n", app_id_debug_session,
 2437                         service->name ? service->name:"UNKNOWN", ret);
 2438     }
 2439     /* Else, try to find detector(s) to use based on ports and patterns. */
 2440     else if (!bruteForceDone)
 2441     {
 2442         if (rnaData->candidate_service_list == NULL)
 2443         {
 2444             if (!(rnaData->candidate_service_list = malloc(sizeof(SF_LIST))))
 2445             {
 2446                 _dpd.errMsg("Could not allocate a candidate service list.");
 2447                 return SERVICE_ENOMEM;
 2448             }
 2449             sflist_init(rnaData->candidate_service_list);
 2450         }
 2451 
 2452         /* See if we've got more detector(s) to add to the candidate list. */
 2453         if ((rnaData->search_state == SERVICE_ID_PORT) ||
 2454             ((rnaData->search_state == SERVICE_ID_PATTERN) && (dir == APP_ID_FROM_RESPONDER)))
 2455         {
 2456             struct _SERVICE_MATCH *serviceList = NULL;
 2457             struct _SERVICE_MATCH *currentService = NULL;
 2458             const tRNAServiceElement *tmp = NULL; // Also used to remember last service in the loop
 2459             while ((tmp = AppIdGetNextService(p, dir, rnaData, pConfig, tmp, &serviceList, &currentService)))
 2460             {
 2461                 // Add to list if not already there
 2462                 service = sflist_first(rnaData->candidate_service_list);
 2463                 while (service && (service != tmp))
 2464                     service = sflist_next(rnaData->candidate_service_list);
 2465                 if (service == NULL)
 2466                     sflist_add_tail(rnaData->candidate_service_list, (void*)tmp);
 2467             }
 2468             if (serviceList)
 2469                 AppIdFreeServiceMatchList(serviceList);
 2470         }
 2471 
 2472         /* Run all of the detectors that we currently have. */
 2473         ret = SERVICE_INPROCESS;
 2474         node = sflist_first_node(rnaData->candidate_service_list);
 2475         service = NULL;
 2476         while (node != NULL)
 2477         {
 2478             int result;
 2479             SF_LNODE *node_tmp;
 2480 
 2481             service = (tRNAServiceElement*)SFLIST_NODE_TO_DATA(node);
 2482             args.userdata = service->userdata;
 2483             result = service->validate(&args);
 2484             if (result == SERVICE_NOT_COMPATIBLE)
 2485                 rnaData->got_incompatible_services = 1;
 2486             if (app_id_debug_session_flag)
 2487                 _dpd.logMsg("AppIdDbg %s %s returned %d\n", app_id_debug_session,
 2488                             service->name ? service->name:"UNKNOWN", result);
 2489 
 2490             node_tmp = node;
 2491             node = sflist_next_node(rnaData->candidate_service_list);
 2492             if (result == SERVICE_SUCCESS)
 2493             {
 2494                 ret = SERVICE_SUCCESS;
 2495                 rnaData->serviceData = service;
 2496                 sflist_free(rnaData->candidate_service_list);
 2497                 rnaData->candidate_service_list = NULL;
 2498                 break;    /* done */
 2499             }
 2500             else if (result != SERVICE_INPROCESS)    /* fail */
 2501             {
 2502                 sflist_remove_node(rnaData->candidate_service_list, node_tmp);
 2503             }
 2504         }
 2505 
 2506         /* If we tried everything and found nothing, then fail. */
 2507         if (ret != SERVICE_SUCCESS)
 2508         {
 2509             if (    (sflist_count(rnaData->candidate_service_list) == 0)
 2510                  && (rnaData->search_state == SERVICE_ID_PENDING) )
 2511             {
 2512                 if (!id_state)
 2513                 {    
 2514 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)
 2515 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 2516                     id_state = AppIdGetServiceIDState(ip, proto, port, AppIdServiceDetectionLevel(rnaData),
 2517                                                       asId, cid);
 2518 #else
 2519                     id_state = AppIdGetServiceIDState(ip, proto, port, AppIdServiceDetectionLevel(rnaData), cid);
 2520 #endif
 2521 #else /* No carrierid support */
 2522 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF) 
 2523                     id_state = AppIdGetServiceIDState(ip, proto, port, AppIdServiceDetectionLevel(rnaData),
 2524                                                       asId);
 2525 #else
 2526                     id_state = AppIdGetServiceIDState(ip, proto, port, AppIdServiceDetectionLevel(rnaData));
 2527 #endif
 2528 #endif
 2529                 }                    
 2530                 AppIdServiceFailService(rnaData, p, dir, NULL, APPID_SESSION_DATA_NONE, pConfig, id_state);
 2531                 appIdFailServiceDone = true;
 2532                 ret = SERVICE_NOMATCH;
 2533             }
 2534         }
 2535     }
 2536 
 2537     /* We have seen bidirectional exchange and have not identified any service */
 2538     if (!service && (dir == APP_ID_FROM_RESPONDER))
 2539     {
 2540         if (app_id_debug_session_flag)
 2541             _dpd.logMsg("AppIdDbg %s no RNA service detector\n", app_id_debug_session);
 2542         if (!appIdFailServiceDone)
 2543         {
 2544             if (!id_state)
 2545             {
 2546 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)
 2547 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 2548                 id_state = AppIdGetServiceIDState(ip, proto, port, AppIdServiceDetectionLevel(rnaData),
 2549                                                   asId, cid);
 2550 #else
 2551                 id_state = AppIdGetServiceIDState(ip, proto, port, AppIdServiceDetectionLevel(rnaData), cid);
 2552 #endif
 2553 #else /* No carrierid support */
 2554 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF) 
 2555                 id_state = AppIdGetServiceIDState(ip, proto, port, AppIdServiceDetectionLevel(rnaData),
 2556                                                   asId);
 2557 #else
 2558                 id_state = AppIdGetServiceIDState(ip, proto, port, AppIdServiceDetectionLevel(rnaData));
 2559 #endif
 2560 #endif
 2561             }
 2562             AppIdServiceFailService(rnaData, p, dir, NULL, APPID_SESSION_DATA_NONE, pConfig, id_state);
 2563             appIdFailServiceDone = true;
 2564             ret = SERVICE_NOMATCH;
 2565         }
 2566     }
 2567 
 2568     if ( ((appIdFailServiceDone && !bruteForceDone) || rnaData->got_incompatible_services) &&
 2569          (ret != SERVICE_INPROCESS) && (ret != SERVICE_SUCCESS) )
 2570     {
 2571         /* Handle failure exception cases in states. */
 2572         sfaddr_t *tmp_ip;
 2573         if (dir == APP_ID_FROM_RESPONDER)
 2574             tmp_ip = GET_DST_IP(p);
 2575         else
 2576             tmp_ip = GET_SRC_IP(p);
 2577 
 2578         if (rnaData->got_incompatible_services)
 2579         {
 2580             if (!id_state)
 2581             {
 2582 #if !defined(SFLINUX) && defined(DAQ_CAPA_CARRIER_ID)
 2583 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF)
 2584                 id_state = AppIdGetServiceIDState(ip, proto, port, AppIdServiceDetectionLevel(rnaData),
 2585                                                   asId, cid);
 2586 #else
 2587                 id_state = AppIdGetServiceIDState(ip, proto, port, AppIdServiceDetectionLevel(rnaData), cid);
 2588 #endif
 2589 #else /* No carrier id support */
 2590 #if !defined(SFLINUX) && defined(DAQ_CAPA_VRF) 
 2591                 id_state = AppIdGetServiceIDState(ip, proto, port, AppIdServiceDetectionLevel(rnaData),
 2592                                                   asId);
 2593 #else
 2594                 id_state = AppIdGetServiceIDState(ip, proto, port, AppIdServiceDetectionLevel(rnaData));
 2595 #endif
 2596 #endif
 2597             }
 2598             if (id_state && id_state->invalid_client_count < STATE_ID_INVALID_CLIENT_THRESHOLD)
 2599             {
 2600                 if (sfip_fast_equals_raw(&id_state->last_invalid_client, tmp_ip))
 2601                     id_state->invalid_client_count++;
 2602                 else
 2603                 {
 2604                     id_state->invalid_client_count += 3;
 2605                     id_state->last_invalid_client = *tmp_ip;
 2606                 }
 2607             }
 2608         }
 2609 
 2610         HandleFailure(rnaData, id_state, tmp_ip, p);
 2611     }
 2612     return ret;
 2613 }
 2614 
 2615 static void *service_flowdata_get(tAppIdData *flow, unsigned service_id)
 2616 {
 2617     return AppIdFlowdataGet(flow, service_id);
 2618 }
 2619 
 2620 static int service_flowdata_add(tAppIdData *flow, void *data, unsigned service_id, AppIdFreeFCN fcn)
 2621 {
 2622     return AppIdFlowdataAdd(flow, data, service_id, fcn);
 2623 }
 2624 
 2625 /** GUS: 2006 09 28 10:10:54
 2626  *  A simple function that prints the
 2627  *  ports that have decoders registered.
 2628  */
 2629 static void dumpServices(FILE *stream, SF_LIST *const *parray)
 2630 {
 2631     int i,n = 0;
 2632     for(i = 0; i < RNA_SERVICE_MAX_PORT; i++)
 2633     {
 2634         if (parray[i] && (sflist_count(parray[i]) != 0))
 2635         {
 2636             if( n !=  0)
 2637             {
 2638                 fprintf(stream," ");
 2639             }
 2640             n++;
 2641             fprintf(stream,"%d",i);
 2642         }
 2643     }
 2644 }
 2645 
 2646 void dumpPorts(FILE *stream, const tAppIdConfig *pConfig)
 2647 {
 2648     fprintf(stream,"(tcp ");
 2649     dumpServices(stream,pConfig->serviceConfig.tcp_services);
 2650     fprintf(stream,") \n");
 2651     fprintf(stream,"(udp ");
 2652     dumpServices(stream,pConfig->serviceConfig.udp_services);
 2653     fprintf(stream,") \n");
 2654 }
 2655 
 2656 static void AppIdServiceAddMisc(tAppIdData* flow, tAppId miscId)
 2657 {
 2658     if(flow != NULL)
 2659         flow->miscAppId = miscId;
 2660 }