13 |
14 |
15 | #include "llimits.h"
16 | #include "lua.h"
17 |
18 |
19 | /* tags for values visible from Lua */
20 | #define LAST_TAG LUA_TTHREAD
21 |
22 | #define NUM_TAGS (LAST_TAG+1)
23 |
24 |
25 | /*
26 | ** Extra tags for non-values
27 | */
28 | #define LUA_TPROTO (LAST_TAG+1)
29 | #define LUA_TUPVAL (LAST_TAG+2)
30 | #define LUA_TDEADKEY (LAST_TAG+3)
31 |
32 |
33 | /*
34 | ** Union of all collectable objects
35 | */
36 | typedef union GCObject GCObject;
37 |
38 |
39 | /*
40 | ** Common Header for all collectable objects (in macro form, to be
41 | ** included in other objects)
42 | */
43 | #define CommonHeader GCObject *next; lu_byte tt; lu_byte marked
44 |
45 |
46 | /*
47 | ** Common header in struct form
48 | */
49 | typedef struct GCheader {
50 | CommonHeader;
51 | } GCheader;
52 |
53 |
54 |
55 |
56 | /*
57 | ** Union of all Lua values
58 | */
59 | typedef union {
60 | GCObject *gc;
61 | void *p;
62 | lua_Number n;
63 | int b;
64 | } Value;
65 |
66 |
67 | /*
68 | ** Tagged Values
69 | */
70 |
71 | #define TValuefields Value value; int tt
72 |
73 | typedef struct lua_TValue {
74 | TValuefields;
75 | } TValue;
76 |
77 |
78 | /* Macros to test type */
79 | #define ttisnil(o) (ttype(o) == LUA_TNIL)
80 | #define ttisnumber(o) (ttype(o) == LUA_TNUMBER)
81 | #define ttisstring(o) (ttype(o) == LUA_TSTRING)
82 | #define ttistable(o) (ttype(o) == LUA_TTABLE)
83 | #define ttisfunction(o) (ttype(o) == LUA_TFUNCTION)
84 | #define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN)
85 | #define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA)
86 | #define ttisthread(o) (ttype(o) == LUA_TTHREAD)
87 | #define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA)
88 |
89 | /* Macros to access values */
90 | #define ttype(o) ((o)->tt)
91 | #define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc)
92 | #define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p)
93 | #define nvalue(o) check_exp(ttisnumber(o), (o)->value.n)
94 | #define rawtsvalue(o) check_exp(ttisstring(o), &(o)->value.gc->ts)
95 | #define tsvalue(o) (&rawtsvalue(o)->tsv)
96 | #define rawuvalue(o) check_exp(ttisuserdata(o), &(o)->value.gc->u)
97 | #define uvalue(o) (&rawuvalue(o)->uv)
98 | #define clvalue(o) check_exp(ttisfunction(o), &(o)->value.gc->cl)
99 | #define hvalue(o) check_exp(ttistable(o), &(o)->value.gc->h)
100 | #define bvalue(o) check_exp(ttisboolean(o), (o)->value.b)
101 | #define thvalue(o) check_exp(ttisthread(o), &(o)->value.gc->th)
102 |
103 | #define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0))
104 |
105 | /*
106 | ** for internal debug only
107 | */
108 | #define checkconsistency(obj) \
109 | lua_assert(!iscollectable(obj) || (ttype(obj) == (obj)->value.gc->gch.tt))
110 |
111 | #define checkliveness(g,obj) \
112 | lua_assert(!iscollectable(obj) || \
113 | ((ttype(obj) == (obj)->value.gc->gch.tt) && !isdead(g, (obj)->value.gc)))
114 |
115 |
116 | /* Macros to set values */
117 | #define setnilvalue(obj) ((obj)->tt=LUA_TNIL)
118 |
119 | #define setnvalue(obj,x) \
120 | { TValue *i_o=(obj); i_o->value.n=(x); i_o->tt=LUA_TNUMBER; }
121 |
122 | #define setpvalue(obj,x) \
123 | { TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TLIGHTUSERDATA; }
124 |
125 | #define setbvalue(obj,x) \
126 | { TValue *i_o=(obj); i_o->value.b=(x); i_o->tt=LUA_TBOOLEAN; }
127 |
128 | #define setsvalue(L,obj,x) \
129 | { TValue *i_o=(obj); \
130 | i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TSTRING; \
131 | checkliveness(G(L),i_o); }
132 |
133 | #define setuvalue(L,obj,x) \
134 | { TValue *i_o=(obj); \
135 | i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TUSERDATA; \
136 | checkliveness(G(L),i_o); }
137 |
138 | #define setthvalue(L,obj,x) \
139 | { TValue *i_o=(obj); \
140 | i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTHREAD; \
141 | checkliveness(G(L),i_o); }
142 |
143 | #define setclvalue(L,obj,x) \
144 | { TValue *i_o=(obj); \
145 | i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TFUNCTION; \
146 | checkliveness(G(L),i_o); }
147 |
148 | #define sethvalue(L,obj,x) \
149 | { TValue *i_o=(obj); \
150 | i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTABLE; \
151 | checkliveness(G(L),i_o); }
152 |
153 | #define setptvalue(L,obj,x) \
154 | { TValue *i_o=(obj); \
155 | i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TPROTO; \
156 | checkliveness(G(L),i_o); }
157 |
158 |
159 |
160 |
161 | #define setobj(L,obj1,obj2) \
162 | { const TValue *o2=(obj2); TValue *o1=(obj1); \
163 | o1->value = o2->value; o1->tt=o2->tt; \
164 | checkliveness(G(L),o1); }
165 |
166 |
167 | /*
168 | ** different types of sets, according to destination
169 | */
170 |
171 | /* from stack to (same) stack */
172 | #define setobjs2s setobj
173 | /* to stack (not from same stack) */
174 | #define setobj2s setobj
175 | #define setsvalue2s setsvalue
176 | #define sethvalue2s sethvalue
177 | #define setptvalue2s setptvalue
178 | /* from table to same table */
179 | #define setobjt2t setobj
180 | /* to table */
181 | #define setobj2t setobj
182 | /* to new object */
183 | #define setobj2n setobj
184 | #define setsvalue2n setsvalue
185 |
186 | #define setttype(obj, tt) (ttype(obj) = (tt))
187 |
188 |
189 | #define iscollectable(o) (ttype(o) >= LUA_TSTRING)
190 |
191 |
192 |
193 | typedef TValue *StkId; /* index to stack elements */
194 |
195 |
196 | /*
197 | ** String headers for string table
198 | */
199 | typedef union TString {
200 | L_Umaxalign dummy; /* ensures maximum alignment for strings */
201 | struct {
202 | CommonHeader;
203 | lu_byte reserved;
204 | unsigned int hash;
205 | size_t len;
206 | } tsv;
207 | } TString;
208 |
209 |
210 | #define getstr(ts) cast(const char *, (ts) + 1)
211 | #define svalue(o) getstr(rawtsvalue(o))
212 |
213 |
214 |
215 | typedef union Udata {
216 | L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */
217 | struct {
218 | CommonHeader;
219 | struct Table *metatable;
220 | struct Table *env;
221 | size_t len;
222 | } uv;
223 | } Udata;
224 |
225 |
226 |
227 |
228 | /*
229 | ** Function Prototypes
230 | */
231 | typedef struct Proto {
232 | CommonHeader;
233 | TValue *k; /* constants used by the function */
234 | Instruction *code;
235 | struct Proto **p; /* functions defined inside the function */
236 | int *lineinfo; /* map from opcodes to source lines */
237 | struct LocVar *locvars; /* information about local variables */
238 | TString **upvalues; /* upvalue names */
239 | TString *source;
240 | int sizeupvalues;
241 | int sizek; /* size of `k' */
242 | int sizecode;
243 | int sizelineinfo;
244 | int sizep; /* size of `p' */
245 | int sizelocvars;
246 | int linedefined;
247 | int lastlinedefined;
248 | GCObject *gclist;
249 | lu_byte nups; /* number of upvalues */
250 | lu_byte numparams;
251 | lu_byte is_vararg;
252 | lu_byte maxstacksize;
253 | } Proto;
254 |
255 |
256 | /* masks for new-style vararg */
257 | #define VARARG_HASARG 1
258 | #define VARARG_ISVARARG 2
259 | #define VARARG_NEEDSARG 4
260 |
261 |
262 | typedef struct LocVar {
263 | TString *varname;
264 | int startpc; /* first point where variable is active */
265 | int endpc; /* first point where variable is dead */
266 | } LocVar;
267 |
268 |
269 |
270 | /*
271 | ** Upvalues
272 | */
273 |
274 | typedef struct UpVal {
275 | CommonHeader;
276 | TValue *v; /* points to stack or to its own value */
277 | union {
278 | TValue value; /* the value (when closed) */
279 | struct { /* double linked list (when open) */
280 | struct UpVal *prev;
281 | struct UpVal *next;
282 | } l;
283 | } u;
284 | } UpVal;
285 |
286 |
287 | /*
288 | ** Closures
289 | */
290 |
291 | #define ClosureHeader \
292 | CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist; \
293 | struct Table *env
294 |
295 | typedef struct CClosure {
296 | ClosureHeader;
297 | lua_CFunction f;
298 | TValue upvalue[1];
299 | } CClosure;
300 |
301 |
302 | typedef struct LClosure {
303 | ClosureHeader;
304 | struct Proto *p;
305 | UpVal *upvals[1];
306 | } LClosure;
307 |
308 |
309 | typedef union Closure {
310 | CClosure c;
311 | LClosure l;
312 | } Closure;
313 |
314 |
315 | #define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->c.isC)
316 | #define isLfunction(o) (ttype(o) == LUA_TFUNCTION && !clvalue(o)->c.isC)
317 |
318 |
319 | /*
320 | ** Tables
321 | */
322 |
323 | typedef union TKey {
324 | struct {
325 | TValuefields;
326 | struct Node *next; /* for chaining */
327 | } nk;
328 | TValue tvk;
329 | } TKey;
330 |
331 |
332 | typedef struct Node {
333 | TValue i_val;
334 | TKey i_key;
335 | } Node;
336 |
337 |
338 | typedef struct Table {
339 | CommonHeader;
340 | lu_byte flags; /* 1<lsizenode))
361 |
362 |
363 | #define luaO_nilobject (&luaO_nilobject_)
364 |
365 | LUAI_DATA const TValue luaO_nilobject_;
366 |
367 | #define ceillog2(x) (luaO_log2((x)-1) + 1)
368 |
369 | LUAI_FUNC int luaO_log2 (unsigned int x);
370 | LUAI_FUNC int luaO_int2fb (unsigned int x);
371 | LUAI_FUNC int luaO_fb2int (int x);
372 | LUAI_FUNC int luaO_rawequalObj (const TValue *t1, const TValue *t2);
373 | LUAI_FUNC int luaO_str2d (const char *s, lua_Number *result);
374 | LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt,
375 | va_list argp);
376 | LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...);
377 | LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t len);
378 |
379 |
380 | #endif
381 |
382 |
--------------------------------------------------------------------------------
/LUA/lua/lopcodes.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: lopcodes.c,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $
3 | ** See Copyright Notice in lua.h
4 | */
5 |
6 |
7 | #define lopcodes_c
8 | #define LUA_CORE
9 |
10 |
11 | #include "lopcodes.h"
12 |
13 |
14 | /* ORDER OP */
15 |
16 | const char *const luaP_opnames[NUM_OPCODES+1] = {
17 | "MOVE",
18 | "LOADK",
19 | "LOADBOOL",
20 | "LOADNIL",
21 | "GETUPVAL",
22 | "GETGLOBAL",
23 | "GETTABLE",
24 | "SETGLOBAL",
25 | "SETUPVAL",
26 | "SETTABLE",
27 | "NEWTABLE",
28 | "SELF",
29 | "ADD",
30 | "SUB",
31 | "MUL",
32 | "DIV",
33 | "MOD",
34 | "POW",
35 | "UNM",
36 | "NOT",
37 | "LEN",
38 | "CONCAT",
39 | "JMP",
40 | "EQ",
41 | "LT",
42 | "LE",
43 | "TEST",
44 | "TESTSET",
45 | "CALL",
46 | "TAILCALL",
47 | "RETURN",
48 | "FORLOOP",
49 | "FORPREP",
50 | "TFORLOOP",
51 | "SETLIST",
52 | "CLOSE",
53 | "CLOSURE",
54 | "VARARG",
55 | NULL
56 | };
57 |
58 |
59 | #define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m))
60 |
61 | const lu_byte luaP_opmodes[NUM_OPCODES] = {
62 | /* T A B C mode opcode */
63 | opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */
64 | ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */
65 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */
66 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LOADNIL */
67 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */
68 | ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_GETGLOBAL */
69 | ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */
70 | ,opmode(0, 0, OpArgK, OpArgN, iABx) /* OP_SETGLOBAL */
71 | ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */
72 | ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */
73 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */
74 | ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */
75 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */
76 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */
77 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */
78 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */
79 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */
80 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */
81 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */
82 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */
83 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */
84 | ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */
85 | ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */
86 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */
87 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */
88 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */
89 | ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TEST */
90 | ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */
91 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */
92 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */
93 | ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */
94 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */
95 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */
96 | ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TFORLOOP */
97 | ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */
98 | ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */
99 | ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */
100 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */
101 | };
102 |
103 |
--------------------------------------------------------------------------------
/LUA/lua/lopcodes.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: lopcodes.h,v 1.125.1.1 2007/12/27 13:02:25 roberto Exp $
3 | ** Opcodes for Lua virtual machine
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 | #ifndef lopcodes_h
8 | #define lopcodes_h
9 |
10 | #include "llimits.h"
11 |
12 |
13 | /*===========================================================================
14 | We assume that instructions are unsigned numbers.
15 | All instructions have an opcode in the first 6 bits.
16 | Instructions can have the following fields:
17 | `A' : 8 bits
18 | `B' : 9 bits
19 | `C' : 9 bits
20 | `Bx' : 18 bits (`B' and `C' together)
21 | `sBx' : signed Bx
22 |
23 | A signed argument is represented in excess K; that is, the number
24 | value is the unsigned value minus K. K is exactly the maximum value
25 | for that argument (so that -max is represented by 0, and +max is
26 | represented by 2*max), which is half the maximum for the corresponding
27 | unsigned argument.
28 | ===========================================================================*/
29 |
30 |
31 | enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */
32 |
33 |
34 | /*
35 | ** size and position of opcode arguments.
36 | */
37 | #define SIZE_C 9
38 | #define SIZE_B 9
39 | #define SIZE_Bx (SIZE_C + SIZE_B)
40 | #define SIZE_A 8
41 |
42 | #define SIZE_OP 6
43 |
44 | #define POS_OP 0
45 | #define POS_A (POS_OP + SIZE_OP)
46 | #define POS_C (POS_A + SIZE_A)
47 | #define POS_B (POS_C + SIZE_C)
48 | #define POS_Bx POS_C
49 |
50 |
51 | /*
52 | ** limits for opcode arguments.
53 | ** we use (signed) int to manipulate most arguments,
54 | ** so they must fit in LUAI_BITSINT-1 bits (-1 for sign)
55 | */
56 | #if SIZE_Bx < LUAI_BITSINT-1
57 | #define MAXARG_Bx ((1<>1) /* `sBx' is signed */
59 | #else
60 | #define MAXARG_Bx MAX_INT
61 | #define MAXARG_sBx MAX_INT
62 | #endif
63 |
64 |
65 | #define MAXARG_A ((1<>POS_OP) & MASK1(SIZE_OP,0)))
81 | #define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \
82 | ((cast(Instruction, o)<>POS_A) & MASK1(SIZE_A,0)))
85 | #define SETARG_A(i,u) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \
86 | ((cast(Instruction, u)<>POS_B) & MASK1(SIZE_B,0)))
89 | #define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \
90 | ((cast(Instruction, b)<>POS_C) & MASK1(SIZE_C,0)))
93 | #define SETARG_C(i,b) ((i) = (((i)&MASK0(SIZE_C,POS_C)) | \
94 | ((cast(Instruction, b)<>POS_Bx) & MASK1(SIZE_Bx,0)))
97 | #define SETARG_Bx(i,b) ((i) = (((i)&MASK0(SIZE_Bx,POS_Bx)) | \
98 | ((cast(Instruction, b)< C) then pc++ */
190 | OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
191 |
192 | OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
193 | OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
194 | OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */
195 |
196 | OP_FORLOOP,/* A sBx R(A)+=R(A+2);
197 | if R(A) = R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
198 | OP_FORPREP,/* A sBx R(A)-=R(A+2); pc+=sBx */
199 |
200 | OP_TFORLOOP,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
201 | if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++ */
202 | OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
203 |
204 | OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/
205 | OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */
206 |
207 | OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */
208 | } OpCode;
209 |
210 |
211 | #define NUM_OPCODES (cast(int, OP_VARARG) + 1)
212 |
213 |
214 |
215 | /*===========================================================================
216 | Notes:
217 | (*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1,
218 | and can be 0: OP_CALL then sets `top' to last_result+1, so
219 | next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'.
220 |
221 | (*) In OP_VARARG, if (B == 0) then use actual number of varargs and
222 | set top (like in OP_CALL with C == 0).
223 |
224 | (*) In OP_RETURN, if (B == 0) then return up to `top'
225 |
226 | (*) In OP_SETLIST, if (B == 0) then B = `top';
227 | if (C == 0) then next `instruction' is real C
228 |
229 | (*) For comparisons, A specifies what condition the test should accept
230 | (true or false).
231 |
232 | (*) All `skips' (pc++) assume that next instruction is a jump
233 | ===========================================================================*/
234 |
235 |
236 | /*
237 | ** masks for instruction properties. The format is:
238 | ** bits 0-1: op mode
239 | ** bits 2-3: C arg mode
240 | ** bits 4-5: B arg mode
241 | ** bit 6: instruction set register A
242 | ** bit 7: operator is a test
243 | */
244 |
245 | enum OpArgMask {
246 | OpArgN, /* argument is not used */
247 | OpArgU, /* argument is used */
248 | OpArgR, /* argument is a register or a jump offset */
249 | OpArgK /* argument is a constant or register/constant */
250 | };
251 |
252 | LUAI_DATA const lu_byte luaP_opmodes[NUM_OPCODES];
253 |
254 | #define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3))
255 | #define getBMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3))
256 | #define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3))
257 | #define testAMode(m) (luaP_opmodes[m] & (1 << 6))
258 | #define testTMode(m) (luaP_opmodes[m] & (1 << 7))
259 |
260 |
261 | LUAI_DATA const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */
262 |
263 |
264 | /* number of list items to accumulate before a SETLIST instruction */
265 | #define LFIELDS_PER_FLUSH 50
266 |
267 |
268 | #endif
269 |
--------------------------------------------------------------------------------
/LUA/lua/lparser.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: lparser.h,v 1.57.1.1 2007/12/27 13:02:25 roberto Exp $
3 | ** Lua Parser
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 | #ifndef lparser_h
8 | #define lparser_h
9 |
10 | #include "llimits.h"
11 | #include "lobject.h"
12 | #include "lzio.h"
13 |
14 |
15 | /*
16 | ** Expression descriptor
17 | */
18 |
19 | typedef enum {
20 | VVOID, /* no value */
21 | VNIL,
22 | VTRUE,
23 | VFALSE,
24 | VK, /* info = index of constant in `k' */
25 | VKNUM, /* nval = numerical value */
26 | VLOCAL, /* info = local register */
27 | VUPVAL, /* info = index of upvalue in `upvalues' */
28 | VGLOBAL, /* info = index of table; aux = index of global name in `k' */
29 | VINDEXED, /* info = table register; aux = index register (or `k') */
30 | VJMP, /* info = instruction pc */
31 | VRELOCABLE, /* info = instruction pc */
32 | VNONRELOC, /* info = result register */
33 | VCALL, /* info = instruction pc */
34 | VVARARG /* info = instruction pc */
35 | } expkind;
36 |
37 | typedef struct expdesc {
38 | expkind k;
39 | union {
40 | struct { int info, aux; } s;
41 | lua_Number nval;
42 | } u;
43 | int t; /* patch list of `exit when true' */
44 | int f; /* patch list of `exit when false' */
45 | } expdesc;
46 |
47 |
48 | typedef struct upvaldesc {
49 | lu_byte k;
50 | lu_byte info;
51 | } upvaldesc;
52 |
53 |
54 | struct BlockCnt; /* defined in lparser.c */
55 |
56 |
57 | /* state needed to generate code for a given function */
58 | typedef struct FuncState {
59 | Proto *f; /* current function header */
60 | Table *h; /* table to find (and reuse) elements in `k' */
61 | struct FuncState *prev; /* enclosing function */
62 | struct LexState *ls; /* lexical state */
63 | struct lua_State *L; /* copy of the Lua state */
64 | struct BlockCnt *bl; /* chain of current blocks */
65 | int pc; /* next position to code (equivalent to `ncode') */
66 | int lasttarget; /* `pc' of last `jump target' */
67 | int jpc; /* list of pending jumps to `pc' */
68 | int freereg; /* first free register */
69 | int nk; /* number of elements in `k' */
70 | int np; /* number of elements in `p' */
71 | short nlocvars; /* number of elements in `locvars' */
72 | lu_byte nactvar; /* number of active local variables */
73 | upvaldesc upvalues[LUAI_MAXUPVALUES]; /* upvalues */
74 | unsigned short actvar[LUAI_MAXVARS]; /* declared-variable stack */
75 | } FuncState;
76 |
77 |
78 | LUAI_FUNC Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
79 | const char *name);
80 |
81 |
82 | #endif
83 |
--------------------------------------------------------------------------------
/LUA/lua/lstate.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: lstate.c,v 2.36.1.2 2008/01/03 15:20:39 roberto Exp $
3 | ** Global State
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 |
8 | #include
9 |
10 | #define lstate_c
11 | #define LUA_CORE
12 |
13 | #include "lua.h"
14 |
15 | #include "ldebug.h"
16 | #include "ldo.h"
17 | #include "lfunc.h"
18 | #include "lgc.h"
19 | #include "llex.h"
20 | #include "lmem.h"
21 | #include "lstate.h"
22 | #include "lstring.h"
23 | #include "ltable.h"
24 | #include "ltm.h"
25 |
26 |
27 | #define state_size(x) (sizeof(x) + LUAI_EXTRASPACE)
28 | #define fromstate(l) (cast(lu_byte *, (l)) - LUAI_EXTRASPACE)
29 | #define tostate(l) (cast(lua_State *, cast(lu_byte *, l) + LUAI_EXTRASPACE))
30 |
31 |
32 | /*
33 | ** Main thread combines a thread state and the global state
34 | */
35 | typedef struct LG {
36 | lua_State l;
37 | global_State g;
38 | } LG;
39 |
40 |
41 |
42 | static void stack_init (lua_State *L1, lua_State *L) {
43 | /* initialize CallInfo array */
44 | L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo);
45 | L1->ci = L1->base_ci;
46 | L1->size_ci = BASIC_CI_SIZE;
47 | L1->end_ci = L1->base_ci + L1->size_ci - 1;
48 | /* initialize stack array */
49 | L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TValue);
50 | L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK;
51 | L1->top = L1->stack;
52 | L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1;
53 | /* initialize first ci */
54 | L1->ci->func = L1->top;
55 | setnilvalue(L1->top++); /* `function' entry for this `ci' */
56 | L1->base = L1->ci->base = L1->top;
57 | L1->ci->top = L1->top + LUA_MINSTACK;
58 | }
59 |
60 |
61 | static void freestack (lua_State *L, lua_State *L1) {
62 | luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo);
63 | luaM_freearray(L, L1->stack, L1->stacksize, TValue);
64 | }
65 |
66 |
67 | /*
68 | ** open parts that may cause memory-allocation errors
69 | */
70 | static void f_luaopen (lua_State *L, void *ud) {
71 | global_State *g = G(L);
72 | UNUSED(ud);
73 | stack_init(L, L); /* init stack */
74 | sethvalue(L, gt(L), luaH_new(L, 0, 2)); /* table of globals */
75 | sethvalue(L, registry(L), luaH_new(L, 0, 2)); /* registry */
76 | luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
77 | luaT_init(L);
78 | luaX_init(L);
79 | luaS_fix(luaS_newliteral(L, MEMERRMSG));
80 | g->GCthreshold = 4*g->totalbytes;
81 | }
82 |
83 |
84 | static void preinit_state (lua_State *L, global_State *g) {
85 | G(L) = g;
86 | L->stack = NULL;
87 | L->stacksize = 0;
88 | L->errorJmp = NULL;
89 | L->hook = NULL;
90 | L->hookmask = 0;
91 | L->basehookcount = 0;
92 | L->allowhook = 1;
93 | resethookcount(L);
94 | L->openupval = NULL;
95 | L->size_ci = 0;
96 | L->nCcalls = L->baseCcalls = 0;
97 | L->status = 0;
98 | L->base_ci = L->ci = NULL;
99 | L->savedpc = NULL;
100 | L->errfunc = 0;
101 | setnilvalue(gt(L));
102 | }
103 |
104 |
105 | static void close_state (lua_State *L) {
106 | global_State *g = G(L);
107 | luaF_close(L, L->stack); /* close all upvalues for this thread */
108 | luaC_freeall(L); /* collect all objects */
109 | lua_assert(g->rootgc == obj2gco(L));
110 | lua_assert(g->strt.nuse == 0);
111 | luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *);
112 | luaZ_freebuffer(L, &g->buff);
113 | freestack(L, L);
114 | lua_assert(g->totalbytes == sizeof(LG));
115 | (*g->frealloc)(g->ud, fromstate(L), state_size(LG), 0);
116 | }
117 |
118 |
119 | lua_State *luaE_newthread (lua_State *L) {
120 | lua_State *L1 = tostate(luaM_malloc(L, state_size(lua_State)));
121 | luaC_link(L, obj2gco(L1), LUA_TTHREAD);
122 | preinit_state(L1, G(L));
123 | stack_init(L1, L); /* init stack */
124 | setobj2n(L, gt(L1), gt(L)); /* share table of globals */
125 | L1->hookmask = L->hookmask;
126 | L1->basehookcount = L->basehookcount;
127 | L1->hook = L->hook;
128 | resethookcount(L1);
129 | lua_assert(iswhite(obj2gco(L1)));
130 | return L1;
131 | }
132 |
133 |
134 | void luaE_freethread (lua_State *L, lua_State *L1) {
135 | luaF_close(L1, L1->stack); /* close all upvalues for this thread */
136 | lua_assert(L1->openupval == NULL);
137 | luai_userstatefree(L1);
138 | freestack(L, L1);
139 | luaM_freemem(L, fromstate(L1), state_size(lua_State));
140 | }
141 |
142 |
143 | LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
144 | int i;
145 | lua_State *L;
146 | global_State *g;
147 | void *l = (*f)(ud, NULL, 0, state_size(LG));
148 | if (l == NULL) return NULL;
149 | L = tostate(l);
150 | g = &((LG *)L)->g;
151 | L->next = NULL;
152 | L->tt = LUA_TTHREAD;
153 | g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT);
154 | L->marked = luaC_white(g);
155 | set2bits(L->marked, FIXEDBIT, SFIXEDBIT);
156 | preinit_state(L, g);
157 | g->frealloc = f;
158 | g->ud = ud;
159 | g->mainthread = L;
160 | g->uvhead.u.l.prev = &g->uvhead;
161 | g->uvhead.u.l.next = &g->uvhead;
162 | g->GCthreshold = 0; /* mark it as unfinished state */
163 | g->strt.size = 0;
164 | g->strt.nuse = 0;
165 | g->strt.hash = NULL;
166 | setnilvalue(registry(L));
167 | luaZ_initbuffer(L, &g->buff);
168 | g->panic = NULL;
169 | g->gcstate = GCSpause;
170 | g->rootgc = obj2gco(L);
171 | g->sweepstrgc = 0;
172 | g->sweepgc = &g->rootgc;
173 | g->gray = NULL;
174 | g->grayagain = NULL;
175 | g->weak = NULL;
176 | g->tmudata = NULL;
177 | g->totalbytes = sizeof(LG);
178 | g->gcpause = LUAI_GCPAUSE;
179 | g->gcstepmul = LUAI_GCMUL;
180 | g->gcdept = 0;
181 | for (i=0; imt[i] = NULL;
182 | if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) {
183 | /* memory allocation error: free partial state */
184 | close_state(L);
185 | L = NULL;
186 | }
187 | else
188 | luai_userstateopen(L);
189 | return L;
190 | }
191 |
192 |
193 | static void callallgcTM (lua_State *L, void *ud) {
194 | UNUSED(ud);
195 | luaC_callGCTM(L); /* call GC metamethods for all udata */
196 | }
197 |
198 |
199 | LUA_API void lua_close (lua_State *L) {
200 | L = G(L)->mainthread; /* only the main thread can be closed */
201 | lua_lock(L);
202 | luaF_close(L, L->stack); /* close all upvalues for this thread */
203 | luaC_separateudata(L, 1); /* separate udata that have GC metamethods */
204 | L->errfunc = 0; /* no error function during GC metamethods */
205 | do { /* repeat until no more errors */
206 | L->ci = L->base_ci;
207 | L->base = L->top = L->ci->base;
208 | L->nCcalls = L->baseCcalls = 0;
209 | } while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0);
210 | lua_assert(G(L)->tmudata == NULL);
211 | luai_userstateclose(L);
212 | close_state(L);
213 | }
214 |
215 |
--------------------------------------------------------------------------------
/LUA/lua/lstate.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: lstate.h,v 2.24.1.2 2008/01/03 15:20:39 roberto Exp $
3 | ** Global State
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 | #ifndef lstate_h
8 | #define lstate_h
9 |
10 | #include "lua.h"
11 |
12 | #include "lobject.h"
13 | #include "ltm.h"
14 | #include "lzio.h"
15 |
16 |
17 |
18 | struct lua_longjmp; /* defined in ldo.c */
19 |
20 |
21 | /* table of globals */
22 | #define gt(L) (&L->l_gt)
23 |
24 | /* registry */
25 | #define registry(L) (&G(L)->l_registry)
26 |
27 |
28 | /* extra stack space to handle TM calls and some other extras */
29 | #define EXTRA_STACK 5
30 |
31 |
32 | #define BASIC_CI_SIZE 8
33 |
34 | #define BASIC_STACK_SIZE (2*LUA_MINSTACK)
35 |
36 |
37 |
38 | typedef struct stringtable {
39 | GCObject **hash;
40 | lu_int32 nuse; /* number of elements */
41 | int size;
42 | } stringtable;
43 |
44 |
45 | /*
46 | ** informations about a call
47 | */
48 | typedef struct CallInfo {
49 | StkId base; /* base for this function */
50 | StkId func; /* function index in the stack */
51 | StkId top; /* top for this function */
52 | const Instruction *savedpc;
53 | int nresults; /* expected number of results from this function */
54 | int tailcalls; /* number of tail calls lost under this entry */
55 | } CallInfo;
56 |
57 |
58 |
59 | #define curr_func(L) (clvalue(L->ci->func))
60 | #define ci_func(ci) (clvalue((ci)->func))
61 | #define f_isLua(ci) (!ci_func(ci)->c.isC)
62 | #define isLua(ci) (ttisfunction((ci)->func) && f_isLua(ci))
63 |
64 |
65 | /*
66 | ** `global state', shared by all threads of this state
67 | */
68 | typedef struct global_State {
69 | stringtable strt; /* hash table for strings */
70 | lua_Alloc frealloc; /* function to reallocate memory */
71 | void *ud; /* auxiliary data to `frealloc' */
72 | lu_byte currentwhite;
73 | lu_byte gcstate; /* state of garbage collector */
74 | int sweepstrgc; /* position of sweep in `strt' */
75 | GCObject *rootgc; /* list of all collectable objects */
76 | GCObject **sweepgc; /* position of sweep in `rootgc' */
77 | GCObject *gray; /* list of gray objects */
78 | GCObject *grayagain; /* list of objects to be traversed atomically */
79 | GCObject *weak; /* list of weak tables (to be cleared) */
80 | GCObject *tmudata; /* last element of list of userdata to be GC */
81 | Mbuffer buff; /* temporary buffer for string concatentation */
82 | lu_mem GCthreshold;
83 | lu_mem totalbytes; /* number of bytes currently allocated */
84 | lu_mem estimate; /* an estimate of number of bytes actually in use */
85 | lu_mem gcdept; /* how much GC is `behind schedule' */
86 | int gcpause; /* size of pause between successive GCs */
87 | int gcstepmul; /* GC `granularity' */
88 | lua_CFunction panic; /* to be called in unprotected errors */
89 | TValue l_registry;
90 | struct lua_State *mainthread;
91 | UpVal uvhead; /* head of double-linked list of all open upvalues */
92 | struct Table *mt[NUM_TAGS]; /* metatables for basic types */
93 | TString *tmname[TM_N]; /* array with tag-method names */
94 | } global_State;
95 |
96 |
97 | /*
98 | ** `per thread' state
99 | */
100 | struct lua_State {
101 | CommonHeader;
102 | lu_byte status;
103 | StkId top; /* first free slot in the stack */
104 | StkId base; /* base of current function */
105 | global_State *l_G;
106 | CallInfo *ci; /* call info for current function */
107 | const Instruction *savedpc; /* `savedpc' of current function */
108 | StkId stack_last; /* last free slot in the stack */
109 | StkId stack; /* stack base */
110 | CallInfo *end_ci; /* points after end of ci array*/
111 | CallInfo *base_ci; /* array of CallInfo's */
112 | int stacksize;
113 | int size_ci; /* size of array `base_ci' */
114 | unsigned short nCcalls; /* number of nested C calls */
115 | unsigned short baseCcalls; /* nested C calls when resuming coroutine */
116 | lu_byte hookmask;
117 | lu_byte allowhook;
118 | int basehookcount;
119 | int hookcount;
120 | lua_Hook hook;
121 | TValue l_gt; /* table of globals */
122 | TValue env; /* temporary place for environments */
123 | GCObject *openupval; /* list of open upvalues in this stack */
124 | GCObject *gclist;
125 | struct lua_longjmp *errorJmp; /* current error recover point */
126 | ptrdiff_t errfunc; /* current error handling function (stack index) */
127 | };
128 |
129 |
130 | #define G(L) (L->l_G)
131 |
132 |
133 | /*
134 | ** Union of all collectable objects
135 | */
136 | union GCObject {
137 | GCheader gch;
138 | union TString ts;
139 | union Udata u;
140 | union Closure cl;
141 | struct Table h;
142 | struct Proto p;
143 | struct UpVal uv;
144 | struct lua_State th; /* thread */
145 | };
146 |
147 |
148 | /* macros to convert a GCObject into a specific value */
149 | #define rawgco2ts(o) check_exp((o)->gch.tt == LUA_TSTRING, &((o)->ts))
150 | #define gco2ts(o) (&rawgco2ts(o)->tsv)
151 | #define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u))
152 | #define gco2u(o) (&rawgco2u(o)->uv)
153 | #define gco2cl(o) check_exp((o)->gch.tt == LUA_TFUNCTION, &((o)->cl))
154 | #define gco2h(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h))
155 | #define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p))
156 | #define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv))
157 | #define ngcotouv(o) \
158 | check_exp((o) == NULL || (o)->gch.tt == LUA_TUPVAL, &((o)->uv))
159 | #define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th))
160 |
161 | /* macro to convert any Lua object into a GCObject */
162 | #define obj2gco(v) (cast(GCObject *, (v)))
163 |
164 |
165 | LUAI_FUNC lua_State *luaE_newthread (lua_State *L);
166 | LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1);
167 |
168 | #endif
169 |
170 |
--------------------------------------------------------------------------------
/LUA/lua/lstring.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: lstring.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $
3 | ** String table (keeps all strings handled by Lua)
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 | #include
8 |
9 | #define lstring_c
10 | #define LUA_CORE
11 |
12 | #include "lua.h"
13 |
14 | #include "lmem.h"
15 | #include "lobject.h"
16 | #include "lstate.h"
17 | #include "lstring.h"
18 |
19 |
20 |
21 | void luaS_resize (lua_State *L, int newsize) {
22 | GCObject **newhash;
23 | stringtable *tb;
24 | int i;
25 | if (G(L)->gcstate == GCSsweepstring)
26 | return; /* cannot resize during GC traverse */
27 | newhash = luaM_newvector(L, newsize, GCObject *);
28 | tb = &G(L)->strt;
29 | for (i=0; isize; i++) {
32 | GCObject *p = tb->hash[i];
33 | while (p) { /* for each node in the list */
34 | GCObject *next = p->gch.next; /* save next */
35 | unsigned int h = gco2ts(p)->hash;
36 | int h1 = lmod(h, newsize); /* new position */
37 | lua_assert(cast_int(h%newsize) == lmod(h, newsize));
38 | p->gch.next = newhash[h1]; /* chain it */
39 | newhash[h1] = p;
40 | p = next;
41 | }
42 | }
43 | luaM_freearray(L, tb->hash, tb->size, TString *);
44 | tb->size = newsize;
45 | tb->hash = newhash;
46 | }
47 |
48 |
49 | static TString *newlstr (lua_State *L, const char *str, size_t l,
50 | unsigned int h) {
51 | TString *ts;
52 | stringtable *tb;
53 | if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char))
54 | luaM_toobig(L);
55 | ts = cast(TString *, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString)));
56 | ts->tsv.len = l;
57 | ts->tsv.hash = h;
58 | ts->tsv.marked = luaC_white(G(L));
59 | ts->tsv.tt = LUA_TSTRING;
60 | ts->tsv.reserved = 0;
61 | memcpy(ts+1, str, l*sizeof(char));
62 | ((char *)(ts+1))[l] = '\0'; /* ending 0 */
63 | tb = &G(L)->strt;
64 | h = lmod(h, tb->size);
65 | ts->tsv.next = tb->hash[h]; /* chain new entry */
66 | tb->hash[h] = obj2gco(ts);
67 | tb->nuse++;
68 | if (tb->nuse > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2)
69 | luaS_resize(L, tb->size*2); /* too crowded */
70 | return ts;
71 | }
72 |
73 |
74 | TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
75 | GCObject *o;
76 | unsigned int h = cast(unsigned int, l); /* seed */
77 | size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */
78 | size_t l1;
79 | for (l1=l; l1>=step; l1-=step) /* compute hash */
80 | h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1]));
81 | for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)];
82 | o != NULL;
83 | o = o->gch.next) {
84 | TString *ts = rawgco2ts(o);
85 | if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) {
86 | /* string may be dead */
87 | if (isdead(G(L), o)) changewhite(o);
88 | return ts;
89 | }
90 | }
91 | return newlstr(L, str, l, h); /* not found */
92 | }
93 |
94 |
95 | Udata *luaS_newudata (lua_State *L, size_t s, Table *e) {
96 | Udata *u;
97 | if (s > MAX_SIZET - sizeof(Udata))
98 | luaM_toobig(L);
99 | u = cast(Udata *, luaM_malloc(L, s + sizeof(Udata)));
100 | u->uv.marked = luaC_white(G(L)); /* is not finalized */
101 | u->uv.tt = LUA_TUSERDATA;
102 | u->uv.len = s;
103 | u->uv.metatable = NULL;
104 | u->uv.env = e;
105 | /* chain it on udata list (after main thread) */
106 | u->uv.next = G(L)->mainthread->next;
107 | G(L)->mainthread->next = obj2gco(u);
108 | return u;
109 | }
110 |
111 |
--------------------------------------------------------------------------------
/LUA/lua/lstring.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: lstring.h,v 1.43.1.1 2007/12/27 13:02:25 roberto Exp $
3 | ** String table (keep all strings handled by Lua)
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 | #ifndef lstring_h
8 | #define lstring_h
9 |
10 |
11 | #include "lgc.h"
12 | #include "lobject.h"
13 | #include "lstate.h"
14 |
15 |
16 | #define sizestring(s) (sizeof(union TString)+((s)->len+1)*sizeof(char))
17 |
18 | #define sizeudata(u) (sizeof(union Udata)+(u)->len)
19 |
20 | #define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s)))
21 | #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \
22 | (sizeof(s)/sizeof(char))-1))
23 |
24 | #define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT)
25 |
26 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
27 | LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e);
28 | LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
29 |
30 |
31 | #endif
32 |
--------------------------------------------------------------------------------
/LUA/lua/ltable.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: ltable.h,v 2.10.1.1 2007/12/27 13:02:25 roberto Exp $
3 | ** Lua tables (hash)
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 | #ifndef ltable_h
8 | #define ltable_h
9 |
10 | #include "lobject.h"
11 |
12 |
13 | #define gnode(t,i) (&(t)->node[i])
14 | #define gkey(n) (&(n)->i_key.nk)
15 | #define gval(n) (&(n)->i_val)
16 | #define gnext(n) ((n)->i_key.nk.next)
17 |
18 | #define key2tval(n) (&(n)->i_key.tvk)
19 |
20 |
21 | LUAI_FUNC const TValue *luaH_getnum (Table *t, int key);
22 | LUAI_FUNC TValue *luaH_setnum (lua_State *L, Table *t, int key);
23 | LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
24 | LUAI_FUNC TValue *luaH_setstr (lua_State *L, Table *t, TString *key);
25 | LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
26 | LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key);
27 | LUAI_FUNC Table *luaH_new (lua_State *L, int narray, int lnhash);
28 | LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize);
29 | LUAI_FUNC void luaH_free (lua_State *L, Table *t);
30 | LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key);
31 | LUAI_FUNC int luaH_getn (Table *t);
32 |
33 |
34 | #if defined(LUA_DEBUG)
35 | LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key);
36 | LUAI_FUNC int luaH_isdummy (Node *n);
37 | #endif
38 |
39 |
40 | #endif
41 |
--------------------------------------------------------------------------------
/LUA/lua/ltablib.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: ltablib.c,v 1.38.1.3 2008/02/14 16:46:58 roberto Exp $
3 | ** Library for Table Manipulation
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 |
8 | #include
9 |
10 | #define ltablib_c
11 | #define LUA_LIB
12 |
13 | #include "lua.h"
14 |
15 | #include "lauxlib.h"
16 | #include "lualib.h"
17 |
18 |
19 | #define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n))
20 |
21 |
22 | static int foreachi (lua_State *L) {
23 | int i;
24 | int n = aux_getn(L, 1);
25 | luaL_checktype(L, 2, LUA_TFUNCTION);
26 | for (i=1; i <= n; i++) {
27 | lua_pushvalue(L, 2); /* function */
28 | lua_pushinteger(L, i); /* 1st argument */
29 | lua_rawgeti(L, 1, i); /* 2nd argument */
30 | lua_call(L, 2, 1);
31 | if (!lua_isnil(L, -1))
32 | return 1;
33 | lua_pop(L, 1); /* remove nil result */
34 | }
35 | return 0;
36 | }
37 |
38 |
39 | static int foreach (lua_State *L) {
40 | luaL_checktype(L, 1, LUA_TTABLE);
41 | luaL_checktype(L, 2, LUA_TFUNCTION);
42 | lua_pushnil(L); /* first key */
43 | while (lua_next(L, 1)) {
44 | lua_pushvalue(L, 2); /* function */
45 | lua_pushvalue(L, -3); /* key */
46 | lua_pushvalue(L, -3); /* value */
47 | lua_call(L, 2, 1);
48 | if (!lua_isnil(L, -1))
49 | return 1;
50 | lua_pop(L, 2); /* remove value and result */
51 | }
52 | return 0;
53 | }
54 |
55 |
56 | static int maxn (lua_State *L) {
57 | lua_Number max = 0;
58 | luaL_checktype(L, 1, LUA_TTABLE);
59 | lua_pushnil(L); /* first key */
60 | while (lua_next(L, 1)) {
61 | lua_pop(L, 1); /* remove value */
62 | if (lua_type(L, -1) == LUA_TNUMBER) {
63 | lua_Number v = lua_tonumber(L, -1);
64 | if (v > max) max = v;
65 | }
66 | }
67 | lua_pushnumber(L, max);
68 | return 1;
69 | }
70 |
71 |
72 | static int getn (lua_State *L) {
73 | lua_pushinteger(L, aux_getn(L, 1));
74 | return 1;
75 | }
76 |
77 |
78 | static int setn (lua_State *L) {
79 | luaL_checktype(L, 1, LUA_TTABLE);
80 | #ifndef luaL_setn
81 | luaL_setn(L, 1, luaL_checkint(L, 2));
82 | #else
83 | luaL_error(L, LUA_QL("setn") " is obsolete");
84 | #endif
85 | lua_pushvalue(L, 1);
86 | return 1;
87 | }
88 |
89 |
90 | static int tinsert (lua_State *L) {
91 | int e = aux_getn(L, 1) + 1; /* first empty element */
92 | int pos; /* where to insert new element */
93 | switch (lua_gettop(L)) {
94 | case 2: { /* called with only 2 arguments */
95 | pos = e; /* insert new element at the end */
96 | break;
97 | }
98 | case 3: {
99 | int i;
100 | pos = luaL_checkint(L, 2); /* 2nd argument is the position */
101 | if (pos > e) e = pos; /* `grow' array if necessary */
102 | for (i = e; i > pos; i--) { /* move up elements */
103 | lua_rawgeti(L, 1, i-1);
104 | lua_rawseti(L, 1, i); /* t[i] = t[i-1] */
105 | }
106 | break;
107 | }
108 | default: {
109 | return luaL_error(L, "wrong number of arguments to " LUA_QL("insert"));
110 | }
111 | }
112 | luaL_setn(L, 1, e); /* new size */
113 | lua_rawseti(L, 1, pos); /* t[pos] = v */
114 | return 0;
115 | }
116 |
117 |
118 | static int tremove (lua_State *L) {
119 | int e = aux_getn(L, 1);
120 | int pos = luaL_optint(L, 2, e);
121 | if (!(1 <= pos && pos <= e)) /* position is outside bounds? */
122 | return 0; /* nothing to remove */
123 | luaL_setn(L, 1, e - 1); /* t.n = n-1 */
124 | lua_rawgeti(L, 1, pos); /* result = t[pos] */
125 | for ( ;pos= P */
228 | while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) {
229 | if (i>u) luaL_error(L, "invalid order function for sorting");
230 | lua_pop(L, 1); /* remove a[i] */
231 | }
232 | /* repeat --j until a[j] <= P */
233 | while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) {
234 | if (j
8 |
9 | #define ltm_c
10 | #define LUA_CORE
11 |
12 | #include "lua.h"
13 |
14 | #include "lobject.h"
15 | #include "lstate.h"
16 | #include "lstring.h"
17 | #include "ltable.h"
18 | #include "ltm.h"
19 |
20 |
21 |
22 | const char *const luaT_typenames[] = {
23 | "nil", "boolean", "userdata", "number",
24 | "string", "table", "function", "userdata", "thread",
25 | "proto", "upval"
26 | };
27 |
28 |
29 | void luaT_init (lua_State *L) {
30 | static const char *const luaT_eventname[] = { /* ORDER TM */
31 | "__index", "__newindex",
32 | "__gc", "__mode", "__eq",
33 | "__add", "__sub", "__mul", "__div", "__mod",
34 | "__pow", "__unm", "__len", "__lt", "__le",
35 | "__concat", "__call"
36 | };
37 | int i;
38 | for (i=0; itmname[i] = luaS_new(L, luaT_eventname[i]);
40 | luaS_fix(G(L)->tmname[i]); /* never collect these names */
41 | }
42 | }
43 |
44 |
45 | /*
46 | ** function to be used with macro "fasttm": optimized for absence of
47 | ** tag methods
48 | */
49 | const TValue *luaT_gettm (Table *events, TMS event, TString *ename) {
50 | const TValue *tm = luaH_getstr(events, ename);
51 | lua_assert(event <= TM_EQ);
52 | if (ttisnil(tm)) { /* no tag method? */
53 | events->flags |= cast_byte(1u<metatable;
65 | break;
66 | case LUA_TUSERDATA:
67 | mt = uvalue(o)->metatable;
68 | break;
69 | default:
70 | mt = G(L)->mt[ttype(o)];
71 | }
72 | return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject);
73 | }
74 |
75 |
--------------------------------------------------------------------------------
/LUA/lua/ltm.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: ltm.h,v 2.6.1.1 2007/12/27 13:02:25 roberto Exp $
3 | ** Tag methods
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 | #ifndef ltm_h
8 | #define ltm_h
9 |
10 |
11 | #include "lobject.h"
12 |
13 |
14 | /*
15 | * WARNING: if you change the order of this enumeration,
16 | * grep "ORDER TM"
17 | */
18 | typedef enum {
19 | TM_INDEX,
20 | TM_NEWINDEX,
21 | TM_GC,
22 | TM_MODE,
23 | TM_EQ, /* last tag method with `fast' access */
24 | TM_ADD,
25 | TM_SUB,
26 | TM_MUL,
27 | TM_DIV,
28 | TM_MOD,
29 | TM_POW,
30 | TM_UNM,
31 | TM_LEN,
32 | TM_LT,
33 | TM_LE,
34 | TM_CONCAT,
35 | TM_CALL,
36 | TM_N /* number of elements in the enum */
37 | } TMS;
38 |
39 |
40 |
41 | #define gfasttm(g,et,e) ((et) == NULL ? NULL : \
42 | ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e]))
43 |
44 | #define fasttm(l,et,e) gfasttm(G(l), et, e)
45 |
46 | LUAI_DATA const char *const luaT_typenames[];
47 |
48 |
49 | LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename);
50 | LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o,
51 | TMS event);
52 | LUAI_FUNC void luaT_init (lua_State *L);
53 |
54 | #endif
55 |
--------------------------------------------------------------------------------
/LUA/lua/lualib.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: lualib.h,v 1.36.1.1 2007/12/27 13:02:25 roberto Exp $
3 | ** Lua standard libraries
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 |
8 | #ifndef lualib_h
9 | #define lualib_h
10 |
11 | #include "lua.h"
12 |
13 |
14 | /* Key to file-handle type */
15 | #define LUA_FILEHANDLE "FILE*"
16 |
17 |
18 | #define LUA_COLIBNAME "coroutine"
19 | LUALIB_API int (luaopen_base) (lua_State *L);
20 |
21 | #define LUA_TABLIBNAME "table"
22 | LUALIB_API int (luaopen_table) (lua_State *L);
23 | /*
24 | #define LUA_IOLIBNAME "io"
25 | LUALIB_API int (luaopen_io) (lua_State *L);
26 |
27 | #define LUA_OSLIBNAME "os"
28 | LUALIB_API int (luaopen_os) (lua_State *L);
29 | */
30 |
31 | #define LUA_STRLIBNAME "string"
32 | LUALIB_API int (luaopen_string) (lua_State *L);
33 |
34 | /*
35 | #define LUA_MATHLIBNAME "math"
36 | LUALIB_API int (luaopen_math) (lua_State *L);
37 |
38 | #define LUA_DBLIBNAME "debug"
39 | LUALIB_API int (luaopen_debug) (lua_State *L);
40 |
41 | #define LUA_LOADLIBNAME "package"
42 | LUALIB_API int (luaopen_package) (lua_State *L);
43 | */
44 |
45 | /* open all previous libraries */
46 | LUALIB_API void (luaL_openlibs) (lua_State *L);
47 |
48 |
49 |
50 | #ifndef lua_assert
51 | #define lua_assert(x) ((void)0)
52 | #endif
53 |
54 |
55 | #endif
56 |
--------------------------------------------------------------------------------
/LUA/lua/lundump.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: lundump.c,v 2.7.1.4 2008/04/04 19:51:41 roberto Exp $
3 | ** load precompiled Lua chunks
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 | #include
8 |
9 | #define lundump_c
10 | #define LUA_CORE
11 |
12 | #include "lua.h"
13 |
14 | #include "ldebug.h"
15 | #include "ldo.h"
16 | #include "lfunc.h"
17 | #include "lmem.h"
18 | #include "lobject.h"
19 | #include "lstring.h"
20 | #include "lundump.h"
21 | #include "lzio.h"
22 |
23 | typedef struct {
24 | lua_State* L;
25 | ZIO* Z;
26 | Mbuffer* b;
27 | const char* name;
28 | } LoadState;
29 |
30 | #ifdef LUAC_TRUST_BINARIES
31 | #define IF(c,s)
32 | #define error(S,s)
33 | #else
34 | #define IF(c,s) if (c) error(S,s)
35 |
36 | static void error(LoadState* S, const char* why)
37 | {
38 | luaO_pushfstring(S->L,"%s: %s in precompiled chunk",S->name,why);
39 | luaD_throw(S->L,LUA_ERRSYNTAX);
40 | }
41 | #endif
42 |
43 | #define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size))
44 | #define LoadByte(S) (lu_byte)LoadChar(S)
45 | #define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x))
46 | #define LoadVector(S,b,n,size) LoadMem(S,b,n,size)
47 |
48 | static void LoadBlock(LoadState* S, void* b, size_t size)
49 | {
50 | size_t r=luaZ_read(S->Z,b,size);
51 | IF (r!=0, "unexpected end");
52 | }
53 |
54 | static int LoadChar(LoadState* S)
55 | {
56 | char x;
57 | LoadVar(S,x);
58 | return x;
59 | }
60 |
61 | static int LoadInt(LoadState* S)
62 | {
63 | int x;
64 | LoadVar(S,x);
65 | IF (x<0, "bad integer");
66 | return x;
67 | }
68 |
69 | static lua_Number LoadNumber(LoadState* S)
70 | {
71 | lua_Number x;
72 | LoadVar(S,x);
73 | return x;
74 | }
75 |
76 | static TString* LoadString(LoadState* S)
77 | {
78 | size_t size;
79 | LoadVar(S,size);
80 | if (size==0)
81 | return NULL;
82 | else
83 | {
84 | char* s=luaZ_openspace(S->L,S->b,size);
85 | LoadBlock(S,s,size);
86 | return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */
87 | }
88 | }
89 |
90 | static void LoadCode(LoadState* S, Proto* f)
91 | {
92 | int n=LoadInt(S);
93 | f->code=luaM_newvector(S->L,n,Instruction);
94 | f->sizecode=n;
95 | LoadVector(S,f->code,n,sizeof(Instruction));
96 | }
97 |
98 | static Proto* LoadFunction(LoadState* S, TString* p);
99 |
100 | static void LoadConstants(LoadState* S, Proto* f)
101 | {
102 | int i,n;
103 | n=LoadInt(S);
104 | f->k=luaM_newvector(S->L,n,TValue);
105 | f->sizek=n;
106 | for (i=0; ik[i]);
107 | for (i=0; ik[i];
110 | int t=LoadChar(S);
111 | switch (t)
112 | {
113 | case LUA_TNIL:
114 | setnilvalue(o);
115 | break;
116 | case LUA_TBOOLEAN:
117 | setbvalue(o,LoadChar(S)!=0);
118 | break;
119 | case LUA_TNUMBER:
120 | setnvalue(o,LoadNumber(S));
121 | break;
122 | case LUA_TSTRING:
123 | setsvalue2n(S->L,o,LoadString(S));
124 | break;
125 | default:
126 | error(S,"bad constant");
127 | break;
128 | }
129 | }
130 | n=LoadInt(S);
131 | f->p=luaM_newvector(S->L,n,Proto*);
132 | f->sizep=n;
133 | for (i=0; ip[i]=NULL;
134 | for (i=0; ip[i]=LoadFunction(S,f->source);
135 | }
136 |
137 | static void LoadDebug(LoadState* S, Proto* f)
138 | {
139 | int i,n;
140 | n=LoadInt(S);
141 | f->lineinfo=luaM_newvector(S->L,n,int);
142 | f->sizelineinfo=n;
143 | LoadVector(S,f->lineinfo,n,sizeof(int));
144 | n=LoadInt(S);
145 | f->locvars=luaM_newvector(S->L,n,LocVar);
146 | f->sizelocvars=n;
147 | for (i=0; ilocvars[i].varname=NULL;
148 | for (i=0; ilocvars[i].varname=LoadString(S);
151 | f->locvars[i].startpc=LoadInt(S);
152 | f->locvars[i].endpc=LoadInt(S);
153 | }
154 | n=LoadInt(S);
155 | f->upvalues=luaM_newvector(S->L,n,TString*);
156 | f->sizeupvalues=n;
157 | for (i=0; iupvalues[i]=NULL;
158 | for (i=0; iupvalues[i]=LoadString(S);
159 | }
160 |
161 | static Proto* LoadFunction(LoadState* S, TString* p)
162 | {
163 | Proto* f;
164 | if (++S->L->nCcalls > LUAI_MAXCCALLS) error(S,"code too deep");
165 | f=luaF_newproto(S->L);
166 | setptvalue2s(S->L,S->L->top,f); incr_top(S->L);
167 | f->source=LoadString(S); if (f->source==NULL) f->source=p;
168 | f->linedefined=LoadInt(S);
169 | f->lastlinedefined=LoadInt(S);
170 | f->nups=LoadByte(S);
171 | f->numparams=LoadByte(S);
172 | f->is_vararg=LoadByte(S);
173 | f->maxstacksize=LoadByte(S);
174 | LoadCode(S,f);
175 | LoadConstants(S,f);
176 | LoadDebug(S,f);
177 | IF (!luaG_checkcode(f), "bad code");
178 | S->L->top--;
179 | S->L->nCcalls--;
180 | return f;
181 | }
182 |
183 | static void LoadHeader(LoadState* S)
184 | {
185 | char h[LUAC_HEADERSIZE];
186 | char s[LUAC_HEADERSIZE];
187 | luaU_header(h);
188 | LoadBlock(S,s,LUAC_HEADERSIZE);
189 | IF (memcmp(h,s,LUAC_HEADERSIZE)!=0, "bad header");
190 | }
191 |
192 | /*
193 | ** load precompiled chunk
194 | */
195 | Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name)
196 | {
197 | LoadState S;
198 | if (*name=='@' || *name=='=')
199 | S.name=name+1;
200 | else if (*name==LUA_SIGNATURE[0])
201 | S.name="binary string";
202 | else
203 | S.name=name;
204 | S.L=L;
205 | S.Z=Z;
206 | S.b=buff;
207 | LoadHeader(&S);
208 | return LoadFunction(&S,luaS_newliteral(L,"=?"));
209 | }
210 |
211 | /*
212 | * make header
213 | */
214 | void luaU_header (char* h)
215 | {
216 | int x=1;
217 | memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1);
218 | h+=sizeof(LUA_SIGNATURE)-1;
219 | *h++=(char)LUAC_VERSION;
220 | *h++=(char)LUAC_FORMAT;
221 | *h++=(char)*(char*)&x; /* endianness */
222 | *h++=(char)sizeof(int);
223 | *h++=(char)sizeof(size_t);
224 | *h++=(char)sizeof(Instruction);
225 | *h++=(char)sizeof(lua_Number);
226 | *h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */
227 | }
228 |
--------------------------------------------------------------------------------
/LUA/lua/lundump.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: lundump.h,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $
3 | ** load precompiled Lua chunks
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 | #ifndef lundump_h
8 | #define lundump_h
9 |
10 | #include "lobject.h"
11 | #include "lzio.h"
12 |
13 | /* load one chunk; from lundump.c */
14 | LUAI_FUNC Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name);
15 |
16 | /* make header; from lundump.c */
17 | LUAI_FUNC void luaU_header (char* h);
18 |
19 | /* dump one chunk; from ldump.c */
20 | LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip);
21 |
22 | #ifdef luac_c
23 | /* print one chunk; from print.c */
24 | LUAI_FUNC void luaU_print (const Proto* f, int full);
25 | #endif
26 |
27 | /* for header of binary files -- this is Lua 5.1 */
28 | #define LUAC_VERSION 0x51
29 |
30 | /* for header of binary files -- this is the official format */
31 | #define LUAC_FORMAT 0
32 |
33 | /* size of header of binary files */
34 | #define LUAC_HEADERSIZE 12
35 |
36 | #endif
37 |
--------------------------------------------------------------------------------
/LUA/lua/lvm.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: lvm.h,v 2.5.1.1 2007/12/27 13:02:25 roberto Exp $
3 | ** Lua virtual machine
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 | #ifndef lvm_h
8 | #define lvm_h
9 |
10 |
11 | #include "ldo.h"
12 | #include "lobject.h"
13 | #include "ltm.h"
14 |
15 |
16 | #define tostring(L,o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o)))
17 |
18 | #define tonumber(o,n) (ttype(o) == LUA_TNUMBER || \
19 | (((o) = luaV_tonumber(o,n)) != NULL))
20 |
21 | #define equalobj(L,o1,o2) \
22 | (ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2))
23 |
24 |
25 | LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
26 | LUAI_FUNC int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2);
27 | LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n);
28 | LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj);
29 | LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key,
30 | StkId val);
31 | LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key,
32 | StkId val);
33 | LUAI_FUNC void luaV_execute (lua_State *L, int nexeccalls);
34 | LUAI_FUNC void luaV_concat (lua_State *L, int total, int last);
35 |
36 | #endif
37 |
--------------------------------------------------------------------------------
/LUA/lua/lzio.c:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: lzio.c,v 1.31.1.1 2007/12/27 13:02:25 roberto Exp $
3 | ** a generic input stream interface
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 | #include
8 |
9 | #define lzio_c
10 | #define LUA_CORE
11 |
12 | #include "lua.h"
13 |
14 | #include "llimits.h"
15 | #include "lmem.h"
16 | #include "lstate.h"
17 | #include "lzio.h"
18 |
19 |
20 | int luaZ_fill (ZIO *z) {
21 | size_t size;
22 | lua_State *L = z->L;
23 | const char *buff;
24 | lua_unlock(L);
25 | buff = z->reader(L, z->data, &size);
26 | lua_lock(L);
27 | if (buff == NULL || size == 0) return EOZ;
28 | z->n = size - 1;
29 | z->p = buff;
30 | return char2int(*(z->p++));
31 | }
32 |
33 |
34 | int luaZ_lookahead (ZIO *z) {
35 | if (z->n == 0) {
36 | if (luaZ_fill(z) == EOZ)
37 | return EOZ;
38 | else {
39 | z->n++; /* luaZ_fill removed first byte; put back it */
40 | z->p--;
41 | }
42 | }
43 | return char2int(*z->p);
44 | }
45 |
46 |
47 | void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) {
48 | z->L = L;
49 | z->reader = reader;
50 | z->data = data;
51 | z->n = 0;
52 | z->p = NULL;
53 | }
54 |
55 |
56 | /* --------------------------------------------------------------- read --- */
57 | size_t luaZ_read (ZIO *z, void *b, size_t n) {
58 | while (n) {
59 | size_t m;
60 | if (luaZ_lookahead(z) == EOZ)
61 | return n; /* return number of missing bytes */
62 | m = (n <= z->n) ? n : z->n; /* min. between n and z->n */
63 | memcpy(b, z->p, m);
64 | z->n -= m;
65 | z->p += m;
66 | b = (char *)b + m;
67 | n -= m;
68 | }
69 | return 0;
70 | }
71 |
72 | /* ------------------------------------------------------------------------ */
73 | char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n) {
74 | if (n > buff->buffsize) {
75 | if (n < LUA_MINBUFFER) n = LUA_MINBUFFER;
76 | luaZ_resizebuffer(L, buff, n);
77 | }
78 | return buff->buffer;
79 | }
80 |
81 |
82 |
--------------------------------------------------------------------------------
/LUA/lua/lzio.h:
--------------------------------------------------------------------------------
1 | /*
2 | ** $Id: lzio.h,v 1.21.1.1 2007/12/27 13:02:25 roberto Exp $
3 | ** Buffered streams
4 | ** See Copyright Notice in lua.h
5 | */
6 |
7 |
8 | #ifndef lzio_h
9 | #define lzio_h
10 |
11 | #include "lua.h"
12 |
13 | #include "lmem.h"
14 |
15 |
16 | #define EOZ (-1) /* end of stream */
17 |
18 | typedef struct Zio ZIO;
19 |
20 | #define char2int(c) cast(int, cast(unsigned char, (c)))
21 |
22 | #define zgetc(z) (((z)->n--)>0 ? char2int(*(z)->p++) : luaZ_fill(z))
23 |
24 | typedef struct Mbuffer {
25 | char *buffer;
26 | size_t n;
27 | size_t buffsize;
28 | } Mbuffer;
29 |
30 | #define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0)
31 |
32 | #define luaZ_buffer(buff) ((buff)->buffer)
33 | #define luaZ_sizebuffer(buff) ((buff)->buffsize)
34 | #define luaZ_bufflen(buff) ((buff)->n)
35 |
36 | #define luaZ_resetbuffer(buff) ((buff)->n = 0)
37 |
38 |
39 | #define luaZ_resizebuffer(L, buff, size) \
40 | (luaM_reallocvector(L, (buff)->buffer, (buff)->buffsize, size, char), \
41 | (buff)->buffsize = size)
42 |
43 | #define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0)
44 |
45 |
46 | LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n);
47 | LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader,
48 | void *data);
49 | LUAI_FUNC size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */
50 | LUAI_FUNC int luaZ_lookahead (ZIO *z);
51 |
52 |
53 |
54 | /* --------- Private Part ------------------ */
55 |
56 | struct Zio {
57 | size_t n; /* bytes still unread */
58 | const char *p; /* current position in buffer */
59 | lua_Reader reader;
60 | void* data; /* additional data */
61 | lua_State *L; /* Lua state (for reader) */
62 | };
63 |
64 |
65 | LUAI_FUNC int luaZ_fill (ZIO *z);
66 |
67 | #endif
68 |
--------------------------------------------------------------------------------
/LUA/lua/setjmp.S:
--------------------------------------------------------------------------------
1 | #
2 | # arch/i386/setjmp.S
3 | #
4 | # setjmp/longjmp for the i386 architecture
5 | #
6 |
7 | #
8 | # The jmp_buf is assumed to contain the following, in order:
9 | # %ebx
10 | # %esp
11 | # %ebp
12 | # %esi
13 | # %edi
14 | #
15 | #
16 |
17 | #define _REGPARM
18 |
19 | .text
20 | .align 4
21 | .globl setjmp
22 | .type setjmp, @function
23 | setjmp:
24 | #ifdef _REGPARM
25 | movl %eax,%edx
26 | #else
27 | movl 4(%esp),%edx
28 | #endif
29 | popl %ecx # Return address, and adjust the stack
30 | xorl %eax,%eax # Return value
31 | movl %ebx,(%edx)
32 | movl %esp,4(%edx) # Post-return %esp!
33 | pushl %ecx # Make the call/return stack happy
34 | movl %ebp,8(%edx)
35 | movl %esi,12(%edx)
36 | movl %edi,16(%edx)
37 | movl %ecx,20(%edx) # Return address
38 | ret
39 |
40 | .size setjmp,.-setjmp
41 |
42 | .text
43 | .align 4
44 | .globl longjmp
45 | .type longjmp, @function
46 | longjmp:
47 | #ifdef _REGPARM
48 | xchgl %eax,%edx
49 | #else
50 | movl 4(%esp),%edx # jmp_ptr address
51 | movl 8(%esp),%eax # Return value
52 | #endif
53 | movl (%edx),%ebx
54 | movl 4(%edx),%esp
55 | movl 8(%edx),%ebp
56 | movl 12(%edx),%esi
57 | movl 16(%edx),%edi
58 | jmp *20(%edx)
59 |
60 | .size longjmp,.-longjmp
61 |
--------------------------------------------------------------------------------
/LUA/lua/setjmp_64.S:
--------------------------------------------------------------------------------
1 | #
2 | # arch/i386/setjmp.S
3 | #
4 | # setjmp/longjmp for the i386 architecture
5 | #
6 |
7 | #
8 | # The jmp_buf is assumed to contain the following, in order:
9 | # %ebx
10 | # %esp
11 | # %ebp
12 | # %esi
13 | # %edi
14 | #
15 | #
16 |
17 | #define _REGPARM
18 |
19 | .text
20 | .align 4
21 | .globl setjmp
22 | .type setjmp, @function
23 | setjmp:
24 | #ifdef _REGPARM
25 | movq %rax,%rdx
26 | #else
27 | movq 4(%rsp),%rdx
28 | #endif
29 | popq %rcx # Return address, and adjust the stack
30 | xorq %rax,%rax # Return value
31 | movq %rbx,(%rdx)
32 | movq %rsp,4(%rdx) # Post-return %esp!
33 | pushq %rcx # Make the call/return stack happy
34 | movq %rbp,8(%rdx)
35 | movq %rsi,12(%rdx)
36 | movq %rdi,16(%rdx)
37 | movq %rcx,20(%rdx) # Return address
38 | ret
39 |
40 | .size setjmp,.-setjmp
41 |
42 | .text
43 | .align 4
44 | .globl longjmp
45 | .type longjmp, @function
46 | longjmp:
47 | #ifdef _REGPARM
48 | xchgq %rax,%rdx
49 | #else
50 | movq 4(%rsp),%rdx # jmp_ptr address
51 | movq 8(%rsp),%rax # Return value
52 | #endif
53 | movq (%rdx),%rbx
54 | movq 4(%rdx),%rsp
55 | movq 8(%rdx),%rbp
56 | movq 12(%rdx),%rsi
57 | movq 16(%rdx),%rdi
58 | jmp *20(%rdx)
59 |
60 | .size longjmp,.-longjmp
61 |
62 |
--------------------------------------------------------------------------------
/LUA/nf_lua.c:
--------------------------------------------------------------------------------
1 | #if defined(__KERNEL__)
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | #endif
11 |
12 | #include "lua.h"
13 | #include "lobject.h" /*sizeof(udata) */
14 | #include "lauxlib.h"
15 | #include "controller.h"
16 |
17 | #if defined(__KERNEL__) /* reachs until luaopen_nflib */
18 |
19 |
20 | static int32_t nf_get_random(lua_State *L)
21 | {
22 | uint32_t rand = 0;
23 |
24 | get_random_bytes(&rand, sizeof(uint32_t ));
25 | lua_pushnumber(L, rand);
26 | return 1;
27 | }
28 |
29 | static int32_t nf_get_time(lua_State *L)
30 | {
31 | lua_pushnumber(L, jiffies_to_msecs(jiffies_64));
32 | return 1;
33 | }
34 |
35 | static const struct luaL_Reg nf_lua_lib_f [] = {
36 | { "get_random", nf_get_random },
37 | { "get_time", nf_get_time },
38 | { NULL, NULL }
39 | };
40 |
41 | void luaopen_nflib(lua_State *L)
42 | {
43 | int32_t top;
44 |
45 | luaL_register(L, NETFILTER_LIB, nf_lua_lib_f);
46 | lua_pop(L, 1);
47 |
48 | /* registering verdicts inside the _G */
49 | lua_getglobal(L, "_G");
50 | top = lua_gettop(L);
51 |
52 | lua_pushinteger(L, XT_CONTINUE);
53 | lua_setfield(L, top, "XT_CONTINUE"); /* continiue with next rule */
54 |
55 | lua_pushinteger(L, NF_DROP);
56 | lua_setfield(L, top, "NF_DROP"); /* stop traversal in the current table hook and drop packet */
57 |
58 | lua_pushinteger(L, NF_ACCEPT);
59 | lua_setfield(L, top, "NF_ACCEPT"); /* stop traversal in the current table hook and accept packet */
60 |
61 | lua_pop(L, 1); /* pop _G */
62 | }
63 |
64 | #endif
65 |
--------------------------------------------------------------------------------
/LUA/prot_buf_ethernet.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010 University of Basel
3 | * by Andre Graf
4 | *
5 | * This program is free software; you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation; either version 2 of the License, or
8 | * (at your option) any later 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, see .
17 | */
18 |
19 | #include "controller.h"
20 |
21 |
22 | static int32_t eth_has_protocol(lua_State *L, struct protocol_buf * prot_buf, lua_packet_segment * seg, int32_t protocol_type)
23 | {
24 | uint8_t *embedded_protocol = seg->start + seg->offset + 12 /*bytes*/;
25 | unsigned short res = (unsigned short)((embedded_protocol[1] << CHAR_BIT) | (embedded_protocol[0] << CHAR_BIT));
26 |
27 | switch (res) {
28 | case 0x0800: /* 1: Internet Protocol (IP) */
29 | if (protocol_type == PACKET_IP) return 1;
30 | break;
31 | default:
32 | return 0;
33 | }
34 |
35 | return 0;
36 | }
37 |
38 | static const struct protocol_field eth_protocol_fields[] = {
39 | /* field name offset length getter setter */
40 | { "dmac", 0, 48, NULL, NULL },
41 | { "smac", 48, 48, NULL, NULL },
42 | { "type", 96, 16, NULL, NULL },
43 | { "data", 112, 0, NULL, NULL },
44 | PROT_FIELD_SENTINEL,
45 | };
46 |
47 | static const struct protocol_buf eth_protocol_buf = {
48 | .is_dynamic = 0,
49 | .name = LUA_PACKET_SEG_ETH,
50 | .payload_field = "data",
51 | .protocol_fields = (struct protocol_field *)ð_protocol_fields,
52 | .has_protocol = ð_has_protocol,
53 | .get_field_changes = NULL,
54 | };
55 |
56 |
57 | void luaopen_protbuf_eth(lua_State *L)
58 | {
59 | register_protbuf(L, (struct protocol_buf *)ð_protocol_buf, PACKET_ETH);
60 | }
61 |
--------------------------------------------------------------------------------
/LUA/prot_buf_helpers.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010 University of Basel
3 | * by Andre Graf
4 | *
5 | * This program is free software; you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation; either version 2 of the License, or
8 | * (at your option) any later 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, see .
17 | */
18 |
19 | #if defined(__KERNEL__)
20 | #include
21 | #include /* kmalloc */
22 | #endif
23 |
24 | #include "controller.h"
25 |
26 | int32_t get_header_size(struct protocol_buf * prot_buf)
27 | {
28 | int32_t bit_counter = 0;
29 | struct protocol_field * field = prot_buf->protocol_fields;
30 |
31 | for (; field->name; field++)
32 | bit_counter += field->length;
33 |
34 | return bit_counter >> 3;
35 | }
36 |
37 |
38 | int32_t set_32_bit_generic(lua_State *L)
39 | {
40 | struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
41 | lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
42 |
43 | *(uint32_t *)(seg->start + seg->offset) = (uint32_t )htonl(luaL_checkinteger(L, 2));
44 | return 0;
45 | }
46 | int32_t get_32_bit_generic(lua_State *L)
47 | {
48 | struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
49 | lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
50 |
51 | lua_pushinteger(L, ntohl(*((uint32_t *)(seg->start + seg->offset))));
52 | return 1;
53 | }
54 |
55 | int32_t set_16_bit_generic(lua_State *L)
56 | {
57 | struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
58 | lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
59 |
60 | *(uint16_t *)(seg->start + seg->offset) = (uint16_t)htons(luaL_checkinteger(L, 2));
61 | return 0;
62 | }
63 | int32_t get_16_bit_generic(lua_State *L)
64 | {
65 | struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
66 | lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
67 |
68 | lua_pushinteger(L, ntohs(*((uint16_t *)(seg->start + seg->offset))));
69 | return 1;
70 | }
71 |
72 | int32_t set_lower_4_bit_generic(lua_State *L)
73 | {
74 | struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
75 | lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
76 | uint8_t b = (uint8_t)luaL_checkinteger(L, 2) << 4;
77 | uint8_t * pos = (uint8_t *)(seg->start + seg->offset);
78 |
79 | *pos &= 0x0F; /* reset lower 4 bits*/
80 | *pos |= b;
81 |
82 | return 0;
83 | }
84 |
85 | int32_t get_lower_4_bit_generic(lua_State *L)
86 | {
87 | struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
88 | lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
89 |
90 | lua_pushinteger(L, (*(uint8_t *)(seg->start + seg->offset)) >> 4);
91 | return 1;
92 | }
93 |
94 | int32_t set_upper_4_bit_generic(lua_State *L)
95 | {
96 | struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
97 | lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
98 | uint8_t b = (uint8_t)luaL_checkinteger(L, 2) << 4;
99 | uint8_t * pos = (uint8_t *)(seg->start + seg->offset);
100 |
101 | *pos &= 0xF0; /* reset upper 4 bits*/
102 | *pos |= (b >> 4);
103 |
104 | return 0;
105 | }
106 |
107 | int32_t get_upper_4_bit_generic(lua_State *L)
108 | {
109 | struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
110 | lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
111 |
112 | lua_pushinteger(L, (*(uint8_t *)(seg->start + seg->offset)) & 0x0F);
113 | return 1;
114 | }
115 |
116 |
117 | int32_t set_8_bit_generic(lua_State *L)
118 | {
119 | struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
120 | lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
121 |
122 | *(uint8_t *)(seg->start + seg->offset) = (uint8_t)luaL_checkinteger(L, 2);
123 | return 0;
124 | }
125 |
126 | int32_t get_8_bit_generic(lua_State *L)
127 | {
128 | struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
129 | lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
130 |
131 | lua_pushinteger(L, *(uint8_t *)(seg->start + seg->offset));
132 | return 1;
133 | }
134 |
135 | int32_t set_1_bit_generic(lua_State *L)
136 | {
137 | struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
138 | lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
139 | unsigned long l = 0;
140 |
141 | memcpy(&l, (seg->start + seg->offset), seg->length);
142 | l |= (1 << ((CHAR_BIT * seg->length) - luaL_checkinteger(L, 2)));
143 | memcpy((seg->start + seg->offset), &l, seg->length);
144 |
145 | return 0;
146 | }
147 |
148 | int32_t get_1_bit_generic(lua_State *L)
149 | {
150 | struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
151 | lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
152 | unsigned long l = 0;
153 | uint32_t bit = 0;
154 |
155 | memcpy(&l, (seg->start + seg->offset), seg->length);
156 | bit = l & (1 << ((CHAR_BIT * seg->length) - luaL_checkinteger(L, 2)));
157 |
158 | lua_pushboolean(L, bit);
159 | return 1;
160 | }
161 |
162 | int32_t get_string_generic(lua_State *L)
163 | {
164 | struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
165 | lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
166 |
167 | /* Warning we cast from uchar to char */
168 | lua_pushlstring(L, (char *)seg->start + seg->offset, seg->length);
169 | return 1;
170 | }
171 |
172 | int32_t set_data_generic(lua_State *L)
173 | {
174 | struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
175 | lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
176 | lua_packet_segment * data = checkbytearray(L, 2);
177 |
178 | pr_debug("seg->length %u, data->length %u\n", seg->length, data->length);
179 |
180 | if (seg->length >= data->length)
181 | memcpy((seg->start + seg->offset), data->start, data->length);
182 | else
183 | luaL_error(L, "provided byte array too big for given packet segment");
184 | return 0;
185 | }
186 |
187 | struct field_changes * get_allocated_field_changes(lua_State *L, int32_t nr_of_fields)
188 | {
189 | struct field_changes * changes;
190 |
191 | changes = kmalloc(sizeof(struct field_changes), GFP_ATOMIC);
192 |
193 | if (!changes)
194 | goto failure;
195 |
196 | changes->field_length_changes = kmalloc(nr_of_fields * sizeof(int), GFP_ATOMIC);
197 | if (!changes->field_length_changes)
198 | goto free1;
199 |
200 | changes->field_offset_changes = kmalloc(nr_of_fields * sizeof(int), GFP_ATOMIC);
201 | if (!changes->field_offset_changes)
202 | goto free2;
203 |
204 | memset(changes->field_length_changes, 0, nr_of_fields * sizeof(int));
205 | memset(changes->field_offset_changes, 0, nr_of_fields * sizeof(int));
206 |
207 | changes->ref_count = 1;
208 |
209 | return changes;
210 |
211 | free2: kfree(changes->field_length_changes);
212 | free1: kfree(changes);
213 | failure:
214 | if (!changes) luaL_error(L, "couldnt allocate memory inside 'get_allocated_field_changes'");
215 | return NULL; /* only to omit warnings */
216 | }
--------------------------------------------------------------------------------
/LUA/prot_buf_icmp.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010 University of Basel
3 | * by Andre Graf
4 | *
5 | * This program is free software; you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation; either version 2 of the License, or
8 | * (at your option) any later 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, see .
17 | */
18 |
19 | #include "controller.h"
20 |
21 | static int32_t icmp_has_protocol(lua_State *L, struct protocol_buf * prot_buf, lua_packet_segment * seg, int32_t protocol_type)
22 | {
23 | return 0;
24 | }
25 |
26 | static const struct protocol_field icmp_protocol_fields[] = {
27 | /* field name offset length getter setter */
28 | { "type", 0, 8, NULL, NULL },
29 | { "code", 8, 8, NULL, NULL },
30 | { "checksum", 16, 16, NULL, NULL },
31 | { "id", 32, 16, NULL, NULL },
32 | { "sequence", 48, 16, NULL, NULL },
33 | PROT_FIELD_SENTINEL,
34 | };
35 |
36 | static const struct protocol_buf icmp_protocol_buf = {
37 | .is_dynamic = 0,
38 | .name = LUA_PACKET_SEG_ICMP,
39 | .payload_field = NULL,
40 | .protocol_fields = (struct protocol_field *)&icmp_protocol_fields,
41 | .has_protocol = &icmp_has_protocol,
42 | .get_field_changes = NULL,
43 | };
44 |
45 | void luaopen_protbuf_icmp(lua_State *L)
46 | {
47 | register_protbuf(L, (struct protocol_buf *)&icmp_protocol_buf, PACKET_ICMP);
48 | }
49 |
50 |
--------------------------------------------------------------------------------
/LUA/prot_buf_ip.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010 University of Basel
3 | * by Andre Graf
4 | *
5 | * This program is free software; you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation; either version 2 of the License, or
8 | * (at your option) any later 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, see .
17 | */
18 |
19 | #if defined(__KERNEL__)
20 | #include
21 | #include
22 | #endif
23 |
24 | #include "controller.h"
25 |
26 |
27 | #define IP_FMT "%u.%u.%u.%u"
28 | #define IP_ACC(buf) buf[0], buf[1], buf[2], buf[3]
29 |
30 |
31 | static int32_t ip_version_set(lua_State *L)
32 | {
33 | uint8_t version_checked;
34 | lua_packet_segment * seg = checkpacketseg(L, 1, LUA_PACKET_SEG_IP);
35 | uint8_t *version_seg = seg->start + seg->offset;
36 | int32_t version = luaL_checkinteger(L, 2);
37 |
38 | luaL_argcheck(L, version >= 0 && version <= 15, 1, "version number invalid");
39 |
40 | version_checked = (uint8_t)version;
41 |
42 | version_seg[0] &= (uint8_t)0x0F; /* reset version bits */
43 | version_seg[0] |= version_checked << 4;
44 |
45 | return 0;
46 | }
47 | static int32_t ip_version_get(lua_State *L)
48 | {
49 | lua_packet_segment * seg = checkpacketseg(L, 1, LUA_PACKET_SEG_IP);
50 | uint8_t *version_seg = seg->start + seg->offset;
51 | uint8_t v = version_seg[0] & 0xF0;
52 |
53 | v >>= 4;
54 |
55 | lua_pushinteger(L, v);
56 | return 1;
57 | }
58 |
59 | static int32_t ip_ihl_set(lua_State *L)
60 | {
61 | uint8_t ihl_checked;
62 | lua_packet_segment * seg = checkpacketseg(L, 1, LUA_PACKET_SEG_IP);
63 | uint8_t *ihl_seg = seg->start + seg->offset;
64 | int32_t ihl = luaL_checkinteger(L, 2);
65 |
66 | luaL_argcheck(L, ihl >= 5 && ihl <= 15, 1, "ip header length invalid"); // RFC 791 5x32 = 160 bits
67 |
68 | ihl_checked = (uint8_t)ihl;
69 |
70 | ihl_seg[0] &= (uint8_t)0xF0; /* reset ihl bits */
71 | ihl_seg[0] |= ihl_checked;
72 |
73 | return 0;
74 | }
75 | static int32_t ip_ihl_get(lua_State *L)
76 | {
77 | lua_packet_segment * seg = checkpacketseg(L, 1, LUA_PACKET_SEG_IP);
78 | uint8_t *ihl_seg = seg->start + seg->offset;
79 | uint8_t v = ihl_seg[0] & 0x0F;
80 |
81 | lua_pushinteger(L, v);
82 | return 1;
83 | }
84 |
85 | static int32_t ip_addr_set(lua_State *L)
86 | {
87 | int32_t field_id = lua_tointeger(L, lua_upvalueindex(2));
88 | lua_packet_segment * seg = checkpacketseg(L, 1, LUA_PACKET_SEG_IP);
89 | uint8_t *addr_seg = seg->start + seg->offset;
90 | uint32_t old_addr;
91 | char *ip = (char *)luaL_checkstring(L, 2);
92 | uint32_t a, b, c, d;
93 | struct sk_buff * skb = (struct sk_buff *)lua_touserdata(L, 3);
94 |
95 | /* for tcp / udp checksumming*/
96 | uint32_t prot_offset;
97 | uint8_t *check, *protocol_seg;
98 |
99 | /* end */
100 |
101 | sscanf(ip, IP_FMT, &a, &b, &c, &d);
102 |
103 | luaL_argcheck(L, a < 256 && b < 256 && c < 256 && d < 256, 1, "invalid ip addr");
104 |
105 | old_addr = *((uint32_t *)addr_seg);
106 | addr_seg[0] = (uint8_t)a;
107 | addr_seg[1] = (uint8_t)b;
108 | addr_seg[2] = (uint8_t)c;
109 | addr_seg[3] = (uint8_t)d;
110 |
111 | #if defined(__KERNEL__)
112 | if (old_addr != *(uint32_t *)addr_seg) {
113 | int32_t offset = (field_id == 10) ? -2 : -6; /* offset from saddr or daddr */
114 |
115 | csum_replace4((uint16_t *)(addr_seg + offset), old_addr, *(uint32_t *)addr_seg);
116 |
117 | prot_offset = (field_id == 10) ? -3 : -7; /* offset from saddr or daddr */
118 | protocol_seg = seg->start + seg->offset + prot_offset;
119 |
120 | if (skb && (protocol_seg[0] == 0x06 || protocol_seg[0] == 0x11)) { /* is payload TCP or UDP ? */
121 |
122 | check = seg->start + seg->offset; /* tmp res */
123 | check += (field_id == 10) ? 8 : 16; /* the start of the payload, depending saddr or daddr */
124 | check += (protocol_seg[0] == 0x06) ? 16 : 6; /* the start of the checksum, depending on TCP or UDP */
125 |
126 | inet_proto_csum_replace4((__sum16 *)check, skb, old_addr, *(uint32_t *)addr_seg, 1);
127 |
128 | lua_pop(L, 1);
129 | }
130 | }
131 | #endif
132 | return 0;
133 | }
134 |
135 |
136 |
137 |
138 |
139 | static int32_t ip_addr_get(lua_State *L)
140 | {
141 | lua_packet_segment * seg = checkpacketseg(L, 1, LUA_PACKET_SEG_IP);
142 | uint8_t *addr_seg = seg->start + seg->offset;
143 |
144 | char buf[16]; /*max: 255.255.255.255\0 --> 16 chars */
145 |
146 | sprintf(buf, IP_FMT, IP_ACC(addr_seg));
147 | lua_pushstring(L, buf);
148 | return 1;
149 | }
150 |
151 | static int32_t ip_has_protocol(lua_State *L, struct protocol_buf * prot_buf, lua_packet_segment * seg, int32_t protocol_type)
152 | {
153 | uint8_t * embedded_protocol = seg->start + seg->offset + 9 /*bytes*/;
154 |
155 | switch (embedded_protocol[0]) {
156 | case 0x01: /* 1: Internet Control Message Protocol (ICMP) */
157 | if (protocol_type == PACKET_ICMP) return 1;
158 | break;
159 | case 0x02: /* 2: Internet Group Management Protocol (IGMP) */
160 | break;
161 | case 0x06: /* 6: Transmission Control Protocol (TCP) */
162 | if (protocol_type == PACKET_TCP) return 1;
163 | break;
164 | case 0x11: /* 17: User Datagram Protocol (UDP) */
165 | if (protocol_type == PACKET_UDP) return 1;
166 | break;
167 | case 0x59: /* 89: Open Shortest Path First (OSPF) */
168 | break;
169 | case 0x84: /* 132: Stream Control Transmission Protocol (SCTP) */
170 | break;
171 | default:
172 | break;
173 | }
174 |
175 | return 0;
176 | }
177 |
178 | static const struct protocol_field ip_protocol_fields[] = {
179 | /* field name offset length getter setter */
180 | { "version", 0, 4, ip_version_get, ip_version_set },
181 | { "ihl", 4, 4, ip_ihl_get, ip_ihl_set },
182 | { "tos", 8, 8, get_8_bit_generic, set_8_bit_generic },
183 | { "tot_len", 16, 16, get_16_bit_generic, set_16_bit_generic },
184 | { "id", 32, 16, get_16_bit_generic, set_16_bit_generic },
185 | { "flags", 48, 3, get_1_bit_generic, set_1_bit_generic },
186 | { "frag_off", 51, 13, NULL, NULL },
187 | { "ttl", 64, 8, get_8_bit_generic, set_8_bit_generic },
188 | { "protocol", 72, 8, get_8_bit_generic, set_8_bit_generic },
189 | { "check", 80, 16, get_16_bit_generic, set_16_bit_generic },
190 | { "saddr", 96, 32, ip_addr_get, ip_addr_set },
191 | { "daddr", 128, 32, ip_addr_get, ip_addr_set },
192 | { "data", 160, 0, NULL, set_data_generic },
193 | PROT_FIELD_SENTINEL,
194 | };
195 |
196 | static const struct protocol_buf ip_protocol_buf = {
197 | .is_dynamic = 0,
198 | .name = LUA_PACKET_SEG_IP,
199 | .payload_field = "data",
200 | .protocol_fields = (struct protocol_field *)&ip_protocol_fields,
201 | .has_protocol = &ip_has_protocol,
202 | .get_field_changes = NULL,
203 | };
204 |
205 | void luaopen_protbuf_ip(lua_State *L)
206 | {
207 | register_protbuf(L, (struct protocol_buf *)&ip_protocol_buf, PACKET_IP);
208 | }
209 |
210 |
--------------------------------------------------------------------------------
/LUA/prot_buf_raw.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010 University of Basel
3 | * by Andre Graf
4 | *
5 | * This program is free software; you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation; either version 2 of the License, or
8 | * (at your option) any later 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, see .
17 | */
18 |
19 | #include "controller.h"
20 | static int32_t raw_has_protocol(lua_State *L, struct protocol_buf * prot_buf, lua_packet_segment * seg, int32_t protocol_type)
21 | {
22 | return 1;
23 | }
24 |
25 | static const struct protocol_field raw_protocol_fields[] = {
26 | /* field name offset length getter setter */
27 | { "data", 0, 0, NULL, NULL },
28 | PROT_FIELD_SENTINEL,
29 | };
30 |
31 | static const struct protocol_buf raw_protocol_buf = {
32 | .is_dynamic = 0,
33 | .name = LUA_PACKET_SEG_RAW,
34 | .payload_field = "data",
35 | .protocol_fields = (struct protocol_field *)&raw_protocol_fields,
36 | .has_protocol = &raw_has_protocol,
37 | .get_field_changes = NULL,
38 | };
39 |
40 | void luaopen_protbuf_raw(lua_State *L)
41 | {
42 | register_protbuf(L, (struct protocol_buf *)&raw_protocol_buf, PACKET_RAW);
43 | }
44 |
--------------------------------------------------------------------------------
/LUA/prot_buf_tcp.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010 University of Basel
3 | * by Andre Graf
4 | *
5 | * This program is free software; you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation; either version 2 of the License, or
8 | * (at your option) any later 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, see .
17 | */
18 |
19 | #if defined(__KERNEL__)
20 | #include
21 | #include
22 | #endif
23 | #include "controller.h"
24 |
25 |
26 | static int32_t tcp_has_protocol(lua_State *L, struct protocol_buf * prot_buf, lua_packet_segment * seg, int32_t protocol_type)
27 | {
28 | return 1;
29 | }
30 |
31 | static int32_t tcp_set_checksum(lua_State *L)
32 | {
33 | struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
34 | lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
35 |
36 | #if defined(__KERNEL__)
37 | uint8_t * check_seg = seg->start + seg->offset;
38 | uint8_t * tcp_hdr = check_seg - 16;
39 | uint8_t * saddr = tcp_hdr - 8;
40 | uint8_t * daddr = saddr + 4;
41 | uint32_t len = 20 + (seg->changes->field_length_changes[11] / 8) + (seg->changes->field_length_changes[10] / 8);
42 | unsigned short checksum = tcp_v4_check(len, *(uint32_t *)saddr, *(uint32_t *)daddr,
43 | csum_partial(tcp_hdr, len, 0));
44 |
45 | memcpy(check_seg, &checksum, sizeof(unsigned short));
46 | #endif
47 | return 0;
48 | }
49 |
50 |
51 | static const struct protocol_field tcp_protocol_fields[] = {
52 | /* field name offset length getter setter */
53 | { "sport", 0, 16, get_16_bit_generic, set_16_bit_generic },
54 | { "dport", 16, 16, get_16_bit_generic, set_16_bit_generic },
55 | { "seq", 32, 32, get_32_bit_generic, set_32_bit_generic },
56 | { "ack", 64, 32, get_32_bit_generic, set_32_bit_generic },
57 | { "data_off", 96, 4, get_lower_4_bit_generic, set_lower_4_bit_generic },
58 | { "reserved", 100, 4, get_upper_4_bit_generic, set_upper_4_bit_generic },
59 | { "flags", 104, 8, get_1_bit_generic, set_1_bit_generic },
60 | { "window_size", 112, 16, get_16_bit_generic, set_16_bit_generic },
61 | { "check", 128, 16, get_16_bit_generic, tcp_set_checksum },
62 | { "urgent", 144, 16, NULL, NULL },
63 | { "options", 160, 0, NULL, set_data_generic },
64 | { "data", 160, 0, NULL, set_data_generic }, /* begin of data depends on options */
65 | PROT_FIELD_SENTINEL,
66 | };
67 |
68 |
69 | static const struct protocol_field tcp_options_and_data[] = {
70 | /* field name offset length getter setter */
71 | { "MSS", 0, 16, get_16_bit_generic, set_16_bit_generic },
72 | { "WS", 0, 8, get_8_bit_generic, set_8_bit_generic },
73 | { "SACK", 0, 16, get_16_bit_generic, set_16_bit_generic },
74 | { "TSVAL", 0, 32, get_32_bit_generic, set_32_bit_generic },
75 | { "TSER", 0, 32, get_32_bit_generic, set_32_bit_generic },
76 | PROT_FIELD_SENTINEL,
77 | };
78 |
79 |
80 | static struct field_changes * tcp_get_field_changes(lua_State *L, lua_packet_segment * seg);
81 |
82 | static const struct protocol_buf tcp_protocol_buf = {
83 | .is_dynamic = 0,
84 | .name = LUA_PACKET_SEG_TCP,
85 | .payload_field = "data",
86 | .protocol_fields = (struct protocol_field *)&tcp_protocol_fields,
87 | .has_protocol = &tcp_has_protocol,
88 | .get_field_changes = &tcp_get_field_changes,
89 | };
90 |
91 |
92 | static struct field_changes * tcp_options_get_field_changes(lua_State *L, lua_packet_segment * seg);
93 |
94 | static const struct protocol_buf tcp_options_and_data_buf = {
95 | .is_dynamic = 0,
96 | .name = LUA_PACKET_SEG_TCP_OPT,
97 | .payload_field = NULL,
98 | .protocol_fields = (struct protocol_field *)&tcp_options_and_data,
99 | .has_protocol = NULL,
100 | .get_field_changes = &tcp_options_get_field_changes,
101 | };
102 |
103 | struct field_changes * tcp_get_field_changes(lua_State *L, lua_packet_segment * seg)
104 | {
105 | /* depending on the value stored inside the 'data_off'-field, the length of
106 | * the 'options' field has to be changed, as well as the length and offset
107 | * of the 'data' field */
108 | uint8_t *tcp_hdr = seg->start + seg->offset;
109 |
110 | /* get the pointer to the 'data_off' field */
111 | uint8_t * data_off_field = tcp_hdr + 12; /* 12 bytes offset */
112 | /* extract the stored header length in bits */
113 | uint32_t tcp_hdr_len = ((*(uint8_t *)data_off_field) >> 4) * 32;
114 |
115 | /* get an allocated 'field_changes' structure */
116 | struct field_changes * changes = get_allocated_field_changes(L, 12);
117 |
118 | /* depending on the tcp header length, change the length of the options*/
119 | changes->field_length_changes[10] = tcp_hdr_len - 160;
120 | /* depending on the options length, change the offset of the data */
121 | changes->field_offset_changes[11] = changes->field_length_changes[10];
122 | changes->field_length_changes[11] = (seg->length * 8) - tcp_hdr_len;
123 |
124 | return changes;
125 |
126 | }
127 |
128 | struct field_changes * tcp_options_get_field_changes(lua_State *L, lua_packet_segment * seg)
129 | {
130 | /* depending on the value stored inside the 'data_off'-field, the length of
131 | * the 'options' field has to be changed, as well as the length and offset
132 | * of the 'data' field */
133 | uint8_t *tcp_opt_hdr = seg->start + seg->offset;
134 |
135 | /* get an allocated 'field_changes' structure */
136 | struct field_changes * changes = get_allocated_field_changes(L, 5);
137 |
138 | int32_t MSS = 0, WS = 0, SACK = 0, TS = 0, i;
139 |
140 | uint8_t b1, b2;
141 |
142 | for (i = 0; i < seg->length; i++) {
143 | b1 = tcp_opt_hdr[i];
144 | b2 = tcp_opt_hdr[i + 1];
145 |
146 | if (b1 == 0x00)
147 | break;
148 |
149 | /* test for MSS */
150 | if (!MSS && (b1 == 0x02 && b2 == 0x04)) {
151 | changes->field_offset_changes[0] = (i + 2) * CHAR_BIT;
152 | MSS = 1;
153 | }
154 |
155 | /* test for WS --- yet buggy somehow */
156 | if (!WS && (b1 == 0x03 && b2 == 0x03)) {
157 | changes->field_offset_changes[1] = (i + 2) * CHAR_BIT;
158 | WS = 1;
159 | }
160 |
161 | /* test for SACK*/
162 | if (!SACK && (b1 == 0x04 && b2 == 0x02)) {
163 | changes->field_offset_changes[2] = i * CHAR_BIT; /* has no value */
164 | SACK = 1;
165 | }
166 |
167 | /* test for TS */
168 | if (!TS && (b1 == 0x08 && b2 == 0x0A)) {
169 | changes->field_offset_changes[3] = (i + 2) * CHAR_BIT;
170 | changes->field_offset_changes[4] = (i + 2 + 4) * CHAR_BIT;
171 | TS = 1;
172 | }
173 | }
174 |
175 | return changes;
176 |
177 | }
178 |
179 | void luaopen_protbuf_tcp(lua_State *L)
180 | {
181 | register_protbuf(L, (struct protocol_buf *)&tcp_protocol_buf, PACKET_TCP);
182 | }
183 | void luaopen_protbuf_tcp_options(lua_State *L)
184 | {
185 | register_protbuf(L, (struct protocol_buf *)&tcp_options_and_data_buf, PACKET_TCP_OPTIONS);
186 | }
187 |
188 |
189 |
--------------------------------------------------------------------------------
/LUA/prot_buf_tftp.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010 University of Basel
3 | * by Andre Graf
4 | *
5 | * This program is free software; you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation; either version 2 of the License, or
8 | * (at your option) any later 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, see .
17 | */
18 | #include "controller.h"
19 |
20 | static const struct protocol_field tftp_protocol_fields[] = {
21 | /* field name offset length getter setter */
22 | { "opcode", 0, 16, get_16_bit_generic, NULL},
23 | { "filename", 0, 0, get_string_generic, NULL},
24 | { "mode", 0, 0, get_string_generic, NULL},
25 | { "block_nr", 0, 16, get_16_bit_generic, NULL},
26 | { "data", 0, 0, NULL, NULL},
27 | PROT_FIELD_SENTINEL,
28 | };
29 |
30 | struct field_changes * tftp_get_field_changes(lua_State *L, lua_packet_segment * seg)
31 | {
32 | /* depending on the value stored inside the 'opcode'-field we have to change
33 | * offsets and lengths */
34 | uint8_t *tftp_hdr = seg->start + seg->offset;
35 | short opcode = ntohs(*((uint16_t *)tftp_hdr));
36 | /* get an allocated 'field_changes' structure */
37 | struct field_changes * changes = get_allocated_field_changes(L, 5);
38 | switch (opcode) {
39 | case 1: /* Read Request (RRQ) */
40 | /* setting offset and length of field 'filename' */
41 | changes->field_offset_changes[1] = sizeof(unsigned short) << 3;
42 | changes->field_length_changes[1] = strlen((char *)tftp_hdr + sizeof(unsigned short)) << 3;
43 | /* setting offset and length of field 'mode' */
44 | changes->field_offset_changes[2] = changes->field_offset_changes[1] + changes->field_length_changes[1];
45 | changes->field_length_changes[2] = strlen((char *)tftp_hdr + (changes->field_offset_changes[2] >> 3));
46 | break;
47 | case 2: /* Write Request (WRQ) */
48 | /* setting offset and length of field 'filename' */
49 | changes->field_offset_changes[1] = sizeof(unsigned short) << 3;
50 | changes->field_length_changes[1] = strlen((char *)tftp_hdr + sizeof(unsigned short)) << 3;
51 | /* setting offset and length of field 'mode' */
52 | changes->field_offset_changes[2] = changes->field_offset_changes[1] + changes->field_length_changes[1];
53 | changes->field_length_changes[2] = strlen((char *)tftp_hdr + (changes->field_offset_changes[2] >> 3));
54 | break;
55 | case 3: /* Data (DATA) */
56 | /* setting offset of field 'block_nr' */
57 | changes->field_offset_changes[3] = sizeof(unsigned short) << 3;
58 | /* setting offset of field 'data' */
59 | changes->field_offset_changes[4] = changes->field_offset_changes[3] + (sizeof(unsigned short) << 3);
60 | break;
61 | case 4: /* Acknowledgment (ACK) */
62 | /* setting offset of field 'block_nr' */
63 | changes->field_offset_changes[3] = sizeof(unsigned short) << 3;
64 | break;
65 | case 5: /* Error (ERROR) */
66 | /* we don't care ... yet */
67 | break;
68 | default:
69 | break;
70 | }
71 |
72 | return changes;
73 | }
74 |
75 | static const struct protocol_buf tftp_protocol_buf = {
76 | .is_dynamic = 0,
77 | .name = LUA_PACKET_SEG_TFTP,
78 | .payload_field = NULL,
79 | .protocol_fields = (struct protocol_field *)&tftp_protocol_fields,
80 | .has_protocol = NULL, /* we don't need it, since we don't provide a payload field */
81 | .get_field_changes = tftp_get_field_changes,
82 | };
83 |
84 | void luaopen_protbuf_tftp(lua_State *L)
85 | {
86 | register_protbuf(L, (struct protocol_buf *)&tftp_protocol_buf, PACKET_TFTP);
87 | }
88 |
--------------------------------------------------------------------------------
/LUA/prot_buf_udp.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010 University of Basel
3 | * by Andre Graf
4 | *
5 | * This program is free software; you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation; either version 2 of the License, or
8 | * (at your option) any later 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, see .
17 | */
18 |
19 | #if defined(__KERNEL__)
20 | #include
21 | #endif
22 |
23 | #include "controller.h"
24 |
25 |
26 | static int32_t udp_has_protocol(lua_State *L, struct protocol_buf * prot_buf, lua_packet_segment * seg, int32_t protocol_type)
27 | {
28 | return 1;
29 | }
30 |
31 | static const struct protocol_field udp_protocol_fields[] = {
32 | /* field name offset length getter setter */
33 | { "sport", 0, 16, get_16_bit_generic, set_16_bit_generic },
34 | { "dport", 16, 16, get_16_bit_generic, set_16_bit_generic },
35 | { "length", 32, 16, get_16_bit_generic, set_16_bit_generic },
36 | { "check", 48, 16, get_16_bit_generic, set_16_bit_generic },
37 | { "data", 64, 0, NULL, NULL },
38 | PROT_FIELD_SENTINEL,
39 | };
40 |
41 | static const struct protocol_buf udp_protocol_buf = {
42 | .is_dynamic = 0,
43 | .name = LUA_PACKET_SEG_UDP,
44 | .payload_field = "data",
45 | .protocol_fields = (struct protocol_field *)&udp_protocol_fields,
46 | .has_protocol = &udp_has_protocol,
47 | .get_field_changes = NULL,
48 | };
49 |
50 | void luaopen_protbuf_udp(lua_State *L)
51 | {
52 | register_protbuf(L, (struct protocol_buf *)&udp_protocol_buf, PACKET_UDP);
53 | }
54 |
--------------------------------------------------------------------------------
/LUA/xt_LUA.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010 University of Basel
3 | * by Andre Graf
4 | *
5 | * This program is free software; you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation; either version 2 of the License, or
8 | * (at your option) any later 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, see .
17 | */
18 |
19 | #ifndef XT_LUA_H_
20 | #define XT_LUA_H_
21 |
22 | #define MAX_FILENAME_SIZE 256
23 | #define MAX_FUNCTION_SIZE 256
24 | #define MAX_SCRIPT_SIZE 32768
25 | #define LUA_STATE_ARRAY_SIZE 128
26 |
27 | /* the targetsize is stored in a u16, so max size of the xt_lua_tginfo cannot exceed 64K*/
28 | struct xt_lua_tginfo {
29 | char buf[MAX_SCRIPT_SIZE];
30 | char filename[MAX_FILENAME_SIZE];
31 | char function[MAX_FUNCTION_SIZE];
32 | __u64 script_size;
33 | __u32 state_id;
34 | };
35 |
36 | #endif /* XT_LUA_H_ */
37 |
--------------------------------------------------------------------------------
/LUA/xt_LUA.mod.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | MODULE_INFO(vermagic, VERMAGIC_STRING);
6 |
7 | struct module __this_module
8 | __attribute__((section(".gnu.linkonce.this_module"))) = {
9 | .name = KBUILD_MODNAME,
10 | .init = init_module,
11 | #ifdef CONFIG_MODULE_UNLOAD
12 | .exit = cleanup_module,
13 | #endif
14 | .arch = MODULE_ARCH_INIT,
15 | };
16 |
17 | static const struct modversion_info ____versions[]
18 | __used
19 | __attribute__((section("__versions"))) = {
20 | { 0xa3379c4b, "module_layout" },
21 | { 0x5cf97727, "xt_unregister_target" },
22 | { 0x9a1dfd65, "strpbrk" },
23 | { 0x56fb5417, "kmalloc_caches" },
24 | { 0x12da5bb2, "__kmalloc" },
25 | { 0xb85f3bbe, "pv_lock_ops" },
26 | { 0x349cba85, "strchr" },
27 | { 0xd0d8621b, "strlen" },
28 | { 0x79aa04a2, "get_random_bytes" },
29 | { 0x20000329, "simple_strtoul" },
30 | { 0x105e2727, "__tracepoint_kmalloc" },
31 | { 0xbf7e1481, "inet_proto_csum_replace4" },
32 | { 0x6c1ce5ce, "strcspn" },
33 | { 0x3c2c5af5, "sprintf" },
34 | { 0xe2d5255a, "strcmp" },
35 | { 0xe24d3a97, "jiffies_64" },
36 | { 0x2bc95bd4, "memset" },
37 | { 0x87fc9bcc, "kmem_cache_alloc_notrace" },
38 | { 0x11089ac7, "_ctype" },
39 | { 0x37befc70, "jiffies_to_msecs" },
40 | { 0x70d1f8f3, "strncat" },
41 | { 0xb72397d5, "printk" },
42 | { 0x42224298, "sscanf" },
43 | { 0x5152e605, "memcmp" },
44 | { 0xb6ed1e53, "strncpy" },
45 | { 0x1e6d26a8, "strstr" },
46 | { 0xc3fa6a59, "memchr" },
47 | { 0x61651be, "strcat" },
48 | { 0x7d8c0d13, "xt_register_target" },
49 | { 0x8ff4079b, "pv_irq_ops" },
50 | { 0x93fca811, "__get_free_pages" },
51 | { 0xf0fdf6cb, "__stack_chk_fail" },
52 | { 0xbbe2391b, "kfree_skb" },
53 | { 0xf333a2fb, "_raw_spin_lock_irq" },
54 | { 0x37a0cba, "kfree" },
55 | { 0x2e60bace, "memcpy" },
56 | { 0x59e7cb79, "skb_make_writable" },
57 | { 0xb742fd7, "simple_strtol" },
58 | { 0x7d50a24, "csum_partial" },
59 | { 0xc2d711e1, "krealloc" },
60 | { 0xe914e41e, "strcpy" },
61 | };
62 |
63 | static const char __module_depends[]
64 | __used
65 | __attribute__((section(".modinfo"))) =
66 | "depends=x_tables";
67 |
68 |
69 | MODULE_INFO(srcversion, "33A1481C4AA71D1B5A8CA8A");
70 |
--------------------------------------------------------------------------------
/LUA/xt_LUA_target.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010 University of Basel
3 | * by Andre Graf
4 | *
5 | * This program is free software; you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation; either version 2 of the License, or
8 | * (at your option) any later 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, see .
17 | */
18 |
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include "xt_LUA.h"
26 |
27 | #include "controller.h"
28 |
29 | /*::*
30 | * lua_envs
31 | * ----------
32 | * This array holds a defined number of `lua_envs`_ structures.
33 | * The used array index is also used as the Lua state identifier.
34 | * The size of the array is defined in `LUA_STATE_ARRAY_SIZE`_.
35 | */
36 | struct lua_env * lua_envs[LUA_STATE_ARRAY_SIZE];
37 |
38 | /*::*
39 | * lua_state_refs
40 | * --------------
41 | * This array holds the reference counts of the several `lua_nf_state`_s
42 | * which are stored inside the array `lua_states`_.
43 | */
44 | uint32_t lua_state_refs[LUA_STATE_ARRAY_SIZE] = { 0 };
45 |
46 | /*::*
47 | * lua_tg
48 | * ------
49 | * This function is called whenever a packet matches all matching conditions
50 | * inside a rule. It is the target. It extracts the state identifier comming
51 | * inside the *xt_target_param* structure and uses it to access the proper
52 | * Lua state inside the `lua_states`_ array.
53 | *
54 | * It then constructs a new Lua userdata of type *lua_packet_segment* and
55 | * initializes it with the lowest network header available. This userdata
56 | * is annotated with the Lua metatable `LUA_PACKET_SEG_RAW`_ which converts
57 | * the userdata to a raw lua packet having all raw functions available.
58 | * This raw packet is the single parameter to the Lua function *process_packet*
59 | * which must be defined inside the Lua script provided by the user. So far
60 | * hardcoded, may be later configured by Lua - subject to change.
61 | *
62 | * The process_packet function must return an integer value, the verdict. For
63 | * convenience reasons xt_LUA exports the verdicts NF_ACCEPT, NF_DROP and
64 | * XT_CONTINUE inside the *register_lua_packet_lib* function.
65 | */
66 |
67 | spinlock_t lock = SPIN_LOCK_UNLOCKED;
68 |
69 | static uint32_t
70 | lua_tg(struct sk_buff *pskb, const struct xt_target_param *par)
71 | {
72 | uint32_t verdict;
73 | lua_packet_segment *p;
74 | const struct xt_lua_tginfo *info = par->targinfo;
75 | lua_State * L;
76 |
77 | /* START critical section on SMP, PacketScript is on the sequential trail at the moment TODO*/
78 | spin_lock_irq(&lock);
79 |
80 | L = lua_envs[info->state_id]->L;
81 |
82 | if (!skb_make_writable(pskb, pskb->len))
83 | return NF_DROP;
84 |
85 | /* call the function provided by --function parameter or the default 'process_packet' defined in Lua */
86 | lua_getglobal(L, info->function);
87 |
88 | /* push the lua_packet_segment as a parameter */
89 | p = (lua_packet_segment *)lua_newuserdata(L, sizeof(lua_packet_segment));
90 | if (pskb->mac_header)
91 | p->start = pskb->mac_header;
92 | else if (pskb->network_header)
93 | p->start = pskb->network_header;
94 | else if (pskb->transport_header)
95 | p->start = pskb->transport_header;
96 | p->offset = 0;
97 | p->length = pskb->tail - p->start;
98 | p->changes = NULL;
99 |
100 | /* marking userdata 'lua_packet_seg' with the corresponding metatable */
101 | luaL_getmetatable(L, LUA_PACKET_SEG_RAW);
102 | lua_setmetatable(L, -2);
103 |
104 | /* push a reference to the skb as a parameter, needed at the moment for calculating TCP checksum, but I am not happy with it*/
105 | lua_pushlightuserdata(L, (void *)skb_get(pskb));
106 |
107 | /* do the function call (2 argument, 1 result) */
108 | if (lua_pcall(L, 2, 1, 0) != 0) {
109 | printk(KERN_ERR "LUA [%d]: pcall '%s' failed: %s\n", info->state_id, info->function, lua_tostring(L, -1));
110 | lua_pop(L, 1);
111 | return NF_DROP;
112 | }
113 |
114 | if (!lua_isnumber(L, -1)) {
115 | printk(KERN_ERR "LUA [%d]: function '%s' must return a verdict\n", info->state_id, info->function);
116 | lua_pop(L, 1);
117 | return NF_DROP;
118 | }
119 |
120 | verdict = lua_tonumber(L, -1);
121 | lua_pop(L, 1);
122 |
123 | kfree_skb(pskb);
124 |
125 | /* END critical section on SMP */
126 | spin_unlock_irq(&lock);
127 |
128 |
129 | return verdict;
130 |
131 | }
132 | /* Helper for checkentry */
133 | static bool load_script_into_state(uint32_t state_id, unsigned long script_size, char *script_buf)
134 | {
135 | char *buf = kmalloc(script_size, GFP_KERNEL);
136 | int32_t ret;
137 | struct lua_env * env = kmalloc(sizeof(struct lua_env), GFP_KERNEL);
138 |
139 | if (!script_size > 0) {
140 | pr_debug("LUA [%d]: script_size %lu < 0\n", state_id, script_size);
141 | return false;
142 | }
143 |
144 | env->L = lua_open();
145 | luaopen_base(env->L);
146 | luaopen_controller(env->L);
147 |
148 | lua_getglobal(env->L, "_G");
149 | lua_pushinteger(env->L, state_id);
150 | lua_setfield(env->L, -2, "STATE_ID");
151 | lua_pop(env->L, 1); /* pop _G */
152 |
153 | strncpy(buf, script_buf, script_size);
154 | ret = luaL_loadbuffer(env->L, buf, script_size, "PacketScript, loadbuffer") ||
155 | lua_pcall(env->L, 0, 1, 0);
156 |
157 | if (ret != 0) {
158 | printk(KERN_ERR "LUA [%d]: failure loading script, error %s \n", state_id, lua_tostring(env->L, -1));
159 | lua_pop(env->L, 1);
160 | kfree(buf);
161 | kfree(env);
162 | return false;
163 | }
164 |
165 | lua_envs[state_id] = env;
166 |
167 | kfree(buf);
168 |
169 | return true;
170 | }
171 | /*::*
172 | * lua_tg_checkentry
173 | * -----------------
174 | * This function is used as a kernel-side sanity check of the data comming
175 | * from the iptables userspace program. Since this is the function which is
176 | * called everytime a new rule (with -j xt_LUA) is injected, this function
177 | * is used to do the bookkeeping work, such as counting the reference of
178 | * several Lua states and the initialization of new states if needed. As an
179 | * extra initialization step it loads the provided Lua script into the Lua
180 | * state.
181 | *
182 | * Lua state initialization
183 | * ~~~~~~~~~~~~~~~~~~~~~~~~
184 | * 1. If a new rule is inserted and there is no existing state for the given
185 | * state identifier (default state identifier is 0) a new Lua state is
186 | * initialized using *lua_open*.
187 | * 2. The Lua base library is registered inside the newly initialized state.
188 | * Have a look at *lua/lbaselib.c* to see what functions of the Lua base
189 | * library are available inside Lua.
190 | * 3. The Lua packet library is registered inside the Lua state using the
191 | * function *register_lua_packet_lib*. So far this function only registers
192 | * the Netfilter verdicts NF_ACCEPT, NF_DROP and XT_CONTINUE inside the
193 | * global environment of the given Lua state.
194 | * 4. All the protocol Buffers, and the functions for accessing the bytes are
195 | * registered using *register_protocols*.
196 | *
197 | * Lua state reference counting
198 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
199 | * Bookkeeping of the Lua states inside the *lua_state_refs* array. The
200 | * state identifier is mapped to the array index, which holds an integer
201 | * counting the several initialized states.
202 | *
203 | * Loading the Lua script
204 | * ~~~~~~~~~~~~~~~~~~~~~~
205 | * Copying the buffer which was initialized by the userspace program to a
206 | * buffer with the proper size. The script is then loaded by the function
207 | * xt_LUA_loadcode, which wrapps the *luaL_loadbuffer* function and does
208 | * some workqueue initialization. So far this is done each time this function
209 | * is called, subject to change.
210 | */
211 | static bool
212 | lua_tg_checkentry(const struct xt_tgchk_param *par)
213 | {
214 | const struct xt_lua_tginfo *info = par->targinfo;
215 |
216 | if (load_script_into_state(info->state_id, info->script_size, (char *)info->buf)) {
217 | lua_state_refs[info->state_id]++;
218 | return true;
219 | }
220 | return false;
221 | }
222 |
223 | /*::*
224 | * lua_tg_destroy
225 | * --------------
226 | * This function is the counterpart of the `lua_tg_checkentry`_ function. It is
227 | * responsible to free all the resources alocated inside the checkentry process.
228 | * To be more specific it frees the Lua state using *lua_close* and kfree on all
229 | * the dynamically allocated pointers to the registered dynamic protocol buffers.
230 | *
231 | * Additionally the function cares about decrementing the reference counters
232 | * inside the array `lua_states`_.
233 | */
234 | static void
235 | lua_tg_destroy(const struct xt_tgdtor_param *par)
236 | {
237 | const struct xt_lua_tginfo *info = par->targinfo;
238 | struct lua_env * env = lua_envs[info->state_id];
239 |
240 | if (lua_state_refs[info->state_id] == 1) {
241 | lua_close(env->L);
242 | cleanup_dynamic_prot_bufs(); /* clean memory allocated by protocols defined in Lua */
243 | kfree(env);
244 | pr_debug("LUA [%d]: Rule removed, close Lua state\n", info->state_id);
245 | } else
246 | pr_debug("LUA [%d]: Rule removed, Lua state stays open, referenced %d time(s)\n",
247 | info->state_id, lua_state_refs[info->state_id] - 1);
248 |
249 | lua_state_refs[info->state_id]--;
250 | }
251 |
252 | static struct xt_target lua_tg_reg __read_mostly = {
253 | .name = "LUA",
254 | .revision = 0,
255 | .family = NFPROTO_UNSPEC,
256 | .targetsize = XT_ALIGN(sizeof(struct xt_lua_tginfo)),
257 | .target = lua_tg,
258 | .checkentry = lua_tg_checkentry,
259 | .destroy = lua_tg_destroy,
260 | .me = THIS_MODULE,
261 | };
262 |
263 |
264 | static int32_t lua_tg_init(void)
265 | {
266 | return xt_register_target(&lua_tg_reg);
267 | }
268 |
269 | static void lua_tg_exit(void)
270 | {
271 | xt_unregister_target(&lua_tg_reg);
272 | }
273 |
274 | module_init(lua_tg_init);
275 | module_exit(lua_tg_exit);
276 |
277 | MODULE_AUTHOR("Andre Graf ");
278 | MODULE_DESCRIPTION("Xtables: Processing of matched packets using the Lua scripting environment");
279 | MODULE_ALIAS("ipt_LUA");
280 | MODULE_ALIAS("ipt6t_LUA");
281 | MODULE_ALIAS("arpt_LUA");
282 | MODULE_ALIAS("ebt_LUA");
283 | MODULE_LICENSE("GPL");
284 |
285 |
286 |
287 |
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
1 | PacketScript
2 | ============
3 | PacketScript enables the scripting of Linux Netfilter extensions using the Lua scripting language. The Lua scripts are loaded with the iptables command line tool. PacketScript can be easily extended (using C or Lua) to support a wide range of networking protocols.
4 |
5 | Compilation
6 | -----------
7 | In order to compile PacketScript you must ...
8 | 1. ... install the Xtables-addons framework http://sourceforge.net/projects/xtables-addons/.
9 | 2. ... copy the LUA directory to the 'xtables-addons-1.xy/extensions' directory
10 | 3. ... add 'build_LUA=m' to the 'xtables-addons-1.xy/mconfig' file
11 | 3. ... add 'obj-${build_LUA} += LUA/' to the 'xtables-addons-1.xy/extensions/Mbuild' file
12 | 4. ... add 'obj-${build_LUA} += LUA/' to the 'xtables-addons-1.xy/extensions/Kbuild' file
13 |
14 | run configure and make in the 'xtables-addons-1.xy' directory
15 |
--------------------------------------------------------------------------------