/* @@@HEAD@@@ // Veil packets buffer manipulation module */ #include "config.h" #include "defs.h" #include "y.tab.h" #include "cdc_types.h" #include "operators.h" #include "execute.h" #include "memory.h" extern Ident pabort_id, pclose_id, popen_id; #define VEIL_P_PUSH 1 #define VEIL_P_ABORT 2 #define VEIL_P_CLOSE 4 #define VEIL_P_OPEN 8 #define VEIL_P_UNDF1 16 #define VEIL_P_UNDF2 32 #define VEIL_P_UNDF3 64 #define VEIL_P_UNDF4 128 #define HEADER_SIZE 5 /* 1 byte bitfield flags 2 bytes session id 2 bytes length */ internal list_t * buffer_to_veil_packets(Buffer * buf) { int flags, session, length, blen; Buffer * databuf, * incomplete; data_t d, * list; list_t * output, * packet; char * cbuf; output = list_new(0); blen = buf->len; cbuf = buf->s; for (;;) { /* 5 bytes will give us the header, we check length again after that, because the header gives us the data length */ if (blen < HEADER_SIZE) break; flags = (int) cbuf[0]; session = (((int) cbuf[1]) * 256) + (int) cbuf[2]; length = (((int) cbuf[3]) * 256) + cbuf[4]; if (length > (blen - HEADER_SIZE)) break; /* copy the data segment of the packet to the databuf */ databuf = buffer_new(length); cbuf += HEADER_SIZE; MEMCPY(databuf->s, cbuf, length); cbuf += (length + HEADER_SIZE); blen -= (length + HEADER_SIZE); /* create the packet list, add it to the output list */ packet = list_new(4); list = list_empty_spaces(packet, 4); list[0].type = INTEGER; list[0].u.val = (flags & VEIL_P_PUSH); /* give abort precedence */ if (flags & VEIL_P_ABORT) { list[1].type = SYMBOL; list[1].u.symbol = pabort_id; } else if (flags & VEIL_P_CLOSE) { list[1].type = SYMBOL; list[1].u.symbol = pclose_id; } else if (flags & VEIL_P_OPEN) { list[1].type = SYMBOL; list[1].u.symbol = popen_id; } else { list[1].type = INTEGER; list[1].u.val = 0; } list[2].type = INTEGER; list[2].u.val = session; list[3].type = BUFFER; list[3].u.buffer = databuf; /* add it to the list */ d.type = LIST; d.u.list = packet; output = list_add(output, &d); buffer_discard(databuf); list_discard(packet); } /* add the incomplete buffer to the end */ incomplete = buffer_new(blen); if (blen > 0) MEMMOVE(incomplete->s, cbuf, blen); \ d.type = BUFFER; d.u.buffer = incomplete; output = list_add(output, &d); buffer_discard(incomplete); return output; } void op_buf_to_veil_packets(void) { data_t * args; int numargs; Buffer * buf; list_t * packets; if (!func_init_1_or_2(&args, &numargs, BUFFER, BUFFER)) return; /* if they sent us a second argument, concatenate it on the end */ buf = buffer_dup(args[0].u.buffer); if (numargs == 2) buffer_append(buf, args[1].u.buffer); packets = buffer_to_veil_packets(buf); buffer_discard(buf); pop(numargs); push_list(packets); list_discard(packets); } void op_buf_from_veil_packets(void) { if (!func_init_0()) /* &args, LIST)) */ return; push_int(0); }