1 /*
2  ** yafscii.c
3  ** YAF flow printer
4  **
5  ** ------------------------------------------------------------------------
6  ** Copyright (C) 2006-2015 Carnegie Mellon University. All Rights Reserved.
7  ** ------------------------------------------------------------------------
8  ** Authors: Brian Trammell
9  ** ------------------------------------------------------------------------
10  ** @OPENSOURCE_HEADER_START@
11  ** Use of the YAF system and related source code is subject to the terms
12  ** of the following licenses:
13  **
14  ** GNU Public License (GPL) Rights pursuant to Version 2, June 1991
15  ** Government Purpose License Rights (GPLR) pursuant to DFARS 252.227.7013
16  **
17  ** NO WARRANTY
18  **
19  ** ANY INFORMATION, MATERIALS, SERVICES, INTELLECTUAL PROPERTY OR OTHER
20  ** PROPERTY OR RIGHTS GRANTED OR PROVIDED BY CARNEGIE MELLON UNIVERSITY
21  ** PURSUANT TO THIS LICENSE (HEREINAFTER THE "DELIVERABLES") ARE ON AN
22  ** "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
23  ** KIND, EITHER EXPRESS OR IMPLIED AS TO ANY MATTER INCLUDING, BUT NOT
24  ** LIMITED TO, WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE,
25  ** MERCHANTABILITY, INFORMATIONAL CONTENT, NONINFRINGEMENT, OR ERROR-FREE
26  ** OPERATION. CARNEGIE MELLON UNIVERSITY SHALL NOT BE LIABLE FOR INDIRECT,
27  ** SPECIAL OR CONSEQUENTIAL DAMAGES, SUCH AS LOSS OF PROFITS OR INABILITY
28  ** TO USE SAID INTELLECTUAL PROPERTY, UNDER THIS LICENSE, REGARDLESS OF
29  ** WHETHER SUCH PARTY WAS AWARE OF THE POSSIBILITY OF SUCH DAMAGES.
30  ** LICENSEE AGREES THAT IT WILL NOT MAKE ANY WARRANTY ON BEHALF OF
31  ** CARNEGIE MELLON UNIVERSITY, EXPRESS OR IMPLIED, TO ANY PERSON
32  ** CONCERNING THE APPLICATION OF OR THE RESULTS TO BE OBTAINED WITH THE
33  ** DELIVERABLES UNDER THIS LICENSE.
34  **
35  ** Licensee hereby agrees to defend, indemnify, and hold harmless Carnegie
36  ** Mellon University, its trustees, officers, employees, and agents from
37  ** all claims or demands made against them (and any related losses,
38  ** expenses, or attorney's fees) arising out of, or relating to Licensee's
39  ** and/or its sub licensees' negligent use or willful misuse of or
40  ** negligent conduct or willful misconduct regarding the Software,
41  ** facilities, or other rights or assistance granted by Carnegie Mellon
42  ** University under this License, including, but not limited to, any
43  ** claims of product liability, personal injury, death, damage to
44  ** property, or violation of any laws or regulations.
45  **
46  ** Carnegie Mellon University Software Engineering Institute authored
47  ** documents are sponsored by the U.S. Department of Defense under
48  ** Contract FA8721-05-C-0003. Carnegie Mellon University retains
49  ** copyrights in all material produced under this contract. The U.S.
50  ** Government retains a non-exclusive, royalty-free license to publish or
51  ** reproduce these documents, or allow others to do so, for U.S.
52  ** Government purposes only pursuant to the copyright license under the
53  ** contract clause at 252.227.7013.
54  **
55  ** @OPENSOURCE_HEADER_END@
56  ** ------------------------------------------------------------------------
57  */
58 
59 #define _YAF_SOURCE_
60 #include <yaf/autoinc.h>
61 #include <airframe/mio.h>
62 #include <airframe/mio_config.h>
63 #include <airframe/mio_source_file.h>
64 #include <airframe/mio_sink_file.h>
65 #include <airframe/logconfig.h>
66 #include <airframe/daeconfig.h>
67 #include <airframe/airutil.h>
68 #include <airframe/privconfig.h>
69 #include <yaf/yafcore.h>
70 
71 typedef struct ytContext_st {
72     fBuf_t          *fbuf;
73     yfFlow_t        flow;
74 } ytContext_t;
75 
76 static uint32_t     yaft_flows = 0;
77 
78 static gboolean     yaft_tabular = FALSE;
79 static gboolean     yaft_mac = FALSE;
80 static gboolean     yaft_first = TRUE;
81 static gboolean     yaft_print_header = FALSE;
82 
83 static uint32_t     yaft_cliflags = MIO_F_CLI_FILE_IN |
84                                     MIO_F_CLI_DIR_IN |
85                                     MIO_F_CLI_DEF_STDIN |
86                                     MIO_F_CLI_FILE_OUT |
87                                     MIO_F_CLI_DIR_OUT |
88                                     MIO_F_CLI_DEF_STDOUT;
89 
90 AirOptionEntry yaft_optentries[] = {
91     AF_OPTION( "tabular", (char)0, 0, AF_OPT_TYPE_NONE, &yaft_tabular,
92       "Print flows in tabular format", NULL ),
93     AF_OPTION( "mac", (char)0, 0, AF_OPT_TYPE_NONE, &yaft_mac,
94                "Print mac addresses (when used with --tabular)", NULL ),
95     AF_OPTION( "print-header", (char)0, 0, AF_OPT_TYPE_NONE, &yaft_print_header,
96                "Print column headers for tabular format", NULL),
97     AF_OPTION_END
98 };
99 
ytParseOptions(int * argc,char ** argv[])100 static void ytParseOptions(
101     int             *argc,
102     char            **argv[]) {
103 
104     AirOptionCtx *aoctx = NULL;
105 
106     aoctx = air_option_context_new("", argc, argv, yaft_optentries);
107 
108     mio_add_option_group(aoctx, yaft_cliflags);
109     daec_add_option_group(aoctx);
110     privc_add_option_group(aoctx);
111     logc_add_option_group(aoctx, "yafscii", VERSION);
112 
113     air_option_context_set_help_enabled(aoctx);
114 
115     air_option_context_parse(aoctx);
116     if (yaft_mac && !yaft_tabular) {
117         g_warning("--mac requires --tabular");
118     }
119     if (yaft_print_header && !yaft_tabular) {
120         g_warning("--print-header requires --tabular");
121     }
122 
123     air_option_context_free(aoctx);
124 }
125 
ytOpenSource(MIOSource * source,void * vctx,uint32_t * flags,GError ** err)126 static gboolean ytOpenSource(
127     MIOSource               *source,
128     void                    *vctx,
129     uint32_t                *flags,
130     GError                  **err)
131 {
132     ytContext_t          *yx = (ytContext_t *)vctx;
133 
134     /* start reading a YAF file */
135     if (!(yx->fbuf = yfReaderForFP(yx->fbuf, mio_fp(source), err))) {
136         *flags |= MIO_F_CTL_SOURCECLOSE;
137         if (g_error_matches(*err, FB_ERROR_DOMAIN, FB_ERROR_EOF)) {
138             g_clear_error(err);
139         } else {
140             *flags |= MIO_F_CTL_ERROR;
141         }
142         return FALSE;
143     }
144 
145     return TRUE;
146 }
147 
ytProcess(MIOSource * source,MIOSink * sink,void * vctx,uint32_t * flags,GError ** err)148 static gboolean ytProcess(
149     MIOSource               *source,
150     MIOSink                 *sink,
151     void                    *vctx,
152     uint32_t                *flags,
153     GError                  **err)
154 {
155     ytContext_t          *yx = (ytContext_t *)vctx;
156     gboolean                ok;
157 
158     /* Print first line column headers if tabular */
159     if (yaft_tabular && yaft_first && yaft_print_header) {
160         yfPrintColumnHeaders(mio_fp(sink), yaft_mac, err);
161         yaft_first = FALSE;
162     }
163 
164     /* read a flow */
165     if ((ok = yfReadFlowExtended(yx->fbuf, &(yx->flow), err))) {
166         ++yaft_flows;
167         if (yaft_tabular) {
168             ok = yfPrintDelimited(mio_fp(sink), &(yx->flow), yaft_mac, err);
169         } else {
170             ok = yfPrint(mio_fp(sink), &(yx->flow), err);
171         }
172     }
173 
174     /* handle error */
175     if (!ok) {
176         /* check for EOF */
177         if (g_error_matches(*err, FB_ERROR_DOMAIN, FB_ERROR_EOF)) {
178             g_clear_error(err);
179             *flags |= MIO_F_CTL_SOURCECLOSE;
180             ok = TRUE;
181         } else {
182             /* die on actual error */
183             *flags |= MIO_F_CTL_ERROR;
184         }
185     }
186 
187     return ok;
188 }
189 
190 
main(int argc,char * argv[])191 int main (
192     int                 argc,
193     char                *argv[]) {
194 
195     GError              *err = NULL;
196     ytContext_t         yx;
197     MIOSource           source;
198     MIOSink             sink;
199     MIOAppDriver        adrv;
200     uint32_t            miodflags;
201     int                 rv = 0;
202 
203     /* parse options */
204     ytParseOptions(&argc, &argv);
205 
206     /* check to make sure the data structures are sane */
207     yfAlignmentCheck();
208 
209     /* set up logging */
210     if (!logc_setup(&err)) {
211         air_opterr("%s", err->message);
212     }
213 
214     /* fork if necessary */
215     if (!daec_setup(&err)) {
216         air_opterr("%s", err->message);
217     }
218 
219     /* initialize MIO option flags */
220     miodflags = MIO_F_OPT_SINKLINK;
221 
222     if (!mio_config_source(&source, yaft_cliflags, &miodflags, &err)) {
223         air_opterr("Cannot set up input: %s", err->message);
224     }
225 
226     /* set up sink */
227     if (!mio_config_sink(&source, &sink, "%s.yaf.txt", yaft_cliflags,
228                          &miodflags, &err)) {
229         air_opterr("Cannot set up output: %s", err->message);
230     }
231 
232     /* initialize yafscii context */
233     yfFlowPrepare(&(yx.flow));
234     yx.fbuf = NULL;
235 
236     /* set up an app driver */
237     adrv.app_open_source = ytOpenSource;
238     adrv.app_open_sink = NULL;
239     adrv.app_close_source = NULL;
240     adrv.app_close_sink = NULL;
241     adrv.app_process = ytProcess;
242 
243     /* run dispatch loop */
244     if (!mio_dispatch_loop(&source, &sink, &adrv, &yx, miodflags, mio_ov_poll,
245                            1, mio_ov_poll))
246     {
247         rv = 1;
248     }
249 
250     if (yx.fbuf) {
251         fBufFree(yx.fbuf);
252     }
253 
254     g_message("yafscii terminating with %d flows read", yaft_flows);
255 
256     return rv;
257 }
258