|
|
1.1 ! root 1: /* rosapapdu.c - ROPM: interpret APDU */ ! 2: ! 3: #ifndef lint ! 4: static char *rcsid = "$Header: /f/osi/rosap/RCS/rosapapdu.c,v 7.1 90/07/01 21:05:58 mrose Exp $"; ! 5: #endif ! 6: ! 7: /* ! 8: * $Header: /f/osi/rosap/RCS/rosapapdu.c,v 7.1 90/07/01 21:05:58 mrose Exp $ ! 9: * ! 10: * Based on an TCP-based implementation by George Michaelson of University ! 11: * College London. ! 12: * ! 13: * ! 14: * $Log: rosapapdu.c,v $ ! 15: * Revision 7.1 90/07/01 21:05:58 mrose ! 16: * pepsy ! 17: * ! 18: * Revision 6.0 89/03/18 23:42:22 mrose ! 19: * Release 5.0 ! 20: * ! 21: */ ! 22: ! 23: /* ! 24: * NOTICE ! 25: * ! 26: * Acquisition, use, and distribution of this module and related ! 27: * materials are subject to the restrictions of a license agreement. ! 28: * Consult the Preface in the User's Manual for the full terms of ! 29: * this agreement. ! 30: * ! 31: */ ! 32: ! 33: ! 34: /* LINTLIBRARY */ ! 35: ! 36: #include <stdio.h> ! 37: #include <signal.h> ! 38: #include "ROS-types.h" ! 39: #include "ropkt.h" ! 40: #ifdef DEBUG ! 41: #include "tailor.h" ! 42: #endif ! 43: ! 44: static int prob2num (); ! 45: ! 46: /* */ ! 47: ! 48: int acb2osdu (acb, invokeID, pe, roi) ! 49: register struct assocblk *acb; ! 50: int *invokeID; ! 51: register PE pe; ! 52: register struct RoSAPindication *roi; ! 53: { ! 54: struct type_ROS_ROSEapdus *papdu; ! 55: struct type_ROS_OPDU *popdu; ! 56: int rosap_type; ! 57: int result; ! 58: ! 59: rosap_type = APDU_UNKNOWN; ! 60: if (((acb -> acb_flags & ACB_ACS) ! 61: ? decode_ROS_ROSEapdus (pe, 1, NULLIP, NULLVP, &papdu) ! 62: : decode_ROS_OPDU (pe, 1, NULLIP, NULLVP, &popdu)) ! 63: == NOTOK) { ! 64: (void) rosapreject (acb, roi, rosap_type != APDU_UNKNOWN ! 65: ? ROS_GP_MISTYPED : ROS_GP_UNRECOG, NULLCP, "%s", ! 66: PY_pepy); ! 67: pe_free (pe); ! 68: return NOTOK; ! 69: } ! 70: ! 71: #ifdef DEBUG ! 72: if (rosap_log -> ll_events & LLOG_PDUS) ! 73: if (acb -> acb_flags & ACB_ACS) ! 74: pvpdu (rosap_log, print_ROS_ROSEapdus_P, pe, "ROSEapdus", 1); ! 75: else ! 76: pvpdu (rosap_log, print_ROS_OPDU_P, pe, "OPDU", 1); ! 77: #endif ! 78: ! 79: /* p = pe_expunge (pe, rosap_data); */ ! 80: ! 81: if ((acb -> acb_flags & ACB_ACS)) { ! 82: result = apdu_proc (acb -> acb_fd, papdu, roi, acb, invokeID); ! 83: if (papdu) ! 84: free_ROS_ROSEapdus (papdu); ! 85: } ! 86: else { ! 87: result = opdu_proc (acb -> acb_fd, popdu, roi, acb, invokeID); ! 88: if (popdu) ! 89: free_ROS_OPDU (popdu); ! 90: } ! 91: ! 92: return (result); ! 93: } ! 94: ! 95: /* */ ! 96: ! 97: /* ! 98: * Process an APDU. This seperates out all the differences between ! 99: * the two cases. Copy all the fields of the structure into the appropriate ! 100: * RoSAPindication structure ! 101: */ ! 102: ! 103: static int apdu_proc (sd, papdu, roi, acb, invokeID) ! 104: int sd; ! 105: struct type_ROS_ROSEapdus *papdu; ! 106: register struct RoSAPindication *roi; ! 107: register struct assocblk *acb; ! 108: int *invokeID; ! 109: { ! 110: int rosap_id; ! 111: ! 112: switch (papdu -> offset) { ! 113: case type_ROS_ROSEapdus_roiv__apdu: ! 114: roi -> roi_type = ROI_INVOKE; ! 115: { ! 116: register struct RoSAPinvoke *rox = &roi -> roi_invoke; ! 117: register struct type_ROS_ROIVapdu *piv = papdu->un.roiv__apdu; ! 118: ! 119: /* if (papdu.un.roiv__apdu->invokeID) */ ! 120: rosap_id = rox -> rox_id = piv -> invokeID -> parm; ! 121: if (!(rox -> rox_nolinked = ! 122: !(piv -> optionals & opt_ROS_ROIVapdu_linked__ID))) ! 123: rox -> rox_linkid = piv -> linked__ID; ! 124: rox -> rox_op = piv->operation__value -> parm; ! 125: rox -> rox_args = piv -> argument; ! 126: } ! 127: break; ! 128: ! 129: case type_ROS_ROSEapdus_rors__apdu: ! 130: roi -> roi_type = ROI_RESULT; ! 131: { ! 132: register struct RoSAPresult *ror = &roi -> roi_result; ! 133: register struct type_ROS_RORSapdu *pres = papdu->un.rors__apdu; ! 134: ! 135: rosap_id = ror -> ror_id = pres -> invokeID -> parm; ! 136: if (pres -> element_ROS_0) { ! 137: ror -> ror_op = pres -> element_ROS_0 -> operation__value -> parm; ! 138: ror -> ror_result = pres -> element_ROS_0 -> result; ! 139: }/* else what : undefined? */ ! 140: } ! 141: break; ! 142: ! 143: case type_ROS_ROSEapdus_roer__apdu: ! 144: roi -> roi_type = ROI_ERROR; ! 145: { ! 146: register struct RoSAPerror *roe = &roi -> roi_error; ! 147: register struct type_ROS_ROERapdu *perr = papdu->un.roer__apdu; ! 148: ! 149: rosap_id = roe -> roe_id = perr -> invokeID->parm; ! 150: roe -> roe_error = perr -> error__value -> parm; ! 151: roe -> roe_param = perr -> parameter; ! 152: } ! 153: break; ! 154: ! 155: case type_ROS_ROSEapdus_rorj__apdu: ! 156: roi -> roi_type = ROI_UREJECT; ! 157: { ! 158: register struct RoSAPureject *rou = &roi -> roi_ureject; ! 159: register struct type_ROS_RORJapdu *prej = papdu->un.rorj__apdu; ! 160: ! 161: if (prej -> invokeID -> offset == choice_ROS_0_2) ! 162: rou -> rou_noid = 1; ! 163: else { ! 164: rosap_id = rou -> rou_id = ! 165: prej -> invokeID -> un.choice_ROS_1 -> parm; ! 166: rou -> rou_noid = 0; ! 167: } ! 168: ! 169: if ((rou -> rou_reason = prob2num(prej -> problem)) == NOTOK) { ! 170: rou->rou_reason = ROS_PROTOCOL; /* ??? */ ! 171: } ! 172: } ! 173: break; ! 174: } ! 175: ! 176: if (invokeID ! 177: && (papdu -> offset == type_ROS_ROSEapdus_roiv__apdu ! 178: || (papdu -> offset == type_ROS_ROSEapdus_rorj__apdu ! 179: && papdu -> un.rorj__apdu -> invokeID -> offset ! 180: == choice_ROS_0_2) ! 181: || *invokeID != rosap_id) ! 182: && acb -> acb_rosindication) { ! 183: (*acb -> acb_rosindication) (sd = acb -> acb_fd, roi); ! 184: ! 185: if (findacblk (sd) != acb)/* still not perfect! */ ! 186: return rosaplose (roi, ROS_DONE, NULLCP, NULLCP); ! 187: return OK; ! 188: } ! 189: ! 190: return DONE; ! 191: } ! 192: ! 193: /* */ ! 194: ! 195: /* ! 196: * Process an OPDU. A seperate function is used for this type of PDU to ! 197: * simpilfy matters. What is an OPDU - an Old PDU ?? ! 198: */ ! 199: ! 200: static int opdu_proc (sd, popdu, roi, acb, invokeID) ! 201: int sd; ! 202: struct type_ROS_OPDU *popdu; ! 203: register struct RoSAPindication *roi; ! 204: register struct assocblk *acb; ! 205: int *invokeID; ! 206: { ! 207: int rosap_id; ! 208: ! 209: switch (popdu -> offset) { ! 210: case type_ROS_OPDU_1: ! 211: roi -> roi_type = ROI_INVOKE; ! 212: { ! 213: register struct RoSAPinvoke *rox = &roi -> roi_invoke; ! 214: register struct type_ROS_Invoke *piv = popdu->un.choice_ROS_8; ! 215: ! 216: rosap_id = rox -> rox_id = piv -> invokeID; ! 217: rox -> rox_op = piv -> element_ROS_2 -> parm; ! 218: rox -> rox_args = piv -> argument; ! 219: } ! 220: break; ! 221: ! 222: case type_ROS_OPDU_2: ! 223: roi -> roi_type = ROI_RESULT; ! 224: { ! 225: register struct RoSAPresult *ror = &roi -> roi_result; ! 226: register struct type_ROS_ReturnResult *piv ! 227: = popdu -> un.choice_ROS_9; ! 228: ! 229: rosap_id = ror -> ror_id = piv -> invokeID -> parm; ! 230: /* ror -> ror_op = ?? - can't do this ! 231: * not fixing this might break programs - time to fix them ! 232: */ ! 233: ror -> ror_result = piv -> result; ! 234: } ! 235: break; ! 236: ! 237: case type_ROS_OPDU_3: ! 238: roi -> roi_type = ROI_ERROR; ! 239: { ! 240: register struct RoSAPerror *roe = &roi -> roi_error; ! 241: register struct type_ROS_ReturnError *per ! 242: = popdu -> un.choice_ROS_10; ! 243: ! 244: rosap_id = roe -> roe_id = per -> invokeID;; ! 245: roe -> roe_error = per -> element_ROS_3 -> parm; ! 246: roe -> roe_param = per -> parameter; ! 247: } ! 248: break; ! 249: ! 250: case type_ROS_OPDU_4: ! 251: roi -> roi_type = ROI_UREJECT; ! 252: { ! 253: register struct RoSAPureject *rou = &roi -> roi_ureject; ! 254: register struct type_ROS_Reject *prj = popdu->un.choice_ROS_11; ! 255: ! 256: if (prj -> invokeID -> offset == choice_ROS_0_2) ! 257: rou -> rou_noid = 1; ! 258: else { ! 259: rosap_id = rou -> rou_id = prj -> invokeID -> un.choice_ROS_1 -> parm; ! 260: rou -> rou_noid = 0; ! 261: } ! 262: ! 263: if ((rou -> rou_reason = prob2num(prj -> problem)) == NOTOK) { ! 264: rou -> rou_reason = ROS_PROTOCOL; /* ??? */ ! 265: } ! 266: ! 267: } ! 268: break; ! 269: } ! 270: ! 271: if (invokeID ! 272: && (popdu -> offset == type_ROS_OPDU_1 ! 273: || (popdu -> offset == type_ROS_OPDU_4 ! 274: && popdu -> un.choice_ROS_11 -> invokeID -> offset ! 275: == choice_ROS_0_2) ! 276: || *invokeID != rosap_id) ! 277: && acb -> acb_rosindication) { ! 278: (*acb -> acb_rosindication) (sd = acb -> acb_fd, roi); ! 279: ! 280: if (findacblk (sd) != acb)/* still not perfect! */ ! 281: return rosaplose (roi, ROS_DONE, NULLCP, NULLCP); ! 282: return OK; ! 283: } ! 284: ! 285: return DONE; ! 286: } ! 287: ! 288: /* */ ! 289: ! 290: static int Gprob[] = { ROS_GP_UNRECOG, ROS_GP_MISTYPED, ROS_GP_STRUCT }; ! 291: static int Iprob[] = { ROS_IP_DUP, ROS_IP_UNRECOG, ROS_IP_MISTYPED, ! 292: ROS_IP_LIMIT, ROS_IP_RELEASE, ROS_IP_UNLINKED, ! 293: ROS_IP_LINKED, ROS_IP_CHILD }; ! 294: static int RRprob[] = { ROS_RRP_UNRECOG, ROS_RRP_UNEXP, ROS_RRP_MISTYPED }; ! 295: static int REprob[] = { ROS_REP_UNRECOG, ROS_REP_UNEXP, ROS_REP_RECERR, ! 296: ROS_REP_UNEXPERR, ROS_REP_MISTYPED }; ! 297: /* computes the Number of entries in an array a */ ! 298: #define NENTRIES(a) (sizeof (a)/sizeof (a[0])) ! 299: ! 300: /* return the ISODE code from the numbers passed in the data or NOTOK if ! 301: * it finds an illegal value ! 302: */ ! 303: static int prob2num (prob) ! 304: register struct choice_ROS_3 *prob; ! 305: { ! 306: register int num; ! 307: ! 308: switch (prob -> offset) { ! 309: case choice_ROS_3_1: ! 310: if ((num = prob -> un.choice_ROS_4 -> parm) < 0 ! 311: || num >= NENTRIES(Gprob)) ! 312: goto out; ! 313: num = Gprob[num]; ! 314: break; ! 315: ! 316: case choice_ROS_3_2: ! 317: if ((num = prob -> un.choice_ROS_5 -> parm) < 0 ! 318: || num >= NENTRIES(Iprob)) ! 319: goto out; ! 320: num = Iprob[num]; ! 321: break; ! 322: ! 323: case choice_ROS_3_3: ! 324: if ((num = prob -> un.choice_ROS_6 -> parm) < 0 ! 325: || num >= NENTRIES(RRprob)) ! 326: goto out; ! 327: num = RRprob[num]; ! 328: break; ! 329: ! 330: ! 331: case choice_ROS_3_4: ! 332: if ((num = prob -> un.choice_ROS_7 -> parm) < 0 ! 333: || num >= NENTRIES(REprob)) ! 334: goto out; ! 335: num = REprob[num]; ! 336: break; ! 337: ! 338: default: ! 339: out: ; ! 340: return ROS_PROTOCOL; /* What else can we say ?*/ ! 341: } ! 342: ! 343: return (num); ! 344: ! 345: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.