Example #1
0
static void ExportExtensionMaps( int aggregate, int bidir, nffile_t *nffile, extension_map_list_t *extension_map_list ) {
int map_id, opt_extensions, num_extensions, new_map_size, opt_align;
extension_map_t	*new_map;

	// no extension maps to export - nothing to do
	if ( extension_map_list->map_list == NULL )
		return;

	new_map = NULL;

	for ( map_id = 0; map_id <= extension_map_list->max_used; map_id++ ) {
		extension_map_t *SourceMap = extension_map_list->slot[map_id]->map;
		int i, has_aggr_flows, has_out_bytes, has_out_packets, has_nat;
		// skip maps, never referenced

#ifdef DEVEL
		printf("Process map id: %i\n", map_id);
		printf("Ref count: %i\n", extension_map_list->slot[map_id]->ref_count);
#endif

		if ( extension_map_list->slot[map_id]->ref_count == 0 ) {
#ifdef DEVEL
			printf("Ref count = 0 => Skip map\n");
#endif
			continue;
		}

		// parse Source map if it contains all required fields:
		// for aggregation EX_AGGR_FLOWS_4 or _8 is required
		// for bidir flows EX_OUT_PKG_4 or _8 and EX_OUT_BYTES_4 or_8 are required
		has_aggr_flows  = 0;
		has_out_bytes	= 0;
		has_out_packets	= 0;
		// parse map for older NEL nat extension
		has_nat			= 0;

		num_extensions = 0;
		i = 0;
		while ( SourceMap->ex_id[i] ) {
			switch (SourceMap->ex_id[i]) {
				case EX_AGGR_FLOWS_4:
				case EX_AGGR_FLOWS_8:
					has_aggr_flows  = 1;
					break;
				case EX_OUT_BYTES_4:
				case EX_OUT_BYTES_8:
					has_out_bytes	= 1;
					break;
				case EX_OUT_PKG_4:
				case EX_OUT_PKG_8:
					has_out_packets	= 1;
					break;
				case EX_NEL_GLOBAL_IP_v4:
					// Map old nat extension to common NSEL extension
					SourceMap->ex_id[i] = EX_NSEL_XLATE_IP_v4;
					has_nat	= 1;
				// default: nothing to do
			}
			i++;
			num_extensions++;
		}
#ifdef DEVEL
		printf("map: num_extensions: %i, has_aggr_flows: %i, has_out_bytes: %i, has_out_packets: %i, has_nat: %i\n", 
			num_extensions, has_aggr_flows, has_out_bytes, has_out_packets, has_nat);
#endif

		// count missing extensions
		opt_extensions = 0;
		if ( aggregate && !has_aggr_flows )
			opt_extensions++;

		if ( bidir && !has_out_bytes ) 
			opt_extensions++;

		if ( bidir && !has_out_packets ) 
			opt_extensions++;

		opt_extensions += has_nat;
		// calculate new map size
		new_map_size = sizeof(extension_map_t) + ( num_extensions + opt_extensions) * sizeof(uint16_t);

#ifdef DEVEL
		printf("opt_extensions: %i, new_map_size: %i\n", opt_extensions,new_map_size );
		PrintExtensionMap(SourceMap);
#endif
		if ( opt_extensions ) {
    		// align 32bits
    		if (( new_map_size & 0x3 ) != 0 ) {
        		new_map_size += 4 - ( new_map_size & 0x3 );
				opt_align = 1;
    		} else {
				opt_align = 0;
			}
		} else {
			// no missing elements in extension map - we can used the original one
			// and we are done

#ifdef DEVEL
			printf("New map identical => use this map:\n");
			PrintExtensionMap(SourceMap);
#endif
			// Flush the map to disk
			AppendToBuffer(nffile, (void *)SourceMap, SourceMap->size);
			continue;
		}

#ifdef DEVEL
		printf("Create new map:\n");
#endif
		// new map is different - create the new map
		new_map = (extension_map_t *)malloc((ssize_t)new_map_size);
		if ( !new_map ) {
			LogError("malloc() error in %s line %d: %s\n", __FILE__, __LINE__, strerror(errno) );
			exit(255);
		}

		// Panic check - should never happen, but we are going to copy memory
		if ( new_map_size < SourceMap->size ) {
			LogError("PANIC! new_map_size(%i) < SourceMap->size(%i) in %s line %d\n", 
				new_map_size, SourceMap->size,  __FILE__, __LINE__);
			exit(255);
		}
		// copy existing map
		memcpy((void *)new_map, (void *)SourceMap, SourceMap->size);
		
		new_map->size   = new_map_size;

		// add the missing extensions to the output map
		// skip to end of current map
		while ( new_map->ex_id[i] )
			i++;

		if ( has_nat ) {
			new_map->ex_id[i++] 	 = EX_NSEL_XLATE_PORTS;
			new_map->extension_size += extension_descriptor[EX_NSEL_XLATE_PORTS].size;
		}
		// add missing map elements
		if ( aggregate && !has_aggr_flows ) {
			new_map->ex_id[i++] 	 = EX_AGGR_FLOWS_4;
			new_map->extension_size += extension_descriptor[EX_AGGR_FLOWS_4].size;
		}
		if ( bidir && !has_out_bytes )  {
			new_map->ex_id[i++] 	 = EX_OUT_BYTES_8;
			new_map->extension_size += extension_descriptor[EX_OUT_BYTES_8].size;
		}
		if ( bidir && !has_out_packets )  {
			new_map->ex_id[i++] 	 = EX_OUT_PKG_8;
			new_map->extension_size += extension_descriptor[EX_OUT_PKG_8].size;
		}
		// end of map tag
		new_map->ex_id[i++]    = 0;
		if ( opt_align )
			new_map->ex_id[i]  = 0;

#ifdef DEVEL
		PrintExtensionMap(new_map);
#endif

		free(extension_map_list->slot[map_id]->map);
		extension_map_list->slot[map_id]->map = new_map; 

		// Flush the map to disk
		AppendToBuffer(nffile, (void *)new_map, new_map->size);

	}

} // End of ExportExtensionMaps
Example #2
0
File: nfx.c Project: icsecurity/fan
int
Insert_Extension_Map (extension_map_list_t * extension_map_list,
		      extension_map_t * map)
{
  uint32_t next_free = extension_map_list->next_free;
  uint16_t map_id;

  map_id = map->map_id == INIT_ID ? 0 : map->map_id & EXTENSION_MAP_MASK;
  map->map_id = map_id;
  dbg_printf ("Insert Extension Map:\n");
#ifdef DEVEL
  PrintExtensionMap (map);
#endif
  // is this slot free
  if (extension_map_list->slot[map_id])
    {
      int i, map_found;
      dbg_printf ("Map %d already exists\n", map_id);
      // no - check if same map already in slot
      if (extension_map_list->slot[map_id]->map->size == map->size)
	{
	  // existing map and new map have the same size 
	  dbg_printf ("New map same size:\n");

	  // we must compare the maps
	  i = 0;
	  while (extension_map_list->slot[map_id]->map->ex_id[i]
		 && (extension_map_list->slot[map_id]->map->ex_id[i] ==
		     map->ex_id[i]))
	    i++;

	  // if last entry == 0 => last map entry => maps are the same
	  if (extension_map_list->slot[map_id]->map->ex_id[i] == 0)
	    {
	      dbg_printf ("Same map => nothing to do\n");
	      // same map
	      return 0;
	    }
	  dbg_printf ("Different map => continue\n");
	}

      dbg_printf ("Search for map in extension page\n");
      map_found = -1;
      // new map is different but has same id - search for map in page list
      for (i = 0; i < next_free; i++)
	{
	  int j;
	  j = 0;
	  if (extension_map_list->page[i]->map->size == map->size)
	    {
	      while (extension_map_list->page[i]->map->ex_id[j]
		     && (extension_map_list->page[i]->map->ex_id[j] ==
			 map->ex_id[j]))
		j++;
	    }
	  if (extension_map_list->page[i]->map->ex_id[j] == 0)
	    {
	      dbg_printf ("Map found in page slot %i\n", i);
	      map_found = i;
	    }
	}
      if (map_found >= 0)
	{
	  extension_info_t *tmp;
	  dbg_printf ("Move map from page slot %i to slot %i\n", map_found,
		      map_id);

	  // exchange the two maps
	  tmp = extension_map_list->slot[map_id];
	  extension_map_list->slot[map_id] =
	    extension_map_list->page[map_found];
	  extension_map_list->slot[map_id]->map->map_id = map_id;

	  extension_map_list->page[map_found] = tmp;
	  extension_map_list->page[map_found]->map->map_id = map_found;
	  return 1;

	}
      else
	{
	  dbg_printf ("Map not found in extension page\n");
	  // map not found - move it to the extension page to a currently free slot
	  if (next_free < MAX_EXTENSION_MAPS)
	    {
	      dbg_printf ("Move existing map from slot %d to page slot %d\n",
			  map_id, next_free);
	      extension_map_list->page[next_free] =
		extension_map_list->slot[map_id];
	      extension_map_list->page[next_free]->map->map_id = next_free;
	      extension_map_list->slot[map_id] = NULL;
	      // ready to fill new slot
	    }
	  else
	    {
	      fprintf (stderr,
		       "Extension map list exhausted - too many extension maps ( > %d ) to process;\n",
		       MAX_EXTENSION_MAPS);
	      exit (255);
	    }
	}
    }

  FixExtensionMap (map);

  // add new entry to slot
  extension_map_list->slot[map_id] =
    (extension_info_t *) calloc (1, sizeof (extension_info_t));
  if (!extension_map_list->slot[map_id])
    {
      fprintf (stderr, "calloc() error in %s line %d: %s\n", __FILE__,
	       __LINE__, strerror (errno));
      exit (255);
    }
  extension_map_list->slot[map_id]->map =
    (extension_map_t *) malloc ((ssize_t) map->size);
  if (!extension_map_list->slot[map_id]->map)
    {
      fprintf (stderr, "malloc() error in %s line %d: %s\n", __FILE__,
	       __LINE__, strerror (errno));
      exit (255);
    }
  memcpy ((void *) extension_map_list->slot[map->map_id]->map, (void *) map,
	  map->size);

  extension_map_list->slot[map_id]->ref_count = 0;

  if (map_id > extension_map_list->max_used)
    {
      extension_map_list->max_used = map_id;
    }

  // Update next_free page slot, if it's used now
  while (extension_map_list->page[next_free]
	 && (next_free < MAX_EXTENSION_MAPS))
    next_free++;
  extension_map_list->next_free = next_free;

  // if all slots are exhausted next_free is now MAX_EXTENSION_MAPS. The next time an empty slot is needed, it will properly fail.
  dbg_printf ("Installed map in slot %d. Next free page slot: %d\n", map_id,
	      next_free);

  //map changed
  return 1;

}				// End of Insert_Extension_Map
Example #3
0
int main(int argc, char **argv) {
struct ftio ftio;
extension_info_t *extension_info;
struct stat statbuf;
uint32_t	limitflows;
int i, extended, printmap, ret, fd, compress;;
char   *ftfile, *wfile;

	/* init fterr */
	fterr_setid(argv[0]);

	extended 	= 0;
	printmap 	= 0;
	limitflows 	= 0;
	ftfile   	= NULL;
	wfile		= "-";
	compress 	= NOT_COMPRESSED;

	while ((i = getopt(argc, argv, "jzEVc:hmr:w:?")) != -1)
		switch (i) {
			case 'h': /* help */
				case '?':
				usage(argv[0]);
				exit (0);
				break;
		
			case 'V':
				printf("%s: Version: %s\n",argv[0], nfdump_version);
				exit(0);
				break;

			case 'E':
				extended = 1;
				break;
		
			case 'c':	
				limitflows = atoi(optarg);
				if ( !limitflows ) {
					fprintf(stderr, "Option -c needs a number > 0\n");
					exit(255);
				}
				break;

			case 'm':
				printmap = 1;
				break;

			case 'j':
				compress = LZO_COMPRESSED;
				break;

			case 'z':
				compress = BZ2_COMPRESSED;
				break;

			case 'r':
				ftfile = optarg;
				if ( (stat(ftfile, &statbuf) < 0 ) || !(statbuf.st_mode & S_IFREG) ) {
					fprintf(stderr, "No such file: '%s'\n", ftfile);
					exit(255);
				}
				break;

			case 'w':
				wfile = optarg;
				break;
		
			default:
				usage(argv[0]);
				exit (1);
				break;
	
		} /* switch */
	// End while

	if (argc - optind)
	fterr_errx(1, "Extra arguments starting with %s.", argv[optind]);
	
	if ( ftfile ) {
		fd = open(ftfile, O_RDONLY, 0);
		if ( fd < 0 ) {
			fprintf(stderr, "Can't open file '%s': %s.", ftfile, strerror(errno));
			exit(255);
		}
	} else {
		fd = 0;
	}

	/* read from fd */
	if (ftio_init(&ftio, fd, FT_IO_FLAG_READ) < 0)
		fterr_errx(1, "ftio_init(): failed");

	extension_info = GenExtensionMap(&ftio);
	if ( !extension_info ) 
		exit(255);

	if ( printmap ) {
		PrintExtensionMap(extension_info->map);
		exit(255);
	} 

	ret = flows2nfdump(&ftio, wfile, compress, extension_info, extended, limitflows);

	return ret;

} // End of main