OSDN Git Service

Fix no pic
[uclinux-h8/uClinux-dist.git] / user / ferret / netbios_dgm.c
1 /* Copyright (c) 2007 by Errata Security */\r
2 #include "protos.h"\r
3 #include "netframe.h"\r
4 #include "formats.h"\r
5 \r
6 #include <ctype.h>\r
7 #include <string.h>\r
8 \r
9 unsigned netbios_copy_name(struct NetFrame *frame, const unsigned char *px, unsigned length, unsigned offset, char *name, unsigned sizeof_name)\r
10 {\r
11         unsigned j=0;\r
12         unsigned k=0;\r
13 \r
14         name[0] = '\0';\r
15 \r
16         while (offset < length) {\r
17                 unsigned len;\r
18                 len = px[offset++];\r
19                 if (len == 0)\r
20                         break;\r
21                 if (len & 0xc0) {\r
22                         if (offset >= length) {\r
23                                 FRAMERR(frame, "netbios: name too short\n");\r
24                                 break;\r
25                         }\r
26                         len = (len << 8) || px[offset++];\r
27                         break;\r
28                 }\r
29 \r
30                 for (j=0; j<len && offset<length; j++) {\r
31                         char c = px[offset++];\r
32 \r
33                         if (c < 'A' || c > 'A'+15)\r
34                                 FRAMERR(frame, "netbios: bad netbios name char %c (0x%02x) \n", c, c);\r
35                         if (k > sizeof_name-1) {\r
36                                 FRAMERR(frame, "netbios: name too long\n");\r
37                                 break;\r
38                         }\r
39                         name[k] = (char)((c-'A')<<4);\r
40                         name[k+1] = '\0';\r
41                         j++;\r
42 \r
43                         if (offset >= length) {\r
44                                 FRAMERR(frame, "netbios: name too short\n");\r
45                                 break;\r
46                         }\r
47                         c = px[offset++];\r
48                         if (c < 'A' || c > 'A'+15)\r
49                                 FRAMERR(frame, "netbios: bad netbios name char %c (0x%02x) \n", c, c);\r
50 \r
51                         name[k] |= (char)((c-'A')&0x0F);\r
52 \r
53                         if (!isprint(name[k])) {\r
54                                 if (k+3 > sizeof_name-1) {\r
55                                         FRAMERR(frame, "netbios: name too long\n");\r
56                                         break;\r
57                                 }\r
58                                 name[k+1] = "0123456789ABCDEF"[(name[k]>>4)&0xF];\r
59                                 name[k+2] = "0123456789ABCDEF"[(name[k]>>0)&0xF];\r
60                                 name[k+3] = '>';\r
61                                 name[k+4] = '\0';\r
62                                 name[k] = '<';\r
63                                 k += 4;\r
64                         } else\r
65                                 k++;\r
66                 }\r
67         }\r
68         return offset;\r
69 }\r
70 \r
71 void process_netbios_dgm(struct Seaper *seap, struct NetFrame *frame, const unsigned char *px, unsigned length)\r
72 {\r
73         unsigned offset=0;\r
74         struct {\r
75                 unsigned type;\r
76                 unsigned flags;\r
77                 unsigned id;\r
78                 unsigned source_ip;\r
79                 unsigned source_port;\r
80                 unsigned length;\r
81                 unsigned offset;\r
82                 char source[70];\r
83                 char destination[70];\r
84         } netbios;\r
85 \r
86         if (length == 0) {\r
87                 FRAMERR(frame, "netbios: frame empty\n");\r
88                 return;\r
89         }\r
90         if (length < 10) {\r
91                 FRAMERR(frame, "netbios: frame too short\n");\r
92                 return;\r
93         }\r
94 \r
95         if (px[0] != 0x11) {\r
96                 FRAMERR(frame, "netbios: unknown type %d\n", px[0]);\r
97                 return;\r
98         }\r
99 \r
100         netbios.type = px[0];\r
101         netbios.flags = px[1];\r
102         netbios.id = ex16be(px+2);\r
103         netbios.source_ip = ex32be(px+4);\r
104         netbios.source_port = ex16be(px+8);\r
105         netbios.length = ex16be(px+10);\r
106         netbios.offset = ex16be(px+12);\r
107 \r
108         offset = 14;\r
109 \r
110         offset = netbios_copy_name(frame, px, length, offset, netbios.source, sizeof(netbios.source));\r
111         offset = netbios_copy_name(frame, px, length, offset, netbios.destination, sizeof(netbios.destination));\r
112 \r
113         frame->netbios_source = netbios.source;\r
114         frame->netbios_destination = netbios.destination;\r
115 \r
116         offset += netbios.offset;\r
117 \r
118         if (offset > length) {\r
119                 FRAMERR(frame, "netbios: not enough data\n");\r
120                 return;\r
121         }\r
122 \r
123         if (offset > 4 && memcmp(px+offset, "\xFFSMB", 4) == 0)\r
124                 process_smb_dgm(seap, frame, px+offset, length-offset);\r
125         else {\r
126                 FRAMERR(frame, "netbios: unknown netbios datagram\n");\r
127                 return;\r
128         }\r
129 }\r
130 \r