The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/ngatm/netnatm/sig/sig_verify.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 2001-2003
    3  *      Fraunhofer Institute for Open Communication Systems (FhG Fokus).
    4  *      All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25  * SUCH DAMAGE.
   26  *
   27  * Author: Hartmut Brandt <harti@freebsd.org>
   28  *
   29  * $Begemot: libunimsg/netnatm/sig/sig_verify.c,v 1.19 2004/07/08 08:22:23 brandt Exp $
   30  *
   31  * Message verification with explicit action indicators.
   32  */
   33 
   34 #include <netnatm/unimsg.h>
   35 #include <netnatm/saal/sscfudef.h>
   36 #include <netnatm/msg/unistruct.h>
   37 #include <netnatm/msg/unimsglib.h>
   38 #include <netnatm/sig/uni.h>
   39 
   40 #include <netnatm/sig/unipriv.h>
   41 #include <netnatm/sig/unimkmsg.h>
   42 
   43 void
   44 uni_mandate_ie(struct uni *uni, enum uni_ietype ie)
   45 {
   46         struct uni_ierr *e;
   47 
   48         FOREACH_ERR(e, uni)
   49                 if (e->ie == ie) {
   50                         e->man = 1;
   51                         return;
   52                 }
   53         if (UNI_SAVE_IERR(&uni->cx, ie, UNI_IEACT_DEFAULT, UNI_IERR_MIS))
   54                 uni->cx.err[uni->cx.errcnt - 1].man = 1;
   55 }
   56 
   57 /*
   58  * This special handling is required for ADD PARTY, PARTY ALERTING and
   59  * ADD PARTY ACKNOWLEDGE by Q.2971 9.5.3.2.1.
   60  * It means, that the EPREF should be handled as mandatory only if
   61  * no other IEs have explicit action indicators.
   62  */
   63 void
   64 uni_mandate_epref(struct uni *uni, struct uni_ie_epref *epref)
   65 {
   66         struct uni_ierr *e;
   67         int maxact;
   68 
   69         if (!IE_ISPRESENT(*epref)) {
   70                 /*
   71                  * 9.5.3.2.1 -- missing endpoint reference
   72                  */
   73 
   74                 /*
   75                  * a) if any unrecognized or IE with error has a CLEAR
   76                  *    action indicator, this takes precedence.
   77                  * b) if any unrecognized or IE with error has a
   78                  *    discard message and report action indicator, this takes
   79                  *    precedence.
   80                  * c) if any unrecognized or IE with error has a
   81                  *    discard message action indicator, this takes
   82                  *    precedence.
   83                  *
   84                  * In any of these cases we must remove the EPREF IE
   85                  * if it has CLEAR, otherwise the CLEAR would take over.
   86                  */
   87                 maxact = -1;
   88                 FOREACH_ERR(e, uni) {
   89                         if (e->ie == UNI_IE_EPREF)
   90                                 continue;
   91                         if (e->act == UNI_IEACT_CLEAR)
   92                                 maxact = UNI_IEACT_CLEAR;
   93                         else if (e->act == UNI_IEACT_MSG_REPORT) {
   94                                 if (maxact == -1 && maxact != UNI_IEACT_CLEAR)
   95                                         maxact = UNI_IEACT_MSG_REPORT;
   96                         } else if (e->act == UNI_IEACT_MSG_IGNORE) {
   97                                 if (maxact == -1)
   98                                         maxact = UNI_IEACT_MSG_IGNORE;
   99                         }
  100                 }
  101 
  102                 if (maxact != -1) {
  103                         /* ok, second pass to remove UNI_IE_EPREF */
  104                         FOREACH_ERR(e, uni)
  105                                 if (e->ie == UNI_IE_EPREF) {
  106                                         memmove(e, e + 1,
  107                                             (uni->cx.errcnt - (e - uni->cx.err)
  108                                             - 1) * sizeof(uni->cx.err[0]));
  109                                         uni->cx.errcnt--;
  110                                         break;
  111                                 }
  112                         return;
  113 
  114                 }
  115 
  116                 /*
  117                  * d) if nothing of the above, the IE is mandatory
  118                  */
  119                 uni_mandate_ie(uni, UNI_IE_EPREF);
  120                 return;
  121                 
  122         }
  123         if (IE_ISGOOD(*epref))
  124                 return;
  125 
  126         /*
  127          * It has an error obviously
  128          * 9.5.3.2.2
  129          *
  130          * It turns out, that Q.2931 handling just does the right thing
  131          * if we don't mandate the IE.
  132          */
  133         return;
  134 }
  135 
  136 /*
  137  * Look, what to do with this message. We assume, that the message itself is
  138  * recognized.
  139  *
  140  * This is rather complicated. We must use the information provided in the
  141  * fields of the context, because IEs with length errors may not be set
  142  * altogether.
  143  */
  144 enum verify
  145 uni_verify(struct uni *uni, enum uni_msgact msgact)
  146 {
  147         struct uni_ierr *e1;
  148 
  149         if (uni->debug[UNI_FAC_VERIFY] >= 2) {
  150                 FOREACH_ERR(e1, uni) {
  151                         VERBOSE(uni, UNI_FAC_VERIFY, 2, "ie=%02x err=%u man=%d"
  152                             " act=%u", e1->ie, e1->err, e1->man, e1->act);
  153                 }
  154         }
  155 
  156         /*
  157          * Look for missing mandatory IEs. The action indicator is ignored
  158          * according to 5.6.7.1. If IEs are missing the action is to
  159          * ignore the message and report status for all messages except
  160          * RELEASE, RELEASE_COMPLETE and SETUP. Because we must differentiate
  161          * this RAI from other RAIs in this case, use another return code.
  162          * Note, that mandatory IEs with errors are not handled here.
  163          */
  164         FOREACH_ERR(e1, uni) {
  165                 if (e1->err == UNI_IERR_MIS) {
  166                         MK_IE_CAUSE(uni->cause, UNI_CAUSE_LOC_USER,
  167                             UNI_CAUSE_MANDAT);
  168                         VERBOSE(uni, UNI_FAC_VERIFY, 1, "RAIM");
  169                         return (VFY_RAIM);
  170                 }
  171         }
  172 
  173         /*
  174          * When any IE with error specifies a CLR action indicator, this
  175          * takes precedence obviously. There are two cases here:
  176          * unrecognized IEs and IEs with error. So we look through the
  177          * error array twice and send only one STATUS. Unrecognized will
  178          * take precedence.
  179          *
  180          * 5.7.2a)
  181          */
  182         FOREACH_ERR(e1, uni) {
  183                 if (e1->act == UNI_IEACT_CLEAR && e1->err == UNI_IERR_UNK) {
  184                         MK_IE_CAUSE(uni->cause, UNI_CAUSE_LOC_USER,
  185                             UNI_CAUSE_IE_NIMPL);
  186                         VERBOSE(uni, UNI_FAC_VERIFY, 1, "CLR1");
  187                         return (VFY_CLR);
  188                 }
  189         }
  190 
  191         FOREACH_ERR(e1, uni) {
  192                 if (e1->act == UNI_IEACT_CLEAR &&
  193                    (e1->err == UNI_IERR_LEN || e1->err == UNI_IERR_BAD ||
  194                     e1->err == UNI_IERR_ACC)) {
  195                         MK_IE_CAUSE(uni->cause, UNI_CAUSE_LOC_USER,
  196                             UNI_CAUSE_IE_INV);
  197                         VERBOSE(uni, UNI_FAC_VERIFY, 1, "CLR2");
  198                         return (VFY_CLR);
  199                 }
  200         }
  201 
  202         /*
  203          * Now check, whether anybody wants to explicitly ignore the message
  204          * and report status.
  205          *
  206          * 5.7.2a)
  207          */
  208         FOREACH_ERR(e1, uni) {
  209                 if (e1->act == UNI_IEACT_MSG_REPORT && e1->err == UNI_IERR_UNK) {
  210                         MK_IE_CAUSE(uni->cause, UNI_CAUSE_LOC_USER,
  211                             UNI_CAUSE_IE_NIMPL);
  212                         VERBOSE(uni, UNI_FAC_VERIFY, 1, "RAI");
  213                         return (VFY_RAI);
  214                 }
  215         }
  216 
  217         FOREACH_ERR(e1, uni) {
  218                 if (e1->act == UNI_IEACT_MSG_REPORT &&
  219                    (e1->err == UNI_IERR_LEN || e1->err == UNI_IERR_BAD ||
  220                     e1->err == UNI_IERR_ACC)) {
  221                         MK_IE_CAUSE(uni->cause, UNI_CAUSE_LOC_USER,
  222                             UNI_CAUSE_IE_INV);
  223                         VERBOSE(uni, UNI_FAC_VERIFY, 1, "RAI");
  224                         return (VFY_RAI);
  225                 }
  226         }
  227 
  228         /*
  229          * Now look whether some IE wants to explicitely ignore the message
  230          * without any report.
  231          */
  232         FOREACH_ERR(e1, uni) {
  233                 if (e1->act == UNI_IEACT_MSG_IGNORE) {
  234                         VERBOSE(uni, UNI_FAC_VERIFY, 1, "I1");
  235                         return (VFY_I);
  236                 }
  237         }
  238 
  239         /*
  240          * At this point we have left only
  241          *  mandatory and non-mandatory IEs with error that want the IE to be
  242          *  ignored or ignored with report or defaulted.
  243          * Because a mandatory IE with errors lead to
  244          * the message beeing ignored, we make this of higher
  245          * precedence, than the rest.
  246          */
  247         FOREACH_ERR(e1, uni) {
  248                 if (e1->man) {
  249                         MK_IE_CAUSE(uni->cause, UNI_CAUSE_LOC_USER,
  250                             UNI_CAUSE_MANDAT);
  251                         VERBOSE(uni, UNI_FAC_VERIFY, 1, "RAI");
  252                         return (VFY_RAI);
  253                 }
  254         }
  255 
  256         /*
  257          * Now look for ignoring the IE and reporting. This takes precedence
  258          * over simply ignoring it. We also collect defaulted (non-mandatory)
  259          * IEs.
  260          *
  261          * 5.7.2d) and 5.6.8.1
  262          */
  263         FOREACH_ERR(e1, uni) {
  264                 if ((e1->act == UNI_IEACT_DEFAULT ||
  265                      e1->act == UNI_IEACT_REPORT)
  266                     && e1->err != UNI_IERR_UNK) {
  267                         MK_IE_CAUSE(uni->cause, UNI_CAUSE_LOC_USER,
  268                             UNI_CAUSE_IE_INV);
  269                         VERBOSE(uni, UNI_FAC_VERIFY, 1, "RAP");
  270                         return (VFY_RAP);
  271                 }
  272         }
  273 
  274         FOREACH_ERR(e1, uni) {
  275                 if ((e1->act == UNI_IEACT_DEFAULT ||
  276                      e1->act == UNI_IEACT_REPORT)
  277                     && e1->err == UNI_IERR_UNK) {
  278                         MK_IE_CAUSE(uni->cause, UNI_CAUSE_LOC_USER,
  279                             UNI_CAUSE_IE_NIMPL);
  280                         VERBOSE(uni, UNI_FAC_VERIFY, 1, "RAPU");
  281                         return (VFY_RAPU);
  282                 }
  283         }
  284 
  285         /*
  286          * This leaves us with IEs, that want to be ignored. Among these may
  287          * be mandatory IEs. If we have an mandatory IEs here in the error
  288          * array, then the message wil not contain enough information and
  289          * must be handled according to 5.8 as either in 5.6.7.1 (this
  290          * means, that mandatory IEs cannot really be ignored) or 5.7.1.
  291          */
  292         FOREACH_ERR(e1, uni) {
  293                 if (e1->man) {
  294                         MK_IE_CAUSE(uni->cause, UNI_CAUSE_LOC_USER,
  295                             UNI_CAUSE_MANDAT);
  296                         if (msgact == UNI_MSGACT_CLEAR) {
  297                                 VERBOSE(uni, UNI_FAC_VERIFY, 1, "CLR3");
  298                                 return (VFY_CLR);
  299                         }
  300                         if (msgact == UNI_MSGACT_IGNORE) {
  301                                 VERBOSE(uni, UNI_FAC_VERIFY, 1, "I2");
  302                                 return (VFY_I);
  303                         }
  304                         VERBOSE(uni, UNI_FAC_VERIFY, 1, "RAI");
  305                         return (VFY_RAI);
  306                 }
  307         }
  308 
  309         /*
  310          * Now only non-mandatory IEs are left, that want to be explicitely
  311          * ignored.
  312          */
  313         if (uni->cx.errcnt != 0)
  314                 MK_IE_CAUSE(uni->cause, UNI_CAUSE_LOC_USER,
  315                     UNI_CAUSE_IE_INV);
  316 
  317         VERBOSE(uni, UNI_FAC_VERIFY, 1, "OK");
  318         return (VFY_OK);
  319 }
  320 
  321 /*
  322  * Collect the IE identifiers for some of the known cause codes.
  323  */
  324 void
  325 uni_vfy_collect_ies(struct uni *uni)
  326 {
  327         struct uni_ierr *e;
  328 
  329 #define STUFF_IE(IE)                                            \
  330         uni->cause.u.ie.ie[uni->cause.u.ie.len++] = (IE);       \
  331         if (uni->cause.u.ie.len == UNI_CAUSE_IE_N)              \
  332                 break;
  333 
  334         uni->cause.u.ie.len = 0;
  335         if (uni->cause.cause == UNI_CAUSE_MANDAT) {
  336                 FOREACH_ERR(e, uni) {
  337                         if (e->err == UNI_IERR_MIS || e->man != 0) {
  338                                 STUFF_IE(e->ie);
  339                         }
  340                 }
  341 
  342         } else if (uni->cause.cause == UNI_CAUSE_IE_NIMPL) {
  343                 FOREACH_ERR(e, uni) {
  344                         if (e->err == UNI_IERR_UNK) {
  345                                 STUFF_IE(e->ie);
  346                         }
  347                 }
  348 
  349         } else if (uni->cause.cause == UNI_CAUSE_IE_INV) {
  350                 FOREACH_ERR(e, uni) {
  351                         if (e->err == UNI_IERR_LEN ||
  352                             e->err == UNI_IERR_BAD ||
  353                             e->err == UNI_IERR_ACC) {
  354                                 STUFF_IE(e->ie);
  355                         }
  356                 }
  357         } else
  358                 return;
  359 
  360         if (uni->cause.u.ie.len != 0)
  361                 uni->cause.h.present |= UNI_CAUSE_IE_P;
  362 }
  363 
  364 
  365 void
  366 uni_respond_status_verify(struct uni *uni, struct uni_cref *cref,
  367     enum uni_callstate cs, struct uni_ie_epref *epref,
  368     enum uni_epstate ps)
  369 {
  370         struct uni_all *resp;
  371 
  372         if ((resp = UNI_ALLOC()) == NULL)
  373                 return;
  374 
  375         uni_vfy_collect_ies(uni);
  376 
  377         MK_MSG_RESP(resp, UNI_STATUS, cref);
  378         MK_IE_CALLSTATE(resp->u.status.callstate, cs);
  379         resp->u.status.cause = uni->cause;
  380         if (epref && IE_ISGOOD(*epref)) {
  381                 MK_IE_EPREF(resp->u.status.epref, epref->epref, !epref->flag);
  382                 MK_IE_EPSTATE(resp->u.status.epstate, ps);
  383         }
  384 
  385         uni_send_output(resp, uni);
  386 
  387         UNI_FREE(resp);
  388 }
  389 
  390 /*
  391  * Handling of Q.2971 9.5.8.1:
  392  */
  393 void
  394 uni_vfy_remove_unknown(struct uni *uni)
  395 {
  396         struct uni_ierr *e1, *e0;
  397         int flag = 0;
  398 
  399         FOREACH_ERR(e1, uni) {
  400                 if (e1->err == UNI_IERR_UNK) {
  401                         if (e1->act == UNI_IEACT_CLEAR ||
  402                             e1->act == UNI_IEACT_MSG_IGNORE ||
  403                             e1->act == UNI_IEACT_MSG_REPORT)
  404                                 return;
  405                         if (e1->act == UNI_IEACT_REPORT ||
  406                             e1->act == UNI_IEACT_DEFAULT)
  407                                 flag = 1;
  408                 }
  409         }
  410         if (flag)
  411                 return;
  412         e0 = e1 = uni->cx.err;
  413         while (e1 < uni->cx.err + uni->cx.errcnt) {
  414                 if (e1->err != UNI_IERR_UNK) {
  415                         if (e0 != e1)
  416                                 *e0 = *e1;
  417                         e0++;
  418                 }
  419                 e1++;
  420         }
  421         uni->cx.errcnt = e0 - uni->cx.err;
  422 }
  423 
  424 /*
  425  * Handling for ADD_PARTY_REJ and DROP_PARTY_ACK with bad cause
  426  */
  427 void
  428 uni_vfy_remove_cause(struct uni *uni)
  429 {
  430         struct uni_ierr *e1, *e0;
  431 
  432         e0 = e1 = uni->cx.err;
  433         while (e1 < uni->cx.err + uni->cx.errcnt) {
  434                 if (e1->ie != UNI_IE_CAUSE) {
  435                         if (e0 != e1)
  436                                 *e0 = *e1;
  437                         e0++;
  438                 }
  439                 e1++;
  440         }
  441         uni->cx.errcnt = e0 - uni->cx.err;
  442 }

Cache object: 388ba2a9404f8863eca96b715055eeb5


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.