2 ** This file is a part of PRADS.
4 ** Copyright (C) 2009, Redpill Linpro
5 ** Copyright (C) 2009, Edward Fjellskål <edward.fjellskaal@redpill-linpro.com>
7 ** This program is free software; you can redistribute it and/or modify
8 ** it under the terms of the GNU General Public License as published by
9 ** the Free Software Foundation; either version 2 of the License, or
10 ** (at your option) any later version.
12 ** This program is distributed in the hope that it will be useful,
13 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ** GNU General Public License for more details.
17 ** You should have received a copy of the GNU General Public License
18 ** along with this program; if not, write to the Free Software
19 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 /* ip,vlan,port,proto,(ASSET DETECTION),FP/MAC,distance,uptime,timstamp */
27 log_file_conf output_log_file_conf
;
29 /* ----------------------------------------------------------
30 * FUNCTION : init_output_log_file
31 * DESC : This function initialize the output file.
32 * : If the file already exists, it will read in the
33 * : file and add each asset to the asset data structure.
34 * INPUT : 0 - CSV filename
36 * --------------------------------------------------------- */
37 int init_output_log_file (bstring filename
)
43 /* Make sure filename isn't NULL. */
45 output_log_file_conf
.filename
= bstrcpy(filename
);
47 output_log_file_conf
.filename
= bfromcstr(PRADS_ASSETLOG
);
49 /* Check to see if *filename exists. */
51 if ((fp
= fopen(bdata(output_log_file_conf
.filename
), mode
)) == NULL
) {
57 /* retry in current working directory */
59 elog("%s denied opening access log '%s'", strerror(e
), bdata(output_log_file_conf
.filename
));
62 bdestroy(output_log_file_conf
.filename
);
63 output_log_file_conf
.filename
= bfromcstr(PRADS_ASSETLOG
);
70 elog("Cannot open file %s: %s!", bdata(output_log_file_conf
.filename
), strerror(errno
));
75 fp
= output_log_file_conf
.file
= fp
;
77 if (mode
== MODE_WRITE
){
78 /* File did not exist, create new.. */
79 fprintf(output_log_file_conf
.file
, "asset,vlan,port,proto,service,[service-info],distance,discovered\n");
81 /* File does exist, read it into data structure. */
83 // read_report_file();
85 /* Open file and assign it to the global FILE pointer. */
86 if ((output_log_file_conf
.file
= fopen(bdata(output_log_file_conf
.filename
), "a")) == NULL
) {
87 printf("Cannot open log file %s for append!\n", bdata(output_log_file_conf
.filename
));
94 /* ----------------------------------------------------------
95 * FUNCTION : read_report_file
96 * DESC : This function will read in a specified
97 * : report CSV file. It will then break a part
98 * : the line and add the assets to the
99 * : specified asset data structure.
102 * ---------------------------------------------------------- */
104 read_report_file (void)
108 struct bstrList
*lines
;
111 printf("[*] Processing Assets from persistent file %s\n", bdata(output_log_file_conf
.filename
));
113 /* Open Signature File */
114 if ((fp
= fopen(bdata(output_log_file_conf
.filename
), "r")) == NULL
) {
115 printf("Unable to open CSV file - %s", bdata(output_log_file_conf
.filename
));
118 /* Read file into 'filedata' and process it accordingly. */
119 filedata
= bread ((bNread
) fread
, fp
);
120 if ((lines
= bsplit(filedata
, '\n')) != NULL
) {
121 for (i
= 0; i
< lines
->qty
; i
++) {
122 parse_raw_report(lines
->entry
[i
]);
128 bstrListDestroy(lines
);
132 /* ----------------------------------------------------------
133 * FUNCTION : parse_raw_report
134 * DESC : This function will parse through a single
135 * : line of the CSV file.
136 * INPUT : 0 - Raw Line
137 * RETURN : 0 - Sucess
139 * ---------------------------------------------------------- */
140 int parse_raw_report (bstring line
)
142 struct bstrList
*list
;
145 /* Temporary Storage */
146 struct in_addr ip_addr
;
147 //char mac_addr[MAC_ADDR_LEN];
154 /* Check to see if this line has something to read. */
155 if (line
->data
[0] == '\0' || line
->data
[0] == '#')
158 /* Break line apart. */
159 if ((list
= bsplit(line
, ',')) == NULL
)
162 /* Check to see if this line contains the header. */
163 if ((biseqcstr(list
->entry
[0], "asset")) == 1) {
165 bstrListDestroy(list
);
169 /* Place data from 'list' into temporary data storage. */
170 if ((inet_aton(bdata(list
->entry
[0]), &ip_addr
)) == -1)
173 if ((port
= htons(atoi(bdata(list
->entry
[1])))) == -1)
176 if ((proto
= atoi(bdata(list
->entry
[2]))) == -1)
179 if ((service
= bstrcpy(list
->entry
[3])) == NULL
)
182 if ((application
= bstrcpy(list
->entry
[4])) == NULL
)
185 if ((discovered
= atol(bdata(list
->entry
[5]))) == -1)
188 /* Make sure that this line contains 'good' data. */
189 if (service
->slen
== 0 || application
->slen
== 0 || discovered
<= 0)
192 /* Add Asset to Data Structure */
193 if (proto
== 0 && ret
!= -1) {
195 //mac2hex(bdata(application), mac_addr, MAC_ADDR_LEN);
196 //add_arp_asset(ip_addr, mac_addr, discovered);
198 /* Everything Else */
199 //add_asset(ip_addr, port, proto, service, application, discovered);
204 bstrListDestroy(list
);
207 if (application
!= NULL
)
208 bdestroy(application
);
213 /* ----------------------------------------------------------
214 * FUNCTION : file_arp
215 * DESC : This function prints an ARP asset to the log file
216 * INPUT : 0 - Main asset
218 * ---------------------------------------------------------- */
219 void file_arp (asset
*main
)
221 /* ip,vlan,port,proto,ARP (mac-resolved),mac-address,timstamp*/
222 static char ip_addr_s
[INET6_ADDRSTRLEN
];
223 if (output_log_file_conf
.file
== NULL
) {
224 elog("[!] ERROR: File handle not open!\n");
227 u_ntop(main
->ip_addr
, main
->af
, ip_addr_s
);
228 if (main
->mac_resolved
!= NULL
) {
229 /* ip,0,0,ARP (mac-resolved),mac-address,timstamp */
230 fprintf(output_log_file_conf
.file
, "%s,%u,0,0,ARP (%s),%s,0,%lu\n", ip_addr_s
,
231 main
->vlan
? ntohs(main
->vlan
) : 0,bdata(main
->mac_resolved
),
232 hex2mac((const char *)main
->mac_addr
), main
->last_seen
);
234 /* ip,0,0,ARP,mac-address,timstamp */
235 fprintf(output_log_file_conf
.file
, "%s,%u,0,0,ARP,[%s],0,%lu\n", ip_addr_s
,
236 main
->vlan
? ntohs(main
->vlan
) : 0,hex2mac((const char *)main
->mac_addr
), main
->last_seen
);
238 fflush(output_log_file_conf
.file
);
241 /* ----------------------------------------------------------
242 * FUNCTION : file_service
243 * DESC : Prints a service asset to the log file.
244 * INPUT : 0 - Main asset
246 * ---------------------------------------------------------- */
248 file_service (asset
*main
, serv_asset
*service
)
250 if (output_log_file_conf
.file
!= NULL
) {
252 static char ip_addr_s
[INET6_ADDRSTRLEN
];
253 u_ntop(main
->ip_addr
, main
->af
, ip_addr_s
);
254 /* ip,vlan,port,proto,SERVICE,application,timstamp*/
255 fprintf(output_log_file_conf
.file
, "%s,%u,%d,%d,",
256 ip_addr_s
, main
->vlan
? ntohs(main
->vlan
) : 0,
257 ntohs(service
->port
),service
->proto
);
258 if (service
->role
== 1) {
259 fprintf(output_log_file_conf
.file
, "SERVER,[%s:%s]",
260 (char*)bdata(service
->service
),
261 (char *)bdata(service
->application
));
263 fprintf(output_log_file_conf
.file
, "CLIENT,[%s:%s]",
264 (char*)bdata(service
->service
),
265 (char*)bdata(service
->application
));
268 tmp_ttl
= normalize_ttl(service
->ttl
);
269 fprintf(output_log_file_conf
.file
, ",%d,%lu\n",tmp_ttl
- service
->ttl
,service
->last_seen
);
270 fflush(output_log_file_conf
.file
);
272 elog("[!] ERROR: File handle not open!\n");
276 /* ----------------------------------------------------------
278 * DESC : Prints a os asset to the log file.
279 * INPUT : 0 - Main asset
282 * ---------------------------------------------------------- */
284 file_os (asset
*main
, os_asset
*os
)
286 static char ip_addr_s
[INET6_ADDRSTRLEN
];
289 if (output_log_file_conf
.file
== NULL
) {
290 elog("[!] ERROR: File handle not open!\n");
295 u_ntop(main
->ip_addr
, main
->af
, ip_addr_s
);
297 /* ip,vlan,port,proto,OS-FP,FP,timstamp*/
298 fprintf(output_log_file_conf
.file
, "%s,%u,%d,", ip_addr_s
,
299 main
->vlan
? ntohs(main
->vlan
) : 0, os
->port
);
300 //ntohs(main->port),service->proto);
302 switch (os
->detection
) {
304 fprintf(output_log_file_conf
.file
, "6,SYN");
307 fprintf(output_log_file_conf
.file
, "6,SYNACK");
310 fprintf(output_log_file_conf
.file
, "6,ACK");
313 fprintf(output_log_file_conf
.file
, "6,RST");
316 fprintf(output_log_file_conf
.file
, "6,FIN");
319 fprintf(output_log_file_conf
.file
, "17,UDP");
323 fprintf(output_log_file_conf
.file
, "1,ICMP");
328 "[!] error in detection type %d (isn't implemented!)\n", os
->detection
);
331 if (os
->raw_fp
!= NULL
) {
332 fprintf(output_log_file_conf
.file
, ",[%s:", (char *)bdata(os
->raw_fp
));
334 //bstring b = gen_fp_tcp(&os->fp, os->fp.zero_stamp, 0);
335 bstring b
= gen_fp_tcp(&os
->fp
, os
->uptime
, 0);
337 fprintf(output_log_file_conf
.file
, ",[%s:", (char *)bdata(os
->raw_fp
));
339 if (os
->fp
.os
!= NULL
) fprintf(output_log_file_conf
.file
,"%s", os
->fp
.os
);
340 else fprintf(output_log_file_conf
.file
, "unknown");
341 if (os
->fp
.desc
!= NULL
) fprintf(output_log_file_conf
.file
, ":%s", os
->fp
.desc
);
342 else fprintf(output_log_file_conf
.file
, ":unknown");
344 if (os
->fp
.mss
) fprintf(output_log_file_conf
.file
, ":link:%s",lookup_link(os
->fp
.mss
,1));
345 if (os
->uptime
) fprintf(output_log_file_conf
.file
, ":uptime:%dhrs",os
->uptime
/360000);
347 tmp_ttl
= normalize_ttl(os
->ttl
);
348 fprintf(output_log_file_conf
.file
, "],%d,%lu\n",tmp_ttl
- os
->ttl
, os
->last_seen
);
349 fflush(output_log_file_conf
.file
);
352 /* ----------------------------------------------------------
353 * FUNCTION : end_output_log_file
354 * DESC : This function will free the memory declared
355 * : for the log_file output.
358 * ---------------------------------------------------------- */
359 int end_output_log_file ()
361 printf("\n[*] Closing log file.");
363 if (output_log_file_conf
.file
!= NULL
)
364 fclose(output_log_file_conf
.file
);
366 if (output_log_file_conf
.filename
!= NULL
)
367 bdestroy(output_log_file_conf
.filename
);