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>
6 ** Copyright (C) 2011, Kacper Wysocki <kacper.wysocki@redpill-linpro.com>
8 ** This program is free software; you can redistribute it and/or modify
9 ** it under the terms of the GNU General Public License as published by
10 ** the Free Software Foundation; either version 2 of the License, or
11 ** (at your option) any later version.
13 ** This program is distributed in the hope that it will be useful,
14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ** GNU General Public License for more details.
18 ** You should have received a copy of the GNU General Public License
19 ** along with this program; if not, write to the Free Software
20 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 /* ip,vlan,port,proto,(ASSET DETECTION),FP/MAC,distance,uptime,timstamp */
27 /* I N C L U D E S *********************************************************/
29 #include "../config.h"
30 #include "../sys_func.h"
38 output_plugin p_file
= {
39 .init
= &init_output_log_file
,
42 .service
= &file_service
,
43 .denit
= &end_output_log_file
,
46 output_plugin
*init_log_file ()
51 /* ----------------------------------------------------------
52 * FUNCTION : init_output_log_file
53 * DESC : This function initialize the output file.
54 * : If the file already exists, it will read in the
55 * : file and add each asset to the asset data structure.
56 * INPUT : 0 - CSV filename
58 * --------------------------------------------------------- */
59 int init_output_log_file (output_plugin
*log
, const char *file
, int flags
)
62 const char *mode
= MODE_READ
;
64 /* Make sure filename isn't NULL. */
71 /* Check to see if *filename exists. */
73 if ((fp
= fopen(log
->path
, mode
)) == NULL
) {
79 /* retry in current working directory */
81 if(flags
& CONFIG_VERBOSE
)
82 elog("%s denied opening asset log '%s'", strerror(e
), log
->path
);
85 log
->path
= PRADS_ASSETLOG
;
92 if(flags
& CONFIG_VERBOSE
)
93 elog("Cannot open file %s: %s!", log
->path
, strerror(errno
));
98 log
->data
= (void *) fp
;
101 /* File did not exist, create new.. */
102 fprintf(fp
, "asset,vlan,port,proto,service,[service-info],distance,discovered\n");
104 /* File does exist, read it into data structure. */
106 // read_report_file();
108 /* Open file and assign it to the global FILE pointer. */
109 if ((log
->data
= (void *) fopen(log
->path
, "a")) == NULL
) {
111 if(flags
& CONFIG_VERBOSE
)
112 printf("Cannot open log file %s for append!\n", log
->path
);
120 /* ----------------------------------------------------------
121 * FUNCTION : read_report_file
122 * DESC : This function will read in a specified
123 * : report CSV file. It will then break a part
124 * : the line and add the assets to the
125 * : specified asset data structure.
128 * ---------------------------------------------------------- */
130 read_report_file (output_plugin
*log
)
134 struct bstrList
*lines
;
137 printf("[*] Processing Assets from persistent file %s\n", log
->path
);
139 /* Open Signature File */
140 if ((fp
= fopen(log
->path
, "r")) == NULL
) {
141 printf("Unable to open CSV file - %s", log
->path
);
144 /* Read file into 'filedata' and process it accordingly. */
145 filedata
= bread ((bNread
) fread
, fp
);
146 if ((lines
= bsplit(filedata
, '\n')) != NULL
) {
147 for (i
= 0; i
< lines
->qty
; i
++) {
148 parse_raw_report(lines
->entry
[i
]);
154 bstrListDestroy(lines
);
158 /* ----------------------------------------------------------
159 * FUNCTION : parse_raw_report
160 * DESC : This function will parse through a single
161 * : line of the CSV file.
162 * INPUT : 0 - Raw Line
163 * RETURN : 0 - Sucess
165 * ---------------------------------------------------------- */
166 int parse_raw_report (bstring line
)
168 struct bstrList
*list
;
171 /* Temporary Storage */
172 struct in_addr ip_addr
;
173 //char mac_addr[MAC_ADDR_LEN];
180 /* Check to see if this line has something to read. */
181 if (line
->data
[0] == '\0' || line
->data
[0] == '#')
184 /* Break line apart. */
185 if ((list
= bsplit(line
, ',')) == NULL
)
188 /* Check to see if this line contains the header. */
189 if ((biseqcstr(list
->entry
[0], "asset")) == 1) {
191 bstrListDestroy(list
);
195 /* Place data from 'list' into temporary data storage. */
196 if ((inet_aton(bdata(list
->entry
[0]), &ip_addr
)) == -1)
199 if ((port
= htons(atoi(bdata(list
->entry
[1])))) == -1)
202 if ((proto
= atoi(bdata(list
->entry
[2]))) == -1)
205 if ((service
= bstrcpy(list
->entry
[3])) == NULL
)
208 if ((application
= bstrcpy(list
->entry
[4])) == NULL
)
211 if ((discovered
= atol(bdata(list
->entry
[5]))) == -1)
214 /* Make sure that this line contains 'good' data. */
215 if (service
->slen
== 0 || application
->slen
== 0 || discovered
<= 0)
218 /* Add Asset to Data Structure */
219 if (proto
== 0 && ret
!= -1) {
221 //mac2hex(bdata(application), mac_addr, MAC_ADDR_LEN);
222 //add_arp_asset(ip_addr, mac_addr, discovered);
224 /* Everything Else */
225 //add_asset(ip_addr, port, proto, service, application, discovered);
230 bstrListDestroy(list
);
233 if (application
!= NULL
)
234 bdestroy(application
);
239 /* ----------------------------------------------------------
240 * FUNCTION : file_arp
241 * DESC : This function prints an ARP asset to the log file
242 * INPUT : 0 - Main asset
244 * ---------------------------------------------------------- */
245 void file_arp (output_plugin
*log
, asset
*main
)
247 /* ip,vlan,port,proto,ARP (mac-resolved),mac-address,timstamp*/
248 static char ip_addr_s
[INET6_ADDRSTRLEN
];
249 if ((FILE*)log
->data
== NULL
) {
250 if(log
->flags
& CONFIG_VERBOSE
)
251 elog("[!] ERROR: File handle not open!\n");
254 u_ntop(main
->ip_addr
, main
->af
, ip_addr_s
);
255 if (main
->macentry
!= NULL
) {
256 /* ip,0,0,ARP (mac-resolved),mac-address,timstamp */
257 /* XXX: vendor info breaks csv niceness */
258 fprintf((FILE*)log
->data
, "%s,%u,0,0,ARP,[%s,(%s)],0,%lu\n", ip_addr_s
,
259 main
->vlan
? ntohs(main
->vlan
) : 0, hex2mac(main
->mac_addr
),
260 main
->macentry
->vendor
, main
->last_seen
);
262 /* ip,0,0,ARP,mac-address,timstamp */
263 fprintf((FILE*)log
->data
, "%s,%u,0,0,ARP,[%s],0,%lu\n", ip_addr_s
,
264 main
->vlan
? ntohs(main
->vlan
) : 0,hex2mac(main
->mac_addr
), main
->last_seen
);
266 fflush((FILE*)log
->data
);
269 /* ----------------------------------------------------------
270 * FUNCTION : file_service
271 * DESC : Prints a service asset to the log file.
272 * INPUT : 0 - Main asset
274 * ---------------------------------------------------------- */
276 file_service (output_plugin
* log
,asset
*main
, serv_asset
*service
, connection
*cxt
)
278 if ((FILE*)log
->data
!= NULL
) {
280 static char ip_addr_s
[INET6_ADDRSTRLEN
];
281 u_ntop(main
->ip_addr
, main
->af
, ip_addr_s
);
282 /* ip,vlan,port,proto,SERVICE,application,timstamp*/
283 fprintf((FILE*)log
->data
, "%s,%u,%d,%d,",
284 ip_addr_s
, main
->vlan
? ntohs(main
->vlan
) : 0,
285 ntohs(service
->port
),service
->proto
);
286 if (service
->role
== SC_SERVER
) {
287 fprintf((FILE*)log
->data
, "SERVER,[%s:%s]",
288 (char*)bdata(service
->service
),
289 (char *)bdata(service
->application
));
291 fprintf((FILE*)log
->data
, "CLIENT,[%s:%s]",
292 (char*)bdata(service
->service
),
293 (char*)bdata(service
->application
));
296 tmp_ttl
= normalize_ttl(service
->ttl
);
297 fprintf((FILE*)log
->data
, ",%d,%lu\n",tmp_ttl
- service
->ttl
,service
->last_seen
);
298 fflush((FILE*)log
->data
);
300 if(log
->flags
& CONFIG_VERBOSE
)
301 elog("[!] ERROR: File handle not open!\n");
305 /* ----------------------------------------------------------
307 * DESC : Prints a os asset to the log file.
308 * INPUT : 0 - Main asset
311 * ---------------------------------------------------------- */
313 file_os (output_plugin
*log
, asset
*main
, os_asset
*os
, connection
*cxt
)
315 static char ip_addr_s
[INET6_ADDRSTRLEN
];
321 if(log
->data
== NULL
){
322 if(log
->flags
& CONFIG_VERBOSE
)
323 elog("[!] ERROR: File handle not open: %s!\n", log
->path
);
327 u_ntop(main
->ip_addr
, main
->af
, ip_addr_s
);
329 /* ip,vlan,port,proto,OS-FP,FP,timstamp*/
330 fprintf((FILE*)log
->data
, "%s,%u,%d,", ip_addr_s
,
331 main
->vlan
? ntohs(main
->vlan
) : 0, os
->port
);
332 //ntohs(main->port),service->proto);
334 switch (os
->detection
) {
336 fprintf((FILE*)log
->data
, "6,SYN");
339 fprintf((FILE*)log
->data
, "6,SYNACK");
342 fprintf((FILE*)log
->data
, "6,ACK");
345 fprintf((FILE*)log
->data
, "6,RST");
348 fprintf((FILE*)log
->data
, "6,FIN");
351 fprintf((FILE*)log
->data
, "17,UDP");
355 fprintf((FILE*)log
->data
, "1,ICMP");
358 fprintf((FILE*)log
->data
, "17,DHCP");
362 "[!] error in detection type %d (isn't implemented!)\n", os
->detection
);
365 if (os
->raw_fp
!= NULL
) {
366 fprintf((FILE*)log
->data
, ",[%s:", (char *)bdata(os
->raw_fp
));
368 //bstring b = gen_fp_tcp(&os->fp, os->fp.zero_stamp, 0);
369 bstring b
= gen_fp_tcp(&os
->fp
, os
->uptime
, 0);
371 fprintf((FILE*)log
->data
, ",[%s:", (char *)bdata(os
->raw_fp
));
373 if (os
->fp
.os
!= NULL
) fprintf((FILE*)log
->data
,"%s", os
->fp
.os
);
374 else fprintf((FILE*)log
->data
, "unknown");
375 if (os
->fp
.desc
!= NULL
) fprintf((FILE*)log
->data
, ":%s", os
->fp
.desc
);
376 else fprintf((FILE*)log
->data
, ":unknown");
378 if (os
->fp
.mss
) fprintf((FILE*)log
->data
, ":link:%s",lookup_link(os
->fp
.mss
,1));
379 if (os
->uptime
) fprintf((FILE*)log
->data
, ":uptime:%dhrs",os
->uptime
/360000);
381 tmp_ttl
= normalize_ttl(os
->ttl
);
382 fprintf((FILE*)log
->data
, "],%d,%lu\n",tmp_ttl
- os
->ttl
, os
->last_seen
);
383 fflush((FILE*)log
->data
);
386 /* ----------------------------------------------------------
387 * FUNCTION : end_output_log_file
388 * DESC : This function will free the memory declared
389 * : for the log_file output.
390 * INPUT : output plugin
392 * ---------------------------------------------------------- */
393 int end_output_log_file (output_plugin
* log
)
395 dlog("[*] Closing asset log.\n");
397 if (log
->data
!= NULL
)
398 fclose((FILE*)log
->data
);