ex_rev() { struct item *p; p = fetch1(); revk(p->rank-1); }
ex_gdu() { struct item *p; p = fetch1(); gd0(p->rank-1, gdu); }
/* the primitive function "execute" (uptack jot) */ void ex_execute() { struct item* p; int i, dim0, dim1; char* b; Context* thisContext; p = fetch1(); if (p->rank > 2) error(ERR_rank, ""); if (p->itemType != CH) error(ERR_domain, "not a literal value"); /*get out if nothing to do, apr 2-23-77 */ if (p->size == 0) return; b = (char*)p->datap; dim0 = p->rank < 2 ? 1 : p->dim[0]; dim1 = p->rank < 2 ? p->size : p->dim[1]; thisContext = (Context*)alloc(sizeof(Context)); thisContext->prev = gsip; /* setup new context */ thisContext->text = (char*)alloc(dim1 + 1); thisContext->Mode = exec; thisContext->sp = sp; thisContext->suspended = 0; gsip = thisContext; for (i = 0; i < dim0; i++) { copy(CH, b, gsip->text, dim1); gsip->text[dim1] = '\n'; compile_new(1); if (gsip->pcode != 0) { gsip->ptr = gsip->pcode; gsip->sp = sp; execute(); aplfree((int*)gsip->pcode); if (gsip->sp == sp) ex_nilret(); } else { gsip = thisContext->prev; /* restore previous context */ aplfree((int*)thisContext->text); aplfree((int*)thisContext); error(ERR_implicit, ""); } b += dim1; if (i < dim0 - 1) pop(); } aplfree((int*)thisContext->text); gsip = thisContext->prev; /* restore previous context */ aplfree((int*)thisContext); p = *--sp; pop(); *sp++ = p; }
ex_gddk() { int k; k = topfix() - thread.iorg; fetch1(); gd0(k, gdd); }
ex_revk() { int k; k = topfix() - thread.iorg; fetch1(); revk(k); }
ex_mtrn() { struct item *p; int i; p = fetch1(); if(p->rank <= 1) return; for(i=0; i<p->rank; i++) idx.idx[i] = p->rank-1-i; trn0(); }
void ex_asgn() { SymTabEntry* p; struct item* q; SymTabEntry* symtabLhsEntry; int i; p = (SymTabEntry*)sp[-1]; q = (struct item *) sp[-1]; /* just to get item->index * further down, q is reassigned */ switch (p->entryType) { case QV: i = q->index; /* get the pointer to applicable quad service routine */ (*exop[i])(1); return; case LV: symtabLhsEntry = symtabFind(p->namep); if (symtabLhsEntry == NULL) { symtabLhsEntry = symtabInsert(p->namep); } if (symtabLhsEntry != NULL) { symtabLhsEntry->entryType = LV; } if (p->itemp != NULL && p->itemp->itemType == LBL) error(ERR_implicit, "attempt to reassign a label value"); if (symtabLhsEntry == NULL) { error(ERR, "asgn - panic"); } break; default: error(ERR, "asgn - panic"); } if (p->entryUse != UNKNOWN && p->entryUse != DA) { error(ERR_domain, "asgn"); } sp--; q = fetch1(); erase(p); symtabLhsEntry->entryUse = DA; symtabLhsEntry->itemp = q; sp[-1] = (struct item*) symtabLhsEntry; if (vars_trace) { vars_dump(); } }
ex_mrho() { struct item *p, *q; data *dp; int i; p = fetch1(); q = newdat(DA, 1, p->rank); dp = q->datap; for(i=0; i<p->rank; i++) *dp++ = p->dim[i]; pop(); *sp++ = q; }
ex_asgn() { struct nlist *p; struct item *q; p = (struct nlist *)sp[-1]; switch(p->type){ case QX: pop(); p = nlook("Llx"); if(p == 0){ /* * allocate new name: */ for(p=nlist; p->namep; p++) ; p->namep = alloc(4); copy(CH, "Llx", p->namep, 4); p->type = LV; p->use = 0; p->itemp = newdat(CH, 0, 0); } sp++; /* reset stack */ break; case QD: pop(); ex_print(); return; case QC: pop(); /* ex_plot(); */ /* don't understand QC data yet -- MEC */ return; case QQ: pop(); epr0(); /* print w/out '\n' (in a2.c) */ return; case LV: if (((struct nlist *)p->itemp) && ((struct nlist *)p)->itemp->type == LBL) error("asgn to label"); break; default: error("asgn lv"); } if(p->use != 0 && p->use != DA) error("asgn var"); sp--; q = fetch1(); erase(p); p->use = DA; ((struct nlist *)p)->itemp = q; sp[-1] = (struct item *)p; }
struct isakmp_packet *parse_isakmp_packet(const uint8_t * data, size_t data_len, int * reject) { int reason = 0; uint8_t payload; struct isakmp_packet *r = new_isakmp_packet(); size_t o_data_len = data_len; size_t isakmp_data_len; if (data_len < ISAKMP_PAYLOAD_O) { DEBUG(2, printf("packet to short: len = %lld < min = %lld\n", (long long) data_len, (long long)ISAKMP_PAYLOAD_O)); reason = ISAKMP_N_UNEQUAL_PAYLOAD_LENGTHS; goto error; } DEBUG(3, printf("\nBEGIN_PARSE\n")); fetchn(r->i_cookie, ISAKMP_COOKIE_LENGTH); hex_dump("i_cookie", r->i_cookie, ISAKMP_COOKIE_LENGTH, NULL); fetchn(r->r_cookie, ISAKMP_COOKIE_LENGTH); hex_dump("r_cookie", r->r_cookie, ISAKMP_COOKIE_LENGTH, NULL); payload = fetch1(); hex_dump("payload", &payload, DUMP_UINT8, isakmp_payload_enum_array); r->isakmp_version = fetch1(); hex_dump("isakmp_version", &r->isakmp_version, DUMP_UINT8, NULL); if (r->isakmp_version > ISAKMP_VERSION) { if ((r->isakmp_version & 0xF0) >= (ISAKMP_VERSION & 0xF0)) reason = ISAKMP_N_INVALID_MAJOR_VERSION; else reason = ISAKMP_N_INVALID_MINOR_VERSION; goto error; } r->exchange_type = fetch1(); hex_dump("exchange_type", &r->exchange_type, DUMP_UINT8, isakmp_exchange_enum_array); r->flags = fetch1(); hex_dump("flags", &r->flags, DUMP_UINT8, NULL); r->message_id = fetch4(); hex_dump("message_id", &r->message_id, sizeof(r->message_id), NULL); isakmp_data_len = fetch4(); hex_dump("len", &isakmp_data_len, DUMP_UINT32, NULL); if (o_data_len != isakmp_data_len) { DEBUG(2, printf("isakmp length does not match packet length: isakmp = %lld != datalen = %lld\n", (long long)isakmp_data_len, (long long)o_data_len)); reason = ISAKMP_N_UNEQUAL_PAYLOAD_LENGTHS; goto error; } r->payload = parse_isakmp_payload(payload, &data, &data_len, &reason, 0); if (reason != 0) goto error; DEBUG(3, printf("PARSE_OK\n\n")); return r; error: free_isakmp_packet(r); if (reject) *reject = reason; return NULL; }
static struct isakmp_payload *parse_isakmp_payload(uint8_t type, const uint8_t ** data_p, size_t * data_len_p, int * reject, enum isakmp_ipsec_proto_enum decode_proto) { const uint8_t *data = *data_p, *tmpdata; size_t data_len = *data_len_p; struct isakmp_payload *r; uint8_t next_type; size_t length, olength; static const uint16_t min_payload_len[ISAKMP_PAYLOAD_MODECFG_ATTR + 1] = { 4, 12, 8, 8, 4, 8, 5, 5, 4, 4, 4, 12, 12, 4, 8 }; hex_dump("PARSING PAYLOAD type", &type, DUMP_UINT8, isakmp_payload_enum_array); if (type == 0) return NULL; if (type <= ISAKMP_PAYLOAD_MODECFG_ATTR) { if (data_len < min_payload_len[type]) { *reject = ISAKMP_N_PAYLOAD_MALFORMED; return NULL; } } else if (data_len < 4) { *reject = ISAKMP_N_PAYLOAD_MALFORMED; return NULL; } r = new_isakmp_payload(type); next_type = fetch1(); hex_dump("next_type", &next_type, DUMP_UINT8, isakmp_payload_enum_array); if (fetch1() != 0) { *reject = ISAKMP_N_PAYLOAD_MALFORMED; return r; } length = fetch2(); hex_dump("length", &length, DUMP_UINT16, NULL); if (length > data_len + 4 || ((type <= ISAKMP_PAYLOAD_MODECFG_ATTR)&&(length < min_payload_len[type])) || (length < 4)) { *reject = ISAKMP_N_PAYLOAD_MALFORMED; return r; } olength = length; switch (type) { case ISAKMP_PAYLOAD_SA: r->u.sa.doi = fetch4(); hex_dump("sa.doi", &r->u.sa.doi, DUMP_UINT32, isakmp_doi_enum_array); if (r->u.sa.doi != ISAKMP_DOI_IPSEC) { *reject = ISAKMP_N_DOI_NOT_SUPPORTED; return r; } r->u.sa.situation = fetch4(); hex_dump("sa.situation", &r->u.sa.situation, DUMP_UINT32, isakmp_ipsec_sit_enum_array); if (r->u.sa.situation != ISAKMP_IPSEC_SIT_IDENTITY_ONLY) { *reject = ISAKMP_N_SITUATION_NOT_SUPPORTED; return r; } *reject = 0; length -= 12; r->u.sa.proposals = parse_isakmp_payload(ISAKMP_PAYLOAD_P, &data, &length, reject, decode_proto); if (*reject != 0) return r; /* Allow trailing garbage at end of payload. */ data_len -= olength - 12; break; case ISAKMP_PAYLOAD_P: if (next_type != ISAKMP_PAYLOAD_P && next_type != 0) { *reject = ISAKMP_N_INVALID_PAYLOAD_TYPE; return r; } { uint8_t num_xform; struct isakmp_payload *xform; r->u.p.number = fetch1(); hex_dump("p.number", &r->u.p.number, DUMP_UINT8, NULL); r->u.p.prot_id = fetch1(); hex_dump("p.prot_id", &r->u.p.prot_id, DUMP_UINT8, isakmp_ipsec_proto_enum_array); r->u.p.spi_size = fetch1(); hex_dump("p.spi_size", &r->u.p.spi_size, DUMP_UINT8, NULL); num_xform = fetch1(); hex_dump("length", &num_xform, DUMP_UINT8, NULL); if (data_len < r->u.p.spi_size) { *reject = ISAKMP_N_PAYLOAD_MALFORMED; return r; } r->u.p.spi = xallocc(r->u.p.spi_size); fetchn(r->u.p.spi, r->u.p.spi_size); hex_dump("p.spi", r->u.p.spi, r->u.p.spi_size, NULL); length -= 8 + r->u.p.spi_size; r->u.p.transforms = parse_isakmp_payload(ISAKMP_PAYLOAD_T, &data, &length, reject, r->u.p.prot_id); for (xform = r->u.p.transforms; xform; xform = xform->next) if (num_xform-- == 0) break; if (num_xform != 0) { *reject = ISAKMP_N_BAD_PROPOSAL_SYNTAX; return r; } /* Allow trailing garbage at end of payload. */ data_len -= olength - 8 - r->u.p.spi_size; } break; case ISAKMP_PAYLOAD_T: if (next_type != ISAKMP_PAYLOAD_T && next_type != 0) { *reject = ISAKMP_N_INVALID_PAYLOAD_TYPE; return r; } r->u.t.number = fetch1(); hex_dump("t.number", &r->u.t.number, DUMP_UINT8, NULL); r->u.t.id = fetch1(); hex_dump("t.id", &r->u.t.id, DUMP_UINT8, transform_id_to_debug_strings(decode_proto)); if (fetch2() != 0) { *reject = ISAKMP_N_BAD_PROPOSAL_SYNTAX; return r; } length -= 8; r->u.t.attributes = parse_isakmp_attributes(&data, length, reject, decode_proto); data_len -= olength - 8; break; case ISAKMP_PAYLOAD_KE: case ISAKMP_PAYLOAD_HASH: case ISAKMP_PAYLOAD_SIG: case ISAKMP_PAYLOAD_NONCE: case ISAKMP_PAYLOAD_VID: case ISAKMP_PAYLOAD_NAT_D: case ISAKMP_PAYLOAD_NAT_D_OLD: r->u.ke.length = length - 4; r->u.ke.data = xallocc(r->u.ke.length); fetchn(r->u.ke.data, r->u.ke.length); hex_dump("ke.data", r->u.ke.data, r->u.ke.length, NULL); break; case ISAKMP_PAYLOAD_ID: r->u.id.type = fetch1(); hex_dump("id.type", &r->u.id.type, DUMP_UINT8, isakmp_ipsec_id_enum_array); r->u.id.protocol = fetch1(); hex_dump("id.protocol", &r->u.id.protocol, DUMP_UINT8, NULL); /* IP protocol nr */ r->u.id.port = fetch2(); hex_dump("id.port", &r->u.id.port, sizeof(r->u.id.port), NULL); r->u.id.length = length - 8; r->u.id.data = xallocc(r->u.id.length); fetchn(r->u.id.data, r->u.id.length); hex_dump("id.data", r->u.id.data, r->u.id.length, NULL); break; case ISAKMP_PAYLOAD_CERT: case ISAKMP_PAYLOAD_CR: r->u.cert.encoding = fetch1(); hex_dump("cert.encoding", &r->u.cert.encoding, DUMP_UINT8, NULL); r->u.cert.length = length - 5; fetchn(r->u.cert.data, r->u.cert.length); hex_dump("cert.data", r->u.cert.data, r->u.cert.length, NULL); break; case ISAKMP_PAYLOAD_N: r->u.n.doi = fetch4(); hex_dump("n.doi", &r->u.n.doi, DUMP_UINT32, isakmp_doi_enum_array); r->u.n.protocol = fetch1(); hex_dump("n.protocol", &r->u.n.protocol, DUMP_UINT8, isakmp_ipsec_proto_enum_array); r->u.n.spi_length = fetch1(); hex_dump("n.spi_length", &r->u.n.spi_length, DUMP_UINT8, NULL); r->u.n.type = fetch2(); hex_dump("n.type", &r->u.n.type, DUMP_UINT16, isakmp_notify_enum_array); if (r->u.n.spi_length + 12u > length) { *reject = ISAKMP_N_PAYLOAD_MALFORMED; return r; } r->u.n.spi = xallocc(r->u.n.spi_length); fetchn(r->u.n.spi, r->u.n.spi_length); hex_dump("n.spi", r->u.n.spi, r->u.n.spi_length, NULL); r->u.n.data_length = length - 12 - r->u.n.spi_length; r->u.n.data = xallocc(r->u.n.data_length); fetchn(r->u.n.data, r->u.n.data_length); hex_dump("n.data", r->u.n.data, r->u.n.data_length, NULL); if ((r->u.n.doi == ISAKMP_DOI_IPSEC)&&(r->u.n.type == ISAKMP_N_IPSEC_RESPONDER_LIFETIME)) { tmpdata = r->u.n.data; r->u.n.attributes = parse_isakmp_attributes(&tmpdata, r->u.n.data_length, reject, r->u.n.protocol); } break; case ISAKMP_PAYLOAD_D: r->u.d.doi = fetch4(); hex_dump("d.doi", &r->u.d.doi, DUMP_UINT32, isakmp_doi_enum_array); r->u.d.protocol = fetch1(); hex_dump("d.protocol", &r->u.d.protocol, DUMP_UINT8, isakmp_ipsec_proto_enum_array); r->u.d.spi_length = fetch1(); hex_dump("d.spi_length", &r->u.d.spi_length, DUMP_UINT8, NULL); r->u.d.num_spi = fetch2(); hex_dump("d.num_spi", &r->u.d.num_spi, DUMP_UINT16, NULL); if (r->u.d.num_spi * r->u.d.spi_length + 12u != length) { *reject = ISAKMP_N_PAYLOAD_MALFORMED; return r; } r->u.d.spi = xallocc(sizeof(uint8_t *) * r->u.d.num_spi); { int i; for (i = 0; i < r->u.d.num_spi; i++) { r->u.d.spi[i] = xallocc(r->u.d.spi_length); fetchn(r->u.d.spi[i], r->u.d.spi_length); hex_dump("d.spi", r->u.d.spi[i], r->u.d.spi_length, NULL); } } break; case ISAKMP_PAYLOAD_MODECFG_ATTR: r->u.modecfg.type = fetch1(); hex_dump("modecfg.type", &r->u.modecfg.type, DUMP_UINT8, isakmp_modecfg_cfg_enum_array); if (fetch1() != 0) { *reject = ISAKMP_N_PAYLOAD_MALFORMED; return r; } r->u.modecfg.id = fetch2(); hex_dump("modecfg.id", &r->u.modecfg.id, DUMP_UINT16, NULL); length -= 8; r->u.modecfg.attributes = parse_isakmp_attributes(&data, length, reject, ISAKMP_IPSEC_PROTO_MODECFG); /* this "proto" is a hack for simplicity */ data_len -= olength - 8; break; default: r->u.ke.length = length - 4; r->u.ke.data = xallocc(r->u.ke.length); fetchn(r->u.ke.data, r->u.ke.length); hex_dump("UNKNOWN.data", r->u.ke.data, r->u.ke.length, NULL); break; } *data_p = data; *data_len_p = data_len; hex_dump("DONE PARSING PAYLOAD type", &type, DUMP_UINT8, isakmp_payload_enum_array); r->next = parse_isakmp_payload(next_type, data_p, data_len_p, reject, decode_proto); return r; }
ex_rev0() { fetch1(); revk(0); }
ex_index() { struct item *p, *q; int i, j, f, n, lv; n = *pcp++; f = *pcp; p = sp[-1]; if(f == ASGN) { pcp++; if(p->type != LV) error("indexed assign value"); if(((struct nlist *)p)->use != DA) fetch1(); /* error("used before set"); */ q = ((struct nlist *)p)->itemp; } else q = fetch1(); if(q->rank != n) error("subscript C"); idx.rank = 0; for(i=0; i<n; i++) { p = sp[-i-2]; if(p->type == EL) { idx.dim[idx.rank++] = q->dim[i]; continue; } p = fetch(p); sp[-i-2] = p; for(j=0; j<p->rank; j++) idx.dim[idx.rank++] = p->dim[j]; } size(); if(f == ASGN) { p = fetch(sp[-n-2]); sp[-n-2] = p; if (p->size > 1) { if(idx.size != p->size) error("assign C"); f = 1; /* v[i] <- v */ } else { if (idx.size && !p->size) error("assign C"); /* Note -- for idx.size = 0, no assign occurs * anyway, so it is safe to set "datum" to 0 */ datum = p->size ? getdat(p) : 0; f = 2; /* v[i] <- s */ } ex_elid(); } else { p = newdat(q->type, idx.rank, idx.size); copy(IN, idx.dim, p->dim, idx.rank); *sp++ = p; f = 0; /* v[i] */ } bidx(q); index1(0, f); if(f == 0) { p = sp[-1]; sp--; for(i=0; i<=n; i++) pop(); *sp++ = p; } else { pop(); /* pop ELID */ sp--; /* skip over LV */ for(i=0; i<n; i++) pop(); } }
void ex_index() { struct item *p, *q; int i, j, f, n; n = *gsip->ptr++; f = *gsip->ptr; p = sp[-1]; if (f == ASGN) { gsip->ptr++; if (p->itemType != LV) error(ERR_value, "not a local variable"); if (((SymTabEntry*)p)->entryUse != DA) fetch1(); q = ((SymTabEntry*)p)->itemp; } else q = fetch1(); if (q->rank != n) error(ERR_index, ""); idx.rank = 0; for (i = 0; i < n; i++) { p = sp[-i - 2]; if (p->itemType == EL) { idx.dim[idx.rank++] = q->dim[i]; continue; } p = fetch(p); sp[-i - 2] = p; for (j = 0; j < p->rank; j++) idx.dim[idx.rank++] = p->dim[j]; } size(); if (f == ASGN) { p = fetch(sp[-n - 2]); sp[-n - 2] = p; if (p->size > 1) { if (idx.size != p->size) error(ERR_length, ""); f = 1; /* v[i] <- v */ } else { if (idx.size && !p->size) error(ERR_length, ""); /* Note -- for idx.size = 0, no assign occurs * anyway, so it is safe to set "datum" to 0 */ datum = p->size ? getdat(p) : 0; f = 2; /* v[i] <- s */ } ex_elid(); } else { p = newdat(q->itemType, idx.rank, idx.size); copy(IN, (char*)idx.dim, (char*)p->dim, idx.rank); *sp++ = p; f = 0; /* v[i] */ } bidx(q); index1(0, f); if (f == 0) { p = sp[-1]; sp--; for (i = 0; i <= n; i++) pop(); *sp++ = p; } else { pop(); /* pop ELID */ sp--; /* skip over LV */ for (i = 0; i < n; i++) pop(); } }