-/*
- this is a tiny msrpc packet parser. This the the partner of msrpc_gen
-
- format specifiers are:
-
- U = unicode string (output is unix string)
- A = ascii string
- B = data blob
- b = data blob in header
- d = word (4 bytes)
- C = constant ascii string
- */
-BOOL msrpc_parse(DATA_BLOB *blob,
- const char *format, ...)
-{
- int i;
- va_list ap;
- char **ps, *s;
- DATA_BLOB *b;
- int head_ofs = 0;
- uint16 len1, len2;
- uint32 ptr;
- uint32 *v;
- pstring p;
-
- va_start(ap, format);
- for (i=0; format[i]; i++) {
- switch (format[i]) {
- case 'U':
- len1 = SVAL(blob->data, head_ofs); head_ofs += 2;
- len2 = SVAL(blob->data, head_ofs); head_ofs += 2;
- ptr = IVAL(blob->data, head_ofs); head_ofs += 4;
- /* make sure its in the right format - be strict */
- if (len1 != len2 || (len1&1) || ptr + len1 > blob->length) {
- return False;
- }
- ps = va_arg(ap, char **);
- pull_string(NULL, p, blob->data + ptr, -1, len1,
- STR_UNICODE|STR_NOALIGN);
- (*ps) = strdup(p);
- break;
- case 'A':
- len1 = SVAL(blob->data, head_ofs); head_ofs += 2;
- len2 = SVAL(blob->data, head_ofs); head_ofs += 2;
- ptr = IVAL(blob->data, head_ofs); head_ofs += 4;
-
- /* make sure its in the right format - be strict */
- if (len1 != len2 || ptr + len1 > blob->length) {
- return False;
- }
- ps = va_arg(ap, char **);
- if (0 < len1) {
- pull_string(NULL, p, blob->data + ptr, -1,
- len1, STR_ASCII|STR_NOALIGN);
- (*ps) = strdup(p);
- } else {
- (*ps) = NULL;
- }
- break;
- case 'B':
- len1 = SVAL(blob->data, head_ofs); head_ofs += 2;
- len2 = SVAL(blob->data, head_ofs); head_ofs += 2;
- ptr = IVAL(blob->data, head_ofs); head_ofs += 4;
- /* make sure its in the right format - be strict */
- if (len1 != len2 || ptr + len1 > blob->length) {
- return False;
- }
- b = (DATA_BLOB *)va_arg(ap, void *);
- *b = data_blob(blob->data + ptr, len1);
- break;
- case 'b':
- b = (DATA_BLOB *)va_arg(ap, void *);
- len1 = va_arg(ap, unsigned);
- *b = data_blob(blob->data + head_ofs,
- MIN(len1, blob->length - head_ofs));
- head_ofs += len1;
- break;
- case 'd':
- v = va_arg(ap, uint32 *);
- *v = IVAL(blob->data, head_ofs); head_ofs += 4;
- break;
- case 'C':
- s = va_arg(ap, char *);
- head_ofs += pull_string(NULL, p, blob->data+head_ofs, sizeof(p),
- blob->length - head_ofs,
- STR_ASCII|STR_TERMINATE);
- if (strcmp(s, p) != 0) {
- return False;
- }
- break;