1 /**********************************************************************
2 * Copyright (C) (2004) (Jack Louis) <jack@dyadsecurity.com> *
3 * *
4 * This program is free software; you can redistribute it and/or *
5 * modify it under the terms of the GNU General Public License *
6 * as published by the Free Software Foundation; either *
7 * version 2 of the License, or (at your option) any later *
8 * version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the Free Software *
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
18 **********************************************************************/
19 #include <config.h>
20
21 #include <stdlib.h>
22 #include <unistd.h>
23
24 #include <terminate.h>
25 #include <output.h>
26 #include <xmalloc.h>
27 #include <putil.h>
28 #include "parse.tab.h"
29
30 #undef LAZY_GDB
31
32 static int buffer_size=0;
33 static char *bbuf=NULL;
34
35 static int ptcpflags=0;
36
37 extern void yyerror(const char *);
38
39 #define PPBLOCK_SIZE 64
40
yyescapestr(const char * in,buf_t * bout)41 int yyescapestr(const char *in, buf_t *bout) {
42 char *out=NULL, bstr=0;
43 int j=0, j1=0;
44 #define BIN bstr=1
45
46 assert(in != NULL);
47 if (*in == '"' && *(in + 1) != '\0') in++;
48
49 /* we'll do better down there */
50 out=xstrdup(in);
51
52 for (j=0, j1=0 ; j < (int)strlen(in) ; j++) {
53 if (in[j] == '\\' && in[j + 1] != '\0') {
54 const char *tmpptr=NULL;
55 int oweight=0, result=0;
56
57 ++j;
58 switch (in[j]) {
59 case 'a':
60 out[j1++]='\a'; BIN; break;
61 case 'b':
62 out[j1++]='\b'; BIN; break;
63 case 'f':
64 out[j1++]='\f'; BIN; break;
65 case 'n':
66 out[j1++]='\n'; BIN; break;
67 case 'r':
68 out[j1++]='\r'; BIN; break;
69 case 't':
70 out[j1++]='\t'; BIN; break;
71 case 'v':
72 out[j1++]='\v'; BIN; break;
73 case '\'': /* " and ' are escaped to be the same thing */
74 case '"':
75 out[j1++]=in[j]; j++; break;
76 case '\\':
77 out[j1++]='\\'; break;
78 case '0': case '1': case '2': case '3':
79 case '4': case '5': case '6': case '7':
80 BIN;
81 /* start at index 0, go to max 3 spaces with all chars being 0 - 7 */
82 for (tmpptr=&in[j], oweight=0;
83 *tmpptr != '\0' && (*tmpptr >= 0x30 && *tmpptr <= 0x37) && oweight < 65;
84 tmpptr++) {
85 if (oweight) {
86 oweight=(oweight * 8);
87 }
88 else {
89 oweight++;
90 }
91 }
92
93 for (tmpptr=&in[j], result=0;
94 *tmpptr != '\0' && (*tmpptr >= 0x30 && *tmpptr <= 0x37) && oweight > 0;
95 tmpptr++, j++, oweight=(oweight / 8)) {
96 int add=0; char bob[2];
97
98 bob[0]=*tmpptr; bob[1]='\0';
99 add=atoi(bob);
100 result += (add * oweight);
101 }
102 /* truncate \777 to 0xFF like \377 */
103 out[j1++]=(result & 0xFF); --j;
104 /* im too lazy to refactor this so i dont need the -- so :P */
105 break;
106 case 'x':
107 BIN;
108 /* start at index 0, go to max 2 spaces with all chars being 0 - 7 */
109 j++;
110 tmpptr=&in[j];
111 if (*tmpptr == '\0' || *(tmpptr + 1) == '\0') {
112 MSG(M_ERR, "Broken hex escape, its late, sorry\n");
113 terminate(TERM_ERROR);
114 }
115 if (1) {
116 char str[3];
117 int num=0;
118
119 str[0]=*tmpptr; str[1]=*(tmpptr + 1); str[2]='\0'; j++;
120
121 if (sscanf(str, "%x", &num) != 1) {
122 MSG(M_ERR, "Broken hex escape (from sscanf), sorry `%s'\n", str);
123 terminate(TERM_ERROR);
124 }
125 out[j1++]=(uint8_t)(num & 0xFF);
126 }
127 break;
128 default:
129 MSG(M_WARN, "Warning unhandled escapechar `%c'\n", in[j]);
130 break;
131 }
132 }
133 else {
134 if ((j + 1) != (int)strlen(in)) { /* no trailing " from string */
135 out[j1++]=in[j];
136 }
137 }
138 }
139
140 if (bstr) {
141 bout->len=0;
142 bout->ptr=NULL;
143 bout->len=j1;
144 bout->ptr=(char *)xmalloc((size_t)j1);
145 memset(bout->ptr, 0, (size_t)j1);
146 memcpy(bout->ptr, out, (size_t)j1);
147 }
148 else {
149 /* terminate with a \0 if non-binary */
150 bout->len=j1;
151 bout->ptr=(char *)xmalloc((size_t)(j1 + 1));
152 memset(bout->ptr, 0, (size_t)(j1 + 1));
153 memcpy(bout->ptr, out, (size_t)j1);
154 }
155 xfree(out);
156
157 if (bstr) {
158 return BSTR;
159 }
160 return STR;
161 }
162
pbuffer_get(buf_t * in)163 void pbuffer_get(buf_t *in) {
164 in->len=buffer_size;
165 in->ptr=bbuf;
166 }
167
pbuffer_append(buf_t * in)168 void pbuffer_append(buf_t *in) {
169 assert(in != NULL);
170
171 if (bbuf == NULL) {
172 bbuf=(char *)xmalloc(in->len);
173 memcpy(bbuf, in->ptr, in->len);
174 buffer_size=in->len;
175 }
176 else {
177 char *newbuf=NULL;
178
179 newbuf=(char *)xmalloc(buffer_size + in->len);
180 memcpy(newbuf, bbuf, (size_t)buffer_size);
181 memcpy(newbuf + buffer_size, in->ptr, in->len);
182 xfree(bbuf);
183 bbuf=newbuf;
184 buffer_size=(buffer_size + in->len);
185 }
186 return;
187 }
188
pbuffer_reset(void)189 void pbuffer_reset(void) {
190 buffer_size=0;
191 if (bbuf) {
192 xfree(bbuf);
193 }
194 bbuf=NULL;
195 return;
196 }
197
add_tcpflag(int flag)198 void add_tcpflag(int flag) {
199 if (flag < 0 || flag > 0xFF) {
200 yyerror("tcp flag out of range");
201 return;
202 }
203 ptcpflags |= flag;
204 }
205
get_tcpflags(void)206 int get_tcpflags(void) {
207 if (ptcpflags < 0 || ptcpflags > 0xFF) {
208 yyerror("combined tcp flags are out of range");
209 return 0;
210 }
211 return ptcpflags;
212 }
213