Esempio n. 1
0
void RotateFile (pcapfile_t *pcapfile, time_t t_CloseRename, int live)
{
	struct pcap_stat p_stat;
	void *_b;

	dbg_printf ("RotateFile() time: %s\n", UNIX2ISO (t_CloseRename));
	// make sure, alternate buffer is already flushed
	pthread_mutex_lock (&pcapfile->m_pbuff);
	while (pcapfile->alternate_size) {
		pthread_cond_wait (&pcapfile->c_pbuff, &pcapfile->m_pbuff);
	}

	// swap buffers
	_b = pcapfile->data_buffer;
	pcapfile->data_buffer = pcapfile->alternate_buffer;
	pcapfile->data_ptr = pcapfile->data_buffer;
	pcapfile->alternate_buffer = _b;
	pcapfile->alternate_size = pcapfile->data_size;
	pcapfile->t_CloseRename = t_CloseRename;

	// release mutex and signal thread
	pthread_mutex_unlock (&pcapfile->m_pbuff);
	pthread_cond_signal (&pcapfile->c_pbuff);

	pcapfile->data_size = 0;

	if (live) {
		// not a capture file
		if (pcap_stats (pcapfile->p, &p_stat) < 0) {
			LogError ("pcap_stats() failed: %s", pcap_geterr (pcapfile->p));
		} else {
			LogInfo ("Packets received: %u, dropped: %u, dropped by interface: %u ",
			         p_stat.ps_recv, p_stat.ps_drop, p_stat.ps_ifdrop);
		}
	}

} // End of RotateFile
void CompiledFilterOutput::compileFilter()
{
    struct bpf_program fcode;

    foreach (QString interfaces, intList_) {
        for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
            interface_t device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);

            if (interfaces.compare(device.display_name)) {
                continue;
            } else {
                pcap_t *pd = pcap_open_dead(device.active_dlt, WTAP_MAX_PACKET_SIZE);
                g_mutex_lock(pcap_compile_mtx);
                if (pcap_compile(pd, &fcode, compile_filter_.toUtf8().constData(), 1, 0) < 0) {
                    compile_results.insert(interfaces, QString("%1").arg(g_strdup(pcap_geterr(pd))));
                    g_mutex_unlock(pcap_compile_mtx);
                    ui->interfaceList->addItem(new QListWidgetItem(QIcon(":expert/expert_error.png"),interfaces));
                } else {
                    GString *bpf_code_dump = g_string_new("");
                    struct bpf_insn *insn = fcode.bf_insns;
                    int ii, n = fcode.bf_len;
                    gchar *bpf_code_str;
                    for (ii = 0; ii < n; ++insn, ++ii) {
                        g_string_append(bpf_code_dump, bpf_image(insn, ii));
                        g_string_append(bpf_code_dump, "\n");
                    }
                    bpf_code_str = g_string_free(bpf_code_dump, FALSE);
                    g_mutex_unlock(pcap_compile_mtx);
                    compile_results.insert(interfaces, QString("%1").arg(g_strdup(bpf_code_str)));
                    ui->interfaceList->addItem(new QListWidgetItem(interfaces));
                }
                break;
            }
        }
    }
}
Esempio n. 3
0
int main(int argc, char** argv)
{       
    char *dev, *error_openoffline, *fname, *gen_error;
    pcap_t *desc;//declaring the decsriptor 
    pcap_dumper_t   *pd;
    struct pcap_pkthdr *header;//declaring packet header
    u_char *sp;//packet data written to savefile    

    dev="eth1";//setting the device as eth1
    fname=argv[1];

    desc=pcap_open_offline( fname, error_openoffline );
    if( desc == NULL )
    {
        printf("The session could not open as %s", error_openoffline );         
        exit(1);
    }

    pd=pcap_dump_open( desc, fname );
    if( pd == NULL )
    {       gen_error=pcap_geterr( desc );
        printf( "\nThe dump could not be opened as %s", gen_error );
        exit(1);        
    }

    pcap_dump( (u_char *) pd, header, sp);

    printf("\nThe data is %h", sp );
    printf("\nThe data is %s", sp );

    pcap_dump_close( pd );
    pcap_close( desc );

    return 0;

}
Esempio n. 4
0
void load_plugin_filters(int link_type)
{
  struct plugins_list_entry *list = plugins_list;

  while (list) {
    if ((*list->type.func)) {

      /* compiling aggregation filter if needed */
      if (list->cfg.a_filter) {
	pcap_t *dev_desc;
	bpf_u_int32 localnet, netmask = 0;  /* pcap library stuff */
	char errbuf[PCAP_ERRBUF_SIZE], *count_token;
	int idx = 0;

	dev_desc = pcap_open_dead(link_type, 128); /* 128 bytes should be long enough */

	if (config.dev) pcap_lookupnet(config.dev, &localnet, &netmask, errbuf);

	list->cfg.bpfp_a_table[idx] = malloc(sizeof(struct bpf_program));
	while ( (count_token = extract_token(&list->cfg.a_filter, ',')) && idx < AGG_FILTER_ENTRIES ) {
	  if (pcap_compile(dev_desc, list->cfg.bpfp_a_table[idx], count_token, 0, netmask) < 0) {
	    Log(LOG_WARNING, "WARN: %s\nWARN ( %s/%s ): aggregation filter disabled.\n",
	    				pcap_geterr(dev_desc), list->cfg.name, list->cfg.type);
	  }
	  else {
	    idx++;
	    list->cfg.bpfp_a_table[idx] = malloc(sizeof(struct bpf_program));
	  }
	}

	list->cfg.bpfp_a_num = idx;
      }
    }
    list = list->next;
  }
}
Esempio n. 5
0
static PyObject *ppcap_set_snaplen(ppcap *self,
                                   PyObject *args)
{
    int snaplen;
    int retval;

    if (!PyArg_ParseTuple(args, "i", &snaplen))
        return NULL;
    if (!ppcap_isset_handle(self->handle)) {
        PyErr_SetString(PyExc_Ppcap, "pcap handle is not created");
        return NULL;
    }
    if (snaplen < MIN_SNAPLEN) {
        PyErr_Format(PyExc_Ppcap, "snaplen must be >= %d",
                     MIN_SNAPLEN);
        return NULL;
    }
    retval = pcap_set_snaplen(self->handle, snaplen);
    if (retval == PCAP_ERROR_ACTIVATED) {
        PyErr_Format(PyExc_Ppcap, "%s", pcap_geterr(self->handle));
        return NULL;
    }
    Py_RETURN_NONE;
}
//------------------------------------------------------------------------------
tOplkError edrv_sendTxBuffer(tEdrvTxBuffer* pBuffer_p)
{
    int         pcapRet;

    // Check parameter validity
    ASSERT(pBuffer_p != NULL);

    //TRACE("%s: TxB=%p (%02X), last TxB=%p\n", __func__, pBuffer_p, (UINT)pBuffer_p->pBuffer[5], edrvInstance_l.pTransmittedTxBufferLastEntry);

    if (pBuffer_p->txBufferNumber.pArg != NULL)
        return kErrorInvalidOperation;

    EnterCriticalSection(&edrvInstance_l.criticalSection);
    if (edrvInstance_l.pTransmittedTxBufferLastEntry == NULL)
    {
        edrvInstance_l.pTransmittedTxBufferLastEntry =
            edrvInstance_l.pTransmittedTxBufferFirstEntry = pBuffer_p;
    }
    else
    {
        edrvInstance_l.pTransmittedTxBufferLastEntry->txBufferNumber.pArg = pBuffer_p;
        edrvInstance_l.pTransmittedTxBufferLastEntry = pBuffer_p;
    }
    LeaveCriticalSection(&edrvInstance_l.criticalSection);

    pcapRet = pcap_sendpacket(edrvInstance_l.pPcap, pBuffer_p->pBuffer,
                              (int)pBuffer_p->txFrameSize);
    if (pcapRet != 0)
    {
        DEBUG_LVL_EDRV_TRACE("%s() pcap_sendpacket returned %d (%s)\n",
                             __func__, pcapRet, pcap_geterr(edrvInstance_l.pPcap));
        return kErrorInvalidOperation;
    }

    return kErrorOk;
}
Esempio n. 7
0
static int output_inject_process(void *obj, struct packet *p, struct proto_process_stack *s, unsigned int stack_index) {

	struct output_inject_priv *priv = obj;

	struct proto_process_stack *stack = &s[stack_index];

 	size_t len = stack->plen;
	if (len > 1500)
		len = 1500;

	int bytes = pcap_inject(priv->p, stack->pload, len);

	if (bytes == -1) {
		pomlog(POMLOG_ERR "Error while injecting packet : %s", pcap_geterr(priv->p));
		return POM_ERR;
	}

	registry_perf_inc(priv->perf_pkts_out, 1);
	registry_perf_inc(priv->perf_bytes_out, stack->plen);


	return POM_OK;

}
Esempio n. 8
0
int  main(int argc, char const *argv[])
{
	char ebuf[PCAP_ERRBUF_SIZE];
	pcap_t *pd;
	if (argc<=1){
		printf("usage :%s <network interface>\n", argv[0]);
		return 0;
	}

	if ((pd=pcap_open_live(argv[1],DEFAULT_SNAPLEN,1,1000,ebuf))==NULL)
	{
		(void)fprintf(stderr, "1:%s\n", ebuf);
	}

	if (pcap_loop(pd,-1,packet_print,NULL)<0)
	{
		(void)fprintf(stderr, "2:pcap_loop: %s\n", pcap_geterr(pd));
	}

	pcap_close(pd);


	return 0;
}
Esempio n. 9
0
static PyObject*
bpf_compile(PyObject* self, PyObject* args)
{
  int linktype;
  int  snaplen;
  char *filter;
  int optimize;
  unsigned int netmask;

  if(!PyArg_ParseTuple(args,
		       "iispI:compile",
		       &linktype,
		       &snaplen,
		       &filter,
		       &optimize,
		       &netmask))
    return NULL;

  pcap_t *pp;

  pp = pcap_open_dead(linktype, snaplen);
  if(pp == NULL)
    return NULL;

  struct bpf_program bpf;
  int status = pcap_compile(pp, &bpf, filter, optimize, netmask);
  pcap_close(pp);

  if(status)
    {
      PyErr_SetString(PcapError, pcap_geterr(pp));
      return NULL;
    }

  return new_bpfobject( &bpf );
}
Esempio n. 10
0
static int pcaprr_daq_acquire(
    void *handle, int cnt, DAQ_Analysis_Func_t callback, void *user)
{
    Pcaprr_Context_t *context = (Pcaprr_Context_t *) handle;
    int ret, i;
    pcap_t *thandle;

    context->analysis_func = callback;
    context->user_data = user;

    context->packets = 0;
    while (context->packets < cnt || cnt <= 0)
    {
	for (i = 0 ; i < context->handle_count ; i++) {
		thandle = context->handle[i];

	        ret = pcap_dispatch(
        	    thandle, cnt-context->packets, pcap_process_loop, (void *) context);

/* fprintf(stderr, "dispatch %d %d %d\n", i, cnt, ret); */
	        if (ret == -1)
	        {
	            DPE(context->errbuf, "%s", pcap_geterr(thandle));
	            return ret;
	        }
	        /* In read-file mode, PCAP returns 0 when it hits the end of the file. */
	        else if (context->file && ret == 0)
	            return DAQ_READFILE_EOF;
	        /* If we hit a breakloop call or timed out without reading any packets, break out. */
	        else if (ret == -2 || ret == 0)
	            break;
	    }
    }

    return 0;
}
Esempio n. 11
0
/* Print packet capture statistics */
void print_stats() {
        struct pcap_stat pkt_stats;
        float run_time;

        if (pcap_hnd && !use_infile) {
                if (pcap_stats(pcap_hnd, &pkt_stats) != 0) {
                        WARN("Cannot obtain packet capture statistics: %s", pcap_geterr(pcap_hnd));
                        return;
                }

                LOG_PRINT("%d packets received, %d packets dropped, %d http packets parsed", \
                     pkt_stats.ps_recv, pkt_stats.ps_drop, num_parsed);

                run_time = (float) (time(0) - start_time);
                if (run_time > 0) {
                        LOG_PRINT("%0.1f packets/min, %0.1f http packets/min", \
                             ((pkt_stats.ps_recv * 60) / run_time), ((num_parsed * 60) / run_time));
                }
        } else if (pcap_hnd) {
                PRINT("%d http packets parsed", num_parsed);
        }

        return;
}
Esempio n. 12
0
	int	PcapWrapper::sendPacket(int adapter_id, unsigned char* packet_buffer, int buffer_size) {
	#ifdef WIN32
		if (!checkForAdapterId(adapter_id)) {
			// specified adapter not found
			RETURN_CODE(RC(ADAPTER_NOT_FOUND));
		}
		pcap_t*	handle = NULL;
		if (static_cast<int>(m_adapter_handles.size()) > adapter_id) {
			handle = m_adapter_handles[adapter_id];
		}
		if (!handle) {
			fprintf(stderr, "Error: retrievePacket() called on unopened adapter.\n");
			RETURN_CODE(RC(ACCESS_ON_UNOPENED_HANDLE));
		}
		if (pcap_sendpacket(handle, packet_buffer, buffer_size ) < 0) {
			fprintf(stderr, "Error: Failed to send the given packet: \n", pcap_geterr(handle));
			RETURN_CODE(RC(UNSPECIFIED_ERROR_OCCURED));
		}
		RETURN_CODE(RC(NORMAL_EXECUTION));
	#else
		fprintf(stderr, "Error: Wrong function called. pcap_sendpacket(...) only works with WinPcap.\n");
		RETURN_CODE(RC(UNSPECIFIED_ERROR_OCCURED));
	#endif
	}
Esempio n. 13
0
int main(int argc, char *argv[]) {

   int ch, fromfile, setfilter, version, drop_privs_flag, daemon_flag, chroot_flag;
   char *bpff, errbuf[PCAP_ERRBUF_SIZE];
   extern char *optarg;
   char roll_metric = 0;
   char roll_type = GIGABYTES;
   size_t roll_point = 2;
   roll_size = roll_point * GIGABYTE;

   int long_option_index = 0;
   static struct option long_options[] = {
     {"help", 0, NULL, '?'},
     {"interface", 1, NULL, 'i'},
     {"format", 1, NULL, 'f'},
     {"bpf", 1, NULL, 'b'},
     {"log-dir", 1, NULL, 'd'},
     {"daemonize", 0, NULL, 'D'},
     {"user", 1, NULL, 'u'},
     {"group", 1, NULL, 'g'},
     {"chroot-dir", 1, NULL, 'T'},
     {"pid-file", 1, NULL, 'p'},
     {"pcap-file", 1, NULL, 'r'},
     {0, 0, 0, 0}
   };


   bpf_u_int32 net_mask = 0;
   ch = fromfile = setfilter = version = drop_privs_flag = daemon_flag = 0;
   dev = "eth0";
   bpff = "";
   chroot_dir = "/tmp/";
   output_format = "sguil";
   cxtbuffer = NULL;
   cxtrackerid  = 0;
   dump_with_flush = inpacket = intr_flag = chroot_flag = 0;
   mode = 0;

   signal(SIGTERM, game_over);
   signal(SIGINT,  game_over);
   signal(SIGQUIT, game_over);
   signal(SIGHUP,  dump_active);
   signal(SIGALRM, set_end_sessions);

   while( (ch=getopt_long(argc, argv, "?b:d:DT:f:g:i:p:P:r:u:vw:s:t:", long_options, &long_option_index)) != EOF )
     switch (ch) {
      case 'i':
         dev = strdup(optarg);
         mode |= MODE_DEV;
         break;
      case 'b':
         bpff = strdup(optarg);
         break;
      case 'v':
         verbose = 1;
         break;
      case 'f':
         output_format = strdup(optarg);
         break;
      case 'd':
         snprintf(dpath, STDBUF, "%s", optarg);

         // normalise the directory path to ensure it's slash terminated
         if( dpath[strlen(dpath)-1] != '/' )
            strncat(dpath, "/", STDBUF);
         break;
      case '?':
         usage(argv[0]);
         exit_clean(0);
         break;
      case 'D':
         daemon_flag = 1;
         break;
      case 'T':
         chroot_flag = 1;
         break;
      case 'u':
         user_name = strdup(optarg);
         drop_privs_flag = 1;
         break;
      case 'g':
         group_name = strdup(optarg);
         drop_privs_flag = 1;
         break;
      case 'p':
         pidfile = strdup(optarg);
         break;
      case 'P':
         pidpath = strdup(optarg);
         break;
      case 'r':
         read_file = strdup(optarg);
         mode |= MODE_FILE;
         dev = NULL;
         break;
      case 'w':
         dump_file_prefix = strdup(optarg);
         mode |= MODE_DUMP;
         break;
      case 'F':
         dump_with_flush = 1;
         break;
      case 's':
         sscanf(optarg, "%zu%c", &roll_point, &roll_metric);

         switch( tolower(roll_metric) ) {
            case 'k':
               roll_size = roll_point * KILOBYTE;
               roll_type = KILOBYTES;
               break;
            case 'm':
               roll_size = roll_point * MEGABYTE;
               roll_type = MEGABYTES;
               break;
            case 'g':
               roll_size = roll_point * GIGABYTE;
               roll_type = GIGABYTES;
               break;
            case 't':
               roll_size = roll_point * TERABYTE;
               roll_type = TERABYTES;
               break;
            default:
               printf("[*] Invalid size metric: %c\n", roll_metric ? roll_metric : '-');
               break;
         }

         break;
      case 't':
         sscanf(optarg, "%zu%c", &roll_point, &roll_metric);

         switch( tolower(roll_metric) ) {
            case 's':
               roll_time = roll_point;
               roll_type = SECONDS;
               break;
            case 'm':
               roll_time = roll_point * 60;
               roll_type = MINUTES;
               break;
            case 'h':
               roll_time = roll_point * 60 * 60;
               roll_type = HOURS;
               break;
            case 'd':
               roll_time = roll_point * 60 * 60 * 24;
               roll_type = DAYS;
               break;
            default:
               printf("[*] Invalid size metric: %c\n", roll_metric ? roll_metric : '-');
               break;
         }

         break;
      default:
         exit_clean(1);
         break;
   }

   errbuf[0] = '\0';

   // validate the output format string
   format_validate(output_format);

   // specify reading from a device OR a file and not both
   if ( (mode & MODE_DEV) && (mode & MODE_FILE) )
   {
      printf("[!] You must specify a device OR file to read from, not both.\n");
      usage(argv[0]);
      exit_clean(1);
   }
   else if ( (mode & MODE_FILE) && read_file) {
      /* Read from PCAP file specified by '-r' switch. */
      printf("[*] Reading from file %s", read_file);
      if (!(handle = pcap_open_offline(read_file, errbuf))) {
         printf("\n");
         printf("[*] Unable to open %s. (%s)\n", read_file, errbuf);
         exit_clean(1);
      } else {
         printf(" - OK\n");
      }

      // in pcap_open_offline(), libpcap appears to use a static buffer
      // for reading in the file. we must use memcpy's to ensure data
      // persists as expected
      if ( ip_init(&ip_config, IP_SET_MEMCPY) )
      {
        printf("[!] Unable to initialise the IP library.\n");
        exit_clean(1);
      }
      else
        printf("[*] IP library using \"memcpy\" set.\n");
   }
   else if ( (mode & MODE_DEV) && dev) {
      if (getuid()) {
         printf("[*] You must be root..\n");
         exit_clean(1);
      }

      printf("[*] Running cxtracker %s\n",VERSION);

      //errbuf[0] = '\0';
      /* look up an availible device if non specified */
      if (dev == 0x0) dev = pcap_lookupdev(errbuf);
      printf("[*] Device: %s\n", dev);

      if ((handle = pcap_open_live(dev, SNAPLENGTH, 1, 500, errbuf)) == NULL) {
         printf("[*] Error pcap_open_live: %s \n", errbuf);
         exit_clean(1);
      }

      // in pcap_open_live(), libpcap maintains a heap allocated buffer
      // for reading off the wire. we can use pointer copies here for 
      // improved speed
      if ( ip_init(&ip_config, IP_SET_MEMCPY) )
      {
        printf("[*] Unable to initialise the IP library.\n");
        exit_clean(1);
      }
      else
        printf("[*] IP library using \"memcpy\" set.\n");

      if ( chroot_flag == 1 ) {
         set_chroot();
      }

      if(daemon_flag) {
         if(!is_valid_path(pidpath))
            printf("[*] PID path \"%s\" is bad, check privilege.",pidpath);
            openlog("cxtracker", LOG_PID | LOG_CONS, LOG_DAEMON);
            printf("[*] Daemonizing...\n\n");
            go_daemon();
      }
   }
   else
   {
      printf("[*] You must specify where to read from.\n");
      exit_clean(1);
   }

   if ((pcap_compile(handle, &cfilter, bpff, 1 ,net_mask)) == -1) {
      printf("[*] Error pcap_compile user_filter: %s\n", pcap_geterr(handle));
      exit_clean(1);
   }

   if (pcap_setfilter(handle, &cfilter)) {
      printf("[*] Unable to set pcap filter!  (%s)\n", pcap_geterr(handle));
   } else {
      pcap_freecode(&cfilter); // filter code not needed after setfilter
   }

   // set up dump mode now as appropriate
   if (mode & MODE_DUMP ) {
      printf("[*] Writing traffic to %s%s.*, rolling every %d %s\n",
          dpath, dump_file_prefix, (int)roll_point, rollover_names[(int)roll_type]);
      dump_file_open();
   }

   /* B0rk if we see an error... */
   if (strlen(errbuf) > 0) {
      printf("[*] Error errbuf: %s \n", errbuf);
      exit_clean(1);
   }

   if(drop_privs_flag) {
      printf("[*] Dropping privs...\n\n");
      drop_privs();
   }

   bucket_keys_NULL();

   alarm(TIMEOUT);
   if (read_file) {
      printf("[*] Reading packets...\n");
   } else {
      printf("[*] Sniffing...\n");
   }

   roll_time_last = time(NULL);
   pcap_loop(handle,-1,got_packet,NULL);

   game_over();

   return 0;
}
Esempio n. 14
0
void* rtp_collect( void* device ) {

        struct bpf_program filter;
        char errbuf[PCAP_ERRBUF_SIZE];
        char *filter_expr;
        uint16_t snaplen = 65535, timeout = 100, len = 300, ret = 0;        

        if(device) {
            if((sniffer_rtp = pcap_open_live((char *)device, snaplen, rtcp_promisc, timeout, errbuf)) == NULL) {
                LERR("Failed to open packet sniffer on %s: pcap_open_live(): %s\n", (char *)device, errbuf);
                return NULL;
            }
        } else  {
            if((sniffer_rtp = pcap_open_offline(usefile, errbuf)) == NULL) {
                LERR("Failed to open packet sniffer rtp on %s: pcap_open_offline(): %s\n", usefile, errbuf);
                return NULL;
            }
        }

        len += (rtcp_portrange != NULL) ? strlen(rtcp_portrange) : 10;        
        len += (rtcp_userfilter != NULL) ? strlen(rtcp_userfilter) : 0;        
        filter_expr = malloc(sizeof(char) * len);
        
        ret += snprintf(filter_expr, len, RTCP_FILTER);
                        
        /* FILTER */
        if(rtcp_portrange != NULL) ret += snprintf(filter_expr+ret, (len - ret), "%s portrange %s ", ret ? " and": "", rtcp_portrange);

        /* CUSTOM FILTER */
        if(rtcp_userfilter != NULL) ret += snprintf(filter_expr+ret, (len - ret), " %s", rtcp_userfilter);

        /* compile filter expression (global constant, see above) */
        if (pcap_compile(sniffer_rtp, &filter, filter_expr, 1, 0) == -1) {
                LERR("Failed to compile filter \"%s\": %s\n", filter_expr, pcap_geterr(sniffer_rtp));
                if(filter_expr) free(filter_expr);
                return NULL;
        }

        /* install filter on sniffer session */
        if (pcap_setfilter(sniffer_rtp, &filter)) {
                LERR("Failed to install filter: %s\n", pcap_geterr(sniffer_rtp));
                if(filter_expr) free(filter_expr);
                return NULL;
        }

        if(filter_expr) free(filter_expr);
        
        /* detect link_offset. Thanks ngrep for this. */
        switch(pcap_datalink(sniffer_rtp)) {
                case DLT_EN10MB:
                    link_offset = ETHHDR_SIZE;
                    break;

                case DLT_IEEE802:
                    link_offset = TOKENRING_SIZE;
                    break;

                case DLT_FDDI:
                    link_offset = FDDIHDR_SIZE;
                    break;

                case DLT_SLIP:
                    link_offset = SLIPHDR_SIZE;
                    break;

                case DLT_PPP:
                    link_offset = PPPHDR_SIZE;
                    break;

                case DLT_LOOP:
                case DLT_NULL:
                    link_offset = LOOPHDR_SIZE;
                    break;

                case DLT_RAW:
                    link_offset = RAWHDR_SIZE;
                    break;

                case DLT_LINUX_SLL:
                    link_offset = ISDNHDR_SIZE;
                    break;

                case DLT_IEEE802_11:
                    link_offset = IEEE80211HDR_SIZE;
                    break;

                default:
                    LERR( "fatal: unsupported interface type %u\n", pcap_datalink(sniffer_rtp));
                    exit(-1);
        }

        while (pcap_loop(sniffer_rtp, 0, (pcap_handler)rtcpback_proto, 0));


        /* terminate from here */
        handler(1);

        return NULL;
}
Esempio n. 15
0
/**
 * returns number of bytes sent on success or -1 on error
 * Note: it is theoretically possible to get a return code >0 and < len
 * which for most people would be considered an error (the packet wasn't fully sent)
 * so you may want to test for recode != len too.
 *
 * Most socket API's have two interesting errors: ENOBUFS & EAGAIN.  ENOBUFS
 * is usually due to the kernel buffers being full.  EAGAIN happens when you
 * try to send traffic faster then the PHY allows.
 */
int
sendpacket(sendpacket_t *sp, const u_char *data, size_t len, struct pcap_pkthdr *pkthdr)
{
    int retcode = 0, val;
    static u_char buffer[10000]; /* 10K bytes, enough for jumbo frames + pkthdr
                                  * larger than page size so made static to
                                  * prevent page misses on stack
                                  */
    static const size_t buffer_payload_size = sizeof(buffer) + sizeof(struct pcap_pkthdr);

    assert(sp);
    assert(data);

    if (len <= 0)
        return -1;

TRY_SEND_AGAIN:
    sp->attempt ++;

    switch (sp->handle_type) {
        case SP_TYPE_KHIAL:

            memcpy(buffer, pkthdr, sizeof(struct pcap_pkthdr));
            memcpy(buffer + sizeof(struct pcap_pkthdr), data, min(len, buffer_payload_size));

            /* tell the kernel module which direction the traffic is going */
            if (sp->cache_dir == TCPR_DIR_C2S) {  /* aka PRIMARY */
                val = KHIAL_DIRECTION_RX;
                if (ioctl(sp->handle.fd, KHIAL_SET_DIRECTION, (void *)&val) < 0) {
                    sendpacket_seterr(sp, "Error setting direction on %s: %s (%d)",
                            sp->device, strerror(errno), errno);
                    return -1;
                }
            } else if (sp->cache_dir == TCPR_DIR_S2C) {
                val = KHIAL_DIRECTION_TX;
                if (ioctl(sp->handle.fd, KHIAL_SET_DIRECTION, (void *)&val) < 0) {
                    sendpacket_seterr(sp, "Error setting direction on %s: %s (%d)",
                            sp->device, strerror(errno), errno);
                    return -1;
                }
            }

            /* write the pkthdr + packet data all at once */
            retcode = write(sp->handle.fd, (void *)buffer, sizeof(struct pcap_pkthdr) + len);
            retcode -= sizeof(struct pcap_pkthdr); /* only record packet bytes we sent, not pcap data too */
                    
            if (retcode < 0 && !sp->abort) {
                switch(errno) {
                    case EAGAIN:
                        sp->retry_eagain ++;
                        goto TRY_SEND_AGAIN;
                        break;
                    case ENOBUFS:
                        sp->retry_enobufs ++;
                        goto TRY_SEND_AGAIN;
                        break;
                    default:
                        sendpacket_seterr(sp, "Error with %s [" COUNTER_SPEC "]: %s (errno = %d)",
                                "khial", sp->sent + sp->failed + 1, strerror(errno), errno);
                }
                break;
            }

            break;

        case SP_TYPE_TUNTAP:
            retcode = write(sp->handle.fd, (void *)data, len);
            break;

            /* Linux PF_PACKET and TX_RING */
        case SP_TYPE_PF_PACKET:
        case SP_TYPE_TX_RING:
#if defined HAVE_PF_PACKET
#ifdef HAVE_TX_RING
            retcode = (int)txring_put(sp->tx_ring, data, len);
#else
            retcode = (int)send(sp->handle.fd, (void *)data, len, 0);
#endif

            /* out of buffers, or hit max PHY speed, silently retry
             * as long as we're not told to abort
             */
            if (retcode < 0 && !sp->abort) {
                switch (errno) {
                    case EAGAIN:
                        sp->retry_eagain ++;
                        goto TRY_SEND_AGAIN;
                        break;
                    case ENOBUFS:
                        sp->retry_enobufs ++;
                        goto TRY_SEND_AGAIN;
                        break;

                    default:
                        sendpacket_seterr(sp, "Error with %s [" COUNTER_SPEC "]: %s (errno = %d)", 
                                INJECT_METHOD, sp->sent + sp->failed + 1, strerror(errno), errno);
                }
            }

#endif /* HAVE_PF_PACKET */

            break;


        /* BPF */
        case SP_TYPE_BPF:
#if defined HAVE_BPF
            retcode = write(sp->handle.fd, (void *)data, len);

            /* out of buffers, or hit max PHY speed, silently retry */
            if (retcode < 0 && !sp->abort) {
                switch (errno) {
                    case EAGAIN:
                        sp->retry_eagain ++;
                        goto TRY_SEND_AGAIN;
                        break;

                    case ENOBUFS:
                        sp->retry_enobufs ++;
                        goto TRY_SEND_AGAIN;
                        break;

                    default:
                        sendpacket_seterr(sp, "Error with %s [" COUNTER_SPEC "]: %s (errno = %d)", 
                                INJECT_METHOD, sp->sent + sp->failed + 1, strerror(errno), errno);
                }
            }
#endif
            break;

        /* Libdnet */
        case SP_TYPE_LIBDNET:

#if defined HAVE_LIBDNET
            retcode = eth_send(sp->handle.ldnet, (void*)data, (size_t)len);

            /* out of buffers, or hit max PHY speed, silently retry */
            if (retcode < 0 && !sp->abort) {
                switch (errno) {
                    case EAGAIN:
                        sp->retry_eagain ++;
                        goto TRY_SEND_AGAIN;
                        break;

                    case ENOBUFS:
                        sp->retry_enobufs ++;
                        goto TRY_SEND_AGAIN;
                        break;

                    default:
                        sendpacket_seterr(sp, "Error with %s [" COUNTER_SPEC "]: %s (errno = %d)", 
                                INJECT_METHOD, sp->sent + sp->failed + 1, strerror(errno), errno);
                }
            }
#endif
            break;

        case SP_TYPE_LIBPCAP:
#if (defined HAVE_PCAP_INJECT || defined HAVE_PCAP_SENDPACKET)
#if defined HAVE_PCAP_INJECT
            /* 
             * pcap methods don't seem to support ENOBUFS, so we just straight fail
             * is there a better way???
             */
            retcode = pcap_inject(sp->handle.pcap, (void*)data, len);
#elif defined HAVE_PCAP_SENDPACKET
            retcode = pcap_sendpacket(sp->handle.pcap, data, (int)len);
#endif

            /* out of buffers, or hit max PHY speed, silently retry */
            if (retcode < 0 && !sp->abort) {
                switch (errno) {
                    case EAGAIN:
                        sp->retry_eagain ++;
                        goto TRY_SEND_AGAIN;
                        break;

                    case ENOBUFS:
                        sp->retry_enobufs ++;
                        goto TRY_SEND_AGAIN;
                        break;

                    default:
                        sendpacket_seterr(sp, "Error with %s [" COUNTER_SPEC "]: %s (errno = %d)", 
                                INJECT_METHOD, sp->sent + sp->failed + 1, pcap_geterr(sp->handle.pcap), errno);
                }
            }
#if defined HAVE_PCAP_SENDPACKET
            /* 
             * pcap_sendpacket returns 0 on success, not the packet length! 
             * hence, we have to fix retcode to be more standard on success
             */
            if (retcode == 0)
                retcode = len;
#endif /* HAVE_PCAP_SENDPACKET */

#endif /* HAVE_PCAP_INJECT || HAVE_PCAP_SENDPACKET */

            break;

        case SP_TYPE_QUICK_TX:
#ifdef HAVE_QUICK_TX
            retcode = quick_tx_send_packet(sp->qtx_dev, data, len);
            if (retcode < 0)
                sendpacket_seterr(sp, "Quick TX send failure");
#endif
            break;

        case SP_TYPE_NETMAP:
#ifdef HAVE_NETMAP
            retcode = sendpacket_send_netmap(sp, data, len);

            if (retcode == -1) {
                sendpacket_seterr(sp, "interface hung!!");
            } else if (retcode == -2) {
                /* this indicates that a retry was requested - this is not a failure */
                retcode = 0;
                goto TRY_SEND_AGAIN;
            }
#endif /* HAVE_NETMAP */
            break;

        default:
            errx(-1, "Unsupported sp->handle_type = %d", sp->handle_type);
    } /* end case */

    if (retcode < 0) {
        sp->failed ++;
    } else if (retcode != (int)len) {
        sendpacket_seterr(sp, "Only able to write %d bytes out of %u bytes total",
                retcode, len);
        sp->trunc_packets ++;
    } else {
        sp->bytes_sent += len;
        sp->sent ++;
    }
    return retcode;
}
Esempio n. 16
0
/**
 * \brief Init function for ReceivePcap.
 *
 * This is a setup function for recieving packets
 * via libpcap. There are two versions of this function
 * depending on the major version of libpcap used.
 * For versions prior to 1.x we use open_pcap_live,
 * for versions 1.x and greater we use pcap_create + pcap_activate.
 *
 * \param tv pointer to ThreadVars
 * \param initdata pointer to the interface passed from the user
 * \param data pointer gets populated with PcapThreadVars
 *
 * \todo Create a general pcap setup function.
 */
TmEcode ReceivePcapThreadInit(ThreadVars *tv, const void *initdata, void **data)
{
    SCEnter();
    PcapIfaceConfig *pcapconfig = (PcapIfaceConfig *)initdata;

    if (initdata == NULL) {
        SCLogError(SC_ERR_INVALID_ARGUMENT, "initdata == NULL");
        SCReturnInt(TM_ECODE_FAILED);
    }

    PcapThreadVars *ptv = SCMalloc(sizeof(PcapThreadVars));
    if (unlikely(ptv == NULL)) {
        pcapconfig->DerefFunc(pcapconfig);
        SCReturnInt(TM_ECODE_FAILED);
    }
    memset(ptv, 0, sizeof(PcapThreadVars));

    ptv->tv = tv;

    ptv->livedev = LiveGetDevice(pcapconfig->iface);
    if (ptv->livedev == NULL) {
        SCLogError(SC_ERR_INVALID_VALUE, "Unable to find Live device");
        SCFree(ptv);
        SCReturnInt(TM_ECODE_FAILED);
    }

    SCLogInfo("using interface %s", (char *)pcapconfig->iface);

    if (LiveGetOffload() == 0) {
        (void)GetIfaceOffloading((char *)pcapconfig->iface, 1, 1);
    } else {
        DisableIfaceOffloading(ptv->livedev, 1, 1);
    }

    ptv->checksum_mode = pcapconfig->checksum_mode;
    if (ptv->checksum_mode == CHECKSUM_VALIDATION_AUTO) {
        SCLogInfo("Running in 'auto' checksum mode. Detection of interface state will require "
                  xstr(CHECKSUM_SAMPLE_COUNT) " packets.");
    }

    /* XXX create a general pcap setup function */
    char errbuf[PCAP_ERRBUF_SIZE];
    ptv->pcap_handle = pcap_create((char *)pcapconfig->iface, errbuf);
    if (ptv->pcap_handle == NULL) {
        if (strlen(errbuf)) {
            SCLogError(SC_ERR_PCAP_CREATE, "Couldn't create a new pcap handler for %s, error %s",
                    (char *)pcapconfig->iface, errbuf);
        } else {
            SCLogError(SC_ERR_PCAP_CREATE, "Couldn't create a new pcap handler for %s",
                    (char *)pcapconfig->iface);
        }
        SCFree(ptv);
        pcapconfig->DerefFunc(pcapconfig);
        SCReturnInt(TM_ECODE_FAILED);
    }

    if (pcapconfig->snaplen == 0) {
        /* We set snaplen if we can get the MTU */
        ptv->pcap_snaplen = GetIfaceMaxPacketSize(pcapconfig->iface);
    } else {
        ptv->pcap_snaplen = pcapconfig->snaplen;
    }
    if (ptv->pcap_snaplen > 0) {
        /* set Snaplen. Must be called before pcap_activate */
        int pcap_set_snaplen_r = pcap_set_snaplen(ptv->pcap_handle, ptv->pcap_snaplen);
        if (pcap_set_snaplen_r != 0) {
            SCLogError(SC_ERR_PCAP_SET_SNAPLEN, "Couldn't set snaplen, error: %s", pcap_geterr(ptv->pcap_handle));
            SCFree(ptv);
            pcapconfig->DerefFunc(pcapconfig);
            SCReturnInt(TM_ECODE_FAILED);
        }
        SCLogInfo("Set snaplen to %d for '%s'", ptv->pcap_snaplen,
                  pcapconfig->iface);
    }

    /* set Promisc, and Timeout. Must be called before pcap_activate */
    int pcap_set_promisc_r = pcap_set_promisc(ptv->pcap_handle, pcapconfig->promisc);
    //printf("ReceivePcapThreadInit: pcap_set_promisc(%p) returned %" PRId32 "\n", ptv->pcap_handle, pcap_set_promisc_r);
    if (pcap_set_promisc_r != 0) {
        SCLogError(SC_ERR_PCAP_SET_PROMISC, "Couldn't set promisc mode, error %s", pcap_geterr(ptv->pcap_handle));
        SCFree(ptv);
        pcapconfig->DerefFunc(pcapconfig);
        SCReturnInt(TM_ECODE_FAILED);
    }

    int pcap_set_timeout_r = pcap_set_timeout(ptv->pcap_handle,LIBPCAP_COPYWAIT);
    //printf("ReceivePcapThreadInit: pcap_set_timeout(%p) returned %" PRId32 "\n", ptv->pcap_handle, pcap_set_timeout_r);
    if (pcap_set_timeout_r != 0) {
        SCLogError(SC_ERR_PCAP_SET_TIMEOUT, "Problems setting timeout, error %s", pcap_geterr(ptv->pcap_handle));
        SCFree(ptv);
        pcapconfig->DerefFunc(pcapconfig);
        SCReturnInt(TM_ECODE_FAILED);
    }
#ifdef HAVE_PCAP_SET_BUFF
    ptv->pcap_buffer_size = pcapconfig->buffer_size;
    if (ptv->pcap_buffer_size >= 0 && ptv->pcap_buffer_size <= INT_MAX) {
        if (ptv->pcap_buffer_size > 0)
            SCLogInfo("Going to use pcap buffer size of %" PRId32 "", ptv->pcap_buffer_size);

        int pcap_set_buffer_size_r = pcap_set_buffer_size(ptv->pcap_handle,ptv->pcap_buffer_size);
        //printf("ReceivePcapThreadInit: pcap_set_timeout(%p) returned %" PRId32 "\n", ptv->pcap_handle, pcap_set_buffer_size_r);
        if (pcap_set_buffer_size_r != 0) {
            SCLogError(SC_ERR_PCAP_SET_BUFF_SIZE, "Problems setting pcap buffer size, error %s", pcap_geterr(ptv->pcap_handle));
            SCFree(ptv);
            pcapconfig->DerefFunc(pcapconfig);
            SCReturnInt(TM_ECODE_FAILED);
        }
    }
#endif /* HAVE_PCAP_SET_BUFF */

    /* activate the handle */
    int pcap_activate_r = pcap_activate(ptv->pcap_handle);
    //printf("ReceivePcapThreadInit: pcap_activate(%p) returned %" PRId32 "\n", ptv->pcap_handle, pcap_activate_r);
    if (pcap_activate_r != 0) {
        SCLogError(SC_ERR_PCAP_ACTIVATE_HANDLE, "Couldn't activate the pcap handler, error %s", pcap_geterr(ptv->pcap_handle));
        SCFree(ptv);
        pcapconfig->DerefFunc(pcapconfig);
        SCReturnInt(TM_ECODE_FAILED);
    } else {
        ptv->pcap_state = PCAP_STATE_UP;
    }

    /* set bpf filter if we have one */
    if (pcapconfig->bpf_filter) {
        SCMutexLock(&pcap_bpf_compile_lock);

        ptv->bpf_filter = pcapconfig->bpf_filter;

        if (pcap_compile(ptv->pcap_handle,&ptv->filter,(char *)ptv->bpf_filter,1,0) < 0) {
            SCLogError(SC_ERR_BPF, "bpf compilation error %s", pcap_geterr(ptv->pcap_handle));

            SCMutexUnlock(&pcap_bpf_compile_lock);
            SCFree(ptv);
            pcapconfig->DerefFunc(pcapconfig);
            return TM_ECODE_FAILED;
        }

        if (pcap_setfilter(ptv->pcap_handle,&ptv->filter) < 0) {
            SCLogError(SC_ERR_BPF, "could not set bpf filter %s", pcap_geterr(ptv->pcap_handle));

            SCMutexUnlock(&pcap_bpf_compile_lock);
            SCFree(ptv);
            pcapconfig->DerefFunc(pcapconfig);
            return TM_ECODE_FAILED;
        }

        SCMutexUnlock(&pcap_bpf_compile_lock);
    }

    /* no offloading supported at all */
    (void)GetIfaceOffloading(pcapconfig->iface, 1, 1);

    ptv->datalink = pcap_datalink(ptv->pcap_handle);

    pcapconfig->DerefFunc(pcapconfig);

    ptv->capture_kernel_packets = StatsRegisterCounter("capture.kernel_packets",
            ptv->tv);
    ptv->capture_kernel_drops = StatsRegisterCounter("capture.kernel_drops",
            ptv->tv);
    ptv->capture_kernel_ifdrops = StatsRegisterCounter("capture.kernel_ifdrops",
            ptv->tv);

    *data = (void *)ptv;
    SCReturnInt(TM_ECODE_OK);
}
Esempio n. 17
0
void capture_init(void)
{
   pcap_t *pd;
   pcap_t *pb = NULL; /* for the bridge */
   pcap_dumper_t *pdump;
   bpf_u_int32 net, mask;
   struct bpf_program bpf;
   char pcap_errbuf[PCAP_ERRBUF_SIZE];
   
   /*
    * if the user didn't specified the interface,
    * we have to found one...
    */
   if (!GBL_OPTIONS->read && GBL_OPTIONS->iface == NULL) {
      char *ifa = pcap_lookupdev(pcap_errbuf);
      ON_ERROR(ifa, NULL, "No suitable interface found...");
      
      GBL_OPTIONS->iface = iface_name(ifa);
   }
  
   if (GBL_OPTIONS->iface)
      DEBUG_MSG("capture_init %s", GBL_OPTIONS->iface);
   else
      DEBUG_MSG("capture_init (no interface)");
      
              
   if (GBL_SNIFF->type == SM_BRIDGED) {
      if (!strcmp(GBL_OPTIONS->iface, GBL_OPTIONS->iface_bridge))
         FATAL_ERROR("Bridging iface must be different from %s", GBL_OPTIONS->iface);
      USER_MSG("Bridging %s and %s...\n\n", GBL_OPTIONS->iface, GBL_OPTIONS->iface_bridge);
   } else if (GBL_OPTIONS->read) {
      USER_MSG("Reading from %s... ", GBL_OPTIONS->pcapfile_in);
   } else
      USER_MSG("Listening on %s... ", GBL_OPTIONS->iface);
   
   /* set the snaplen to maximum */
   GBL_PCAP->snaplen = UINT16_MAX;
   
   /* open the interface from GBL_OPTIONS (user specified) */
   if (GBL_OPTIONS->read)
      pd = pcap_open_offline(GBL_OPTIONS->pcapfile_in, pcap_errbuf);
   else
      pd = pcap_open_live(GBL_OPTIONS->iface, GBL_PCAP->snaplen, GBL_PCAP->promisc, 
                   PCAP_TIMEOUT, pcap_errbuf);
   
   ON_ERROR(pd, NULL, "pcap_open: %s", pcap_errbuf);

   /* 
    * update to the reap assigned snapshot.
    * this may be different reading from files
    */
   DEBUG_MSG("requested snapshot: %d assigned: %d", GBL_PCAP->snaplen, pcap_snapshot(pd));
   GBL_PCAP->snaplen = pcap_snapshot(pd);
  
   /* get the file size */
   if (GBL_OPTIONS->read) {
      struct stat st;
      fstat(fileno(pcap_file(pd)), &st);
      GBL_PCAP->dump_size = st.st_size;
   }

   /* set the pcap filters */
   if (GBL_PCAP->filter != NULL && strcmp(GBL_PCAP->filter, "")) {

      DEBUG_MSG("pcap_filter: %s", GBL_PCAP->filter);
   
      if (pcap_lookupnet(GBL_OPTIONS->iface, &net, &mask, pcap_errbuf) == -1)
         ERROR_MSG("%s", pcap_errbuf);

      if (pcap_compile(pd, &bpf, GBL_PCAP->filter, 1, mask) < 0)
         ERROR_MSG("%s", pcap_errbuf);
            
      if (pcap_setfilter(pd, &bpf) == -1)
         ERROR_MSG("pcap_setfilter");

      pcap_freecode(&bpf);
   }
   
   /* if in bridged sniffing, we have to open even the other iface */
   if (GBL_SNIFF->type == SM_BRIDGED) {
      pb = pcap_open_live(GBL_OPTIONS->iface_bridge, GBL_PCAP->snaplen, GBL_PCAP->promisc, 
                   PCAP_TIMEOUT, pcap_errbuf);
   
      ON_ERROR(pb, NULL, "%s", pcap_errbuf);
   
      /* set the pcap filters */
      if (GBL_PCAP->filter != NULL) {
   
         if (pcap_lookupnet(GBL_OPTIONS->iface_bridge, &net, &mask, pcap_errbuf) == -1)
            ERROR_MSG("%s", pcap_errbuf);

         if (pcap_compile(pb, &bpf, GBL_PCAP->filter, 1, mask) < 0)
            ERROR_MSG("%s", pcap_errbuf);
            
         if (pcap_setfilter(pb, &bpf) == -1)
            ERROR_MSG("pcap_setfilter");

         pcap_freecode(&bpf);
      }
   }


   /* open the dump file */
   if (GBL_OPTIONS->write) {
      DEBUG_MSG("pcapfile_out: %s", GBL_OPTIONS->pcapfile_out);
      pdump = pcap_dump_open(pd, GBL_OPTIONS->pcapfile_out);
      ON_ERROR(pdump, NULL, "%s", pcap_geterr(pd));
      GBL_PCAP->dump = pdump;               
   }
   
   /* set the right dlt type for the iface */
   GBL_PCAP->dlt = pcap_datalink(pd);
     
   DEBUG_MSG("capture_init: %s [%d]", pcap_datalink_val_to_description(GBL_PCAP->dlt), GBL_PCAP->dlt);
   USER_MSG("(%s)\n\n", pcap_datalink_val_to_description(GBL_PCAP->dlt));
 
   /* check that the bridge type is the same as the main iface */
   if (GBL_SNIFF->type == SM_BRIDGED && pcap_datalink(pb) != GBL_PCAP->dlt)
      FATAL_ERROR("You can NOT bridge two different type of interfaces !");
   
   /* check if we support this media */
   if (get_decoder(LINK_LAYER, GBL_PCAP->dlt) == NULL) {
      if (GBL_OPTIONS->read)
         FATAL_ERROR("Dump file not supported (%s)", pcap_datalink_val_to_description(GBL_PCAP->dlt));
      else
         FATAL_ERROR("Inteface \"%s\" not supported (%s)", GBL_OPTIONS->iface, pcap_datalink_val_to_description(GBL_PCAP->dlt));
   }
   
   /* set the alignment for the buffer */
   set_alignment(GBL_PCAP->dlt);
   
   /* allocate the buffer for the packets (UINT16_MAX) */
   SAFE_CALLOC(GBL_PCAP->buffer, UINT16_MAX + GBL_PCAP->align, sizeof(char));
  
   /* set the global descriptor for both the iface and the bridge */
   GBL_PCAP->pcap = pd;               
   if (GBL_SNIFF->type == SM_BRIDGED)
      GBL_PCAP->pcap_bridge = pb;
 
   /* on exit clean up the structures */
   atexit(capture_close);
   
}
Esempio n. 18
0
int
main(int argc, char **argv)
{
	register int op;
	register char *cp, *cmdbuf, *device;
	long longarg;
	char *p;
	int timeout = 1000;
	int immediate = 0;
	int nonblock = 0;
	bpf_u_int32 localnet, netmask;
	struct bpf_program fcode;
	char ebuf[PCAP_ERRBUF_SIZE];
	int status;
	int packet_count;

	device = NULL;
	if ((cp = strrchr(argv[0], '/')) != NULL)
		program_name = cp + 1;
	else
		program_name = argv[0];

	opterr = 0;
	while ((op = getopt(argc, argv, "i:mnt:")) != -1) {
		switch (op) {

		case 'i':
			device = optarg;
			break;

		case 'm':
			immediate = 1;
			break;

		case 'n':
			nonblock = 1;
			break;

		case 't':
			longarg = strtol(optarg, &p, 10);
			if (p == optarg || *p != '\0') {
				error("Timeout value \"%s\" is not a number",
				    optarg);
				/* NOTREACHED */
			}
			if (longarg < 0) {
				error("Timeout value %ld is negative", longarg);
				/* NOTREACHED */
			}
			if (longarg > INT_MAX) {
				error("Timeout value %ld is too large (> %d)",
				    longarg, INT_MAX);
				/* NOTREACHED */
			}
			timeout = (int)longarg;
			break;

		default:
			usage();
			/* NOTREACHED */
		}
	}

	if (device == NULL) {
		device = pcap_lookupdev(ebuf);
		if (device == NULL)
			error("%s", ebuf);
	}
	*ebuf = '\0';
	pd = pcap_create(device, ebuf);
	if (pd == NULL)
		error("%s", ebuf);
	status = pcap_set_snaplen(pd, 65535);
	if (status != 0)
		error("%s: pcap_set_snaplen failed: %s",
			    device, pcap_statustostr(status));
	if (immediate) {
		status = pcap_set_immediate_mode(pd, 1);
		if (status != 0)
			error("%s: pcap_set_immediate_mode failed: %s",
			    device, pcap_statustostr(status));
	}
	status = pcap_set_timeout(pd, timeout);
	if (status != 0)
		error("%s: pcap_set_timeout failed: %s",
		    device, pcap_statustostr(status));
	status = pcap_activate(pd);
	if (status < 0) {
		/*
		 * pcap_activate() failed.
		 */
		error("%s: %s\n(%s)", device,
		    pcap_statustostr(status), pcap_geterr(pd));
	} else if (status > 0) {
		/*
		 * pcap_activate() succeeded, but it's warning us
		 * of a problem it had.
		 */
		warning("%s: %s\n(%s)", device,
		    pcap_statustostr(status), pcap_geterr(pd));
	}
	if (pcap_lookupnet(device, &localnet, &netmask, ebuf) < 0) {
		localnet = 0;
		netmask = 0;
		warning("%s", ebuf);
	}
	cmdbuf = copy_argv(&argv[optind]);

	if (pcap_compile(pd, &fcode, cmdbuf, 1, netmask) < 0)
		error("%s", pcap_geterr(pd));

	if (pcap_setfilter(pd, &fcode) < 0)
		error("%s", pcap_geterr(pd));
	if (pcap_setnonblock(pd, nonblock, ebuf) == -1)
		error("pcap_setnonblock failed: %s", ebuf);
	printf("Listening on %s\n", device);
	for (;;) {
		packet_count = 0;
		status = pcap_dispatch(pd, -1, countme,
		    (u_char *)&packet_count);
		if (status < 0)
			break;
		if (status != 0) {
			printf("%d packets seen, %d packets counted after pcap_dispatch returns\n",
			    status, packet_count);
		}
	}
	if (status == -2) {
		/*
		 * We got interrupted, so perhaps we didn't
		 * manage to finish a line we were printing.
		 * Print an extra newline, just in case.
		 */
		putchar('\n');
	}
	(void)fflush(stdout);
	if (status == -1) {
		/*
		 * Error.  Report it.
		 */
		(void)fprintf(stderr, "%s: pcap_loop: %s\n",
		    program_name, pcap_geterr(pd));
	}
	pcap_close(pd);
	exit(status == -1 ? 1 : 0);
}
Esempio n. 19
0
int main(){
	pcap_if_t *alldevs;
	pcap_if_t *d;
	int inum;
	int i = 0;
	pcap_t *adhandle;
	int res;
	char errbuf[PCAP_ERRBUF_SIZE];
	struct tm *ltime;
	char timestr[16];
	struct pcap_pkthdr *header;
	const u_char *pkt_data;
	time_t local_tv_sec;


	/* 获取本机设备列表 */
	if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1)
	{
		fprintf(stderr, "Error in pcap_findalldevs: %s\n", errbuf);
		exit(1);
	}

	/* 打印列表 */
	for (d = alldevs; d; d = d->next)
	{
		printf("%d. %s", ++i, d->name);
		if (d->description)
			printf(" (%s)\n", d->description);
		else
			printf(" (No description available)\n");
	}

	if (i == 0)
	{
		printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
		return -1;
	}

	printf("Enter the interface number (1-%d):", i);
	scanf("%d", &inum);

	if (inum < 1 || inum > i)
	{
		printf("\nInterface number out of range.\n");
		/* 释放设备列表 */
		pcap_freealldevs(alldevs);
		return -1;
	}

	/* 跳转到已选中的适配器 */
	for (d = alldevs, i = 0; i< inum - 1; d = d->next, i++);

	/* 打开设备 */
	if ((adhandle = pcap_open(d->name,          // 设备名
		65536,            // 要捕捉的数据包的部分 
		// 65535保证能捕获到不同数据链路层上的每个数据包的全部内容
		PCAP_OPENFLAG_PROMISCUOUS,    // 混杂模式
		1000,             // 读取超时时间
		NULL,             // 远程机器验证
		errbuf            // 错误缓冲池
		)) == NULL)
	{
		fprintf(stderr, "\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);
		/* 释放设列表 */
		pcap_freealldevs(alldevs);
		return -1;
	}

	printf("\nlistening on %s...\n", d->description);

	/* 释放设备列表 */
	pcap_freealldevs(alldevs);

	/* 获取数据包 */
	while ((res = pcap_next_ex(adhandle, &header, &pkt_data)) >= 0){

		if (res == 0)
			/* 超时时间到 */
			continue;

		/* 将时间戳转换成可识别的格式 */
		local_tv_sec = header->ts.tv_sec;
		ltime = localtime(&local_tv_sec);
		strftime(timestr, sizeof timestr, "%H:%M:%S", ltime);

		printf("%s,%.6d len:%d\n", timestr, header->ts.tv_usec, header->len);
	}

	if (res == -1){
		printf("Error reading the packets: %s\n", pcap_geterr(adhandle));
		return -1;
	}

	return 0;
}
Esempio n. 20
0
int main(int argc, char **argv)
{
	int c, n, i, proto, packet_size, pause_us, retransmit, file_size, num_packets, npacket;
	char *end;
	libnet_t *ln_ctx;
	char ln_errbuf[LIBNET_ERRBUF_SIZE];
	struct libnet_ether_addr *ln_hwaddr;
	libnet_ptag_t ln_ptag;
	pcap_t *pcap_ctx;
	char pcap_errbuf[PCAP_ERRBUF_SIZE], pcap_fp_str[64];
	struct bpf_program pcap_fp;
	struct pcap_pkthdr pcap_hdr;
	FILE *fp;
	unsigned char buf[ETH_DATA_LEN], dest_mac_addr[ETH_ALEN];
	struct pkt_hdr *pkt_hdr;
	struct vlan_eth_hdr *vlan_eth_hdr;

	proto = 0xCAFE;
	packet_size = ETH_DATA_LEN - PKT_HDR_SIZE;
	pause_us = 1000;
	retransmit = 3;

	while ((c = getopt(argc, argv, "p:s:w:r:")) != -1)
	{
		switch (c)
		{
			case 'p':
				proto = strtol(optarg, &end, 0);
				if ((*end != '\0'))
					usage(argv[0]);
			break;

			case 's':
				packet_size = strtol(optarg, &end, 0);
				if ((*end != '\0'))
					usage(argv[0]);

				if ((packet_size <= 0) || (packet_size > (ETH_DATA_LEN - PKT_HDR_SIZE)))
					packet_size = ETH_DATA_LEN - PKT_HDR_SIZE;
			break;

			case 'w':
				pause_us = strtol(optarg, &end, 0);
				if ((*end != '\0'))
					usage(argv[0]);

				if (pause_us <= 0)
					pause_us = 1;
			break;

			case 'r':
				retransmit = strtol(optarg, &end, 0);
				if ((*end != '\0'))
					usage(argv[0]);

				if (retransmit < 0)
					retransmit = 0;
			break;

			case '?':
			default:
				fprintf(stderr, "unrecognized option: %c\n", c);
				usage(argv[0]);
		}
	}

	if (argc != (optind + 3))
		usage(argv[0]);

	if (strlen(argv[optind]) <= 0)
		usage(argv[0]);

	ln_ctx = libnet_init(LIBNET_LINK, argv[optind], ln_errbuf);
	if (ln_ctx == NULL)
	{
		fprintf(stderr, "couldn't initialize libnet context: %s\n", ln_errbuf);
		exit(1);
	}

	if (str2mac(argv[optind + 1], dest_mac_addr) != 0)
		usage(argv[0]);

	pcap_ctx = pcap_open_live(argv[optind], BUFSIZ, 1, 1000, pcap_errbuf);
	if (pcap_ctx == NULL)
	{
		fprintf(stderr, "couldn't initialize pcap context: %s\n", pcap_errbuf);
		exit(1);
	}

	sprintf(pcap_fp_str, "ether proto 0x%04x and ether src %02x:%02x:%02x:%02x:%02x:%02x",
		proto, dest_mac_addr[0], dest_mac_addr[1], dest_mac_addr[2], dest_mac_addr[3],
		dest_mac_addr[4], dest_mac_addr[5]);

	printf("pcap filter: %s\n", pcap_fp_str);

	if (pcap_compile(pcap_ctx, &pcap_fp, pcap_fp_str, 0, PCAP_NETMASK_UNKNOWN) == -1)
	{
		fprintf(stderr, "couldn't compile pcap filter: %s\n", pcap_geterr(pcap_ctx));
		exit(1);
	}

	if (pcap_setfilter(pcap_ctx, &pcap_fp) == -1)
	{
		fprintf(stderr, "couldn't set pcap filter: %s\n", pcap_geterr(pcap_ctx));
		exit(1);
	}

	fp = fopen(argv[optind + 2], "r");
	if (fp == NULL)
	{
		fprintf(stderr, "couldn't open file '%s'\n", argv[optind + 2]);
		exit(1);
	}

	fseek(fp, 0, SEEK_END);

	file_size = ftell(fp);

	fseek(fp, 0, SEEK_SET);

	printf("file size #%d\n", file_size);

	if (file_size == 0)
	{
		printf("file is empty, terminating\n");
		exit(0);
	}

	ln_hwaddr = libnet_get_hwaddr(ln_ctx);

	ln_ptag = libnet_build_ethernet(dest_mac_addr, (u_int8_t *) ln_hwaddr,
		proto, NULL, 0, ln_ctx, 0);
	if (ln_ptag == -1)
	{
		fprintf(stderr, "couldn't create libnet packet: %s\n", libnet_geterror(ln_ctx));
		exit(1);
	}

	num_packets = (file_size + packet_size - 1) / packet_size;
	npacket = 0;

	while ((n = fread(buf + PKT_HDR_SIZE, 1, packet_size, fp)) > 0)
	{
		pkt_hdr = (struct pkt_hdr *) buf;
		memset(pkt_hdr, 0, PKT_HDR_SIZE);
		pkt_hdr->magic = htonl(PKT_MAGIC);
		pkt_hdr->offset = htonl(npacket * packet_size);
		pkt_hdr->size = htonl(n);
        if (n < packet_size)
		    pkt_hdr->flags |= PKT_FLAG_LAST;
		pkt_hdr->flags = htonl(pkt_hdr->flags);

		npacket++;

		if (libnet_build_ethernet(dest_mac_addr, (u_int8_t *) ln_hwaddr,
			proto, buf, n + PKT_HDR_SIZE, ln_ctx, ln_ptag) == -1)
		{
			fprintf(stderr, "couldn't modify libnet packet #%d: %s\n",
				npacket, libnet_geterror(ln_ctx));
			exit(1);
		}

		for (i = 0; i < retransmit + 1; i++)
		{
			printf("sending packet #%d of #%d\n", npacket, num_packets);

			if ((libnet_write(ln_ctx)) == -1)
			{
				fprintf(stderr, "couldn't send packet #%d: %s\n", npacket, libnet_geterror(ln_ctx));
				exit(1);
			}

			/*vlan_eth_hdr = (struct vlan_eth_hdr *) pcap_next(pcap_ctx, &pcap_hdr);
			if (vlan_eth_hdr == NULL)
			{
				fprintf(stderr, "timeout ack for packet #%d\n", npacket);
				goto next;
			}*/

			/*if (pcap_hdr.len < (VLAN_ETH_HLEN + PKT_HDR_SIZE))
			{
				fprintf(stderr, "invalid ack for packet #%d\n", npacket);
				goto next;
			}

			pkt_hdr = (struct pkt_hdr *) (vlan_eth_hdr + 1);
			pkt_hdr->offset = ntohl(pkt_hdr->offset);

			if (pkt_hdr->offset == ((npacket - 1) * packet_size + n))
			{
				printf("received ack for packet #%d\n", npacket);
				break;
			}
			else
			{
				fprintf(stderr, "bad ack for packet #%d, offset 0x%x\n",
					npacket, pkt_hdr->offset);
				goto next;
			}*/

next:
			usleep(1000);
		}

		if (i == (retransmit + 1))
		{
			//fprintf(stderr, "no ack received for packet #%d\n", npacket);
			//exit(1);
		}

		if (pause_us > 0)
			usleep(pause_us);
	}

	fclose(fp);

	pcap_close(pcap_ctx);

	libnet_destroy(ln_ctx);

	exit(0);
}
Esempio n. 21
0
int main(int argc, char** argv) {
	int c, index;
	char *interface = NULL;
	char *file = NULL;
	char *strng = NULL;
	char *expr = NULL;
	char errbuf[PCAP_ERRBUF_SIZE];
	pcap_t *handle = NULL;
	struct bpf_program fp;		/* The compiled filter expression */
	bpf_u_int32 mask;		/* The netmask of our sniffing device */
	bpf_u_int32 net;		/* The IP of our sniffing device */
	bool set = false;

	opterr = 0;
	while (c = getopt(argc, argv, "hi:r:s:")) {
		switch (c) {
			case 'h' :
				print_usage();
				return;
			case 'i' :
				interface = optarg;
				break;
			case 'r' :
				file = optarg;
				break;
			case 's' :
				strng = optarg;
				break;
			case '?' :
				if (optopt == 'i' || optopt == 'r' || optopt == 's')
					fprintf(stderr, "Option -%c requires an argument.\n", optopt);
				else if (isprint(optopt))
					fprintf(stderr, "Unknown option -%c.\n", optopt);
				else
					fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt);
				return 1;
			default :
				goto out;
		}
	}
out :
	for (index = optind; index < argc; index++)
		expr = argv[index];

	if (file) {
//		printf("Offline Case\n");
		interface = NULL;
		handle = pcap_open_offline(file, errbuf);
                if (!handle) {
                        fprintf(stderr, "Couldn't open device : %s\n", errbuf);
                        return (2);
                }
	} else {
		if (interface) {
//			printf("User Passed Interface : %s\n", interface);
		} else {
//			printf("Default interface needs to be used\n");
			interface = pcap_lookupdev(errbuf);
			if (!interface) {
				fprintf(stderr, "Couldn't find default device : %s\n", errbuf);
				return (2);
			}
//			printf("default interface : %s\n", interface);
		}
	}

	if (interface) {
		handle = pcap_open_live(interface, BUFSIZ, 1, 1000, errbuf);
		if (!handle) {
			fprintf(stderr, "Couldn't open device : %s\n", errbuf);
			return (2);
		}
	}
	if (pcap_datalink(handle) != DLT_EN10MB) {
		fprintf(stderr, "Device %s doesn't provide Ethernet headers - not supported\n", interface);
		return (2);
	}
	
	if (expr) {
		if (interface && (pcap_lookupnet(interface, &net, &mask, errbuf) == -1)) {
			fprintf(stderr, "Can't get netmask for device %s\n", interface);
			net = 0;
			mask = 0;
		} else {
			net = 0;
			mask = 0;
		}
		if (pcap_compile(handle, &fp, expr, 0, net) == -1) {
			fprintf(stderr, "Couldn't parse filter %s: %s\n", expr, pcap_geterr(handle));
			return(2);
		}
		set = true;
		if (pcap_setfilter(handle, &fp) == -1) {
			fprintf(stderr, "Couldn't install filter %s: %s\n", expr, pcap_geterr(handle));
			return(2);
		}
	}
	if (strng)
		pcap_loop(handle, 1000, got_packet, (u_char*)strng);
	else
		pcap_loop(handle, 1000, got_packet, NULL);

	if (set)
		pcap_freecode(&fp);
	pcap_close(handle);
	return 0;
}
Esempio n. 22
0
int main(int argc, char *argv[])
{
	pcap_t *handle;			/* Session handle */
	char *dev = "eth0";			/* The device to sniff on */
	char errbuf[PCAP_ERRBUF_SIZE];	/* Error string */
	struct bpf_program fp;		/* The compiled filter */
	//char filter_exp[] = "port 38959";	/* The filter expression */
	char filter_exp[] = "port 40278";	/* The filter expression */
	/* char filter_exp[] = "ip";	/* The filter expression */
	bpf_u_int32 mask;		/* Our netmask */
	bpf_u_int32 net;		/* Our IP */
	struct pcap_pkthdr header;	/* The header that pcap gives us */
	const u_char *packet;		/* The actual packet */


	/* Define the device */

/*
	dev = pcap_lookupdev(errbuf);
	if (dev == NULL) {
		fprintf(stderr, "Couldn't find default device: %s\n", errbuf);
		return(2);
	}
*/


	/* Find the properties for the device */
	if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) {
		fprintf(stderr, "Couldn't get netmask for device %s: %s\n", dev, errbuf);
		net = 0;
		mask = 0;
	}


	/* Open the session in promiscuous mode */
	handle = pcap_open_live(dev, BUFSIZ, /*malicious*/0, 1000, errbuf);
	if (handle == NULL) {
		fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
		return(2);
	}


	/* Compile and apply the filter */

	if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) {
		fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle));
		return(2);
	}

	if (pcap_setfilter(handle, &fp) == -1) {
		fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle));
		return(2);
	}


    pcap_loop(handle, 1000, got_packet, NULL);


	/* And close the session */
	pcap_close(handle);
	return(0);
 }
Esempio n. 23
0
int main(int argc, char *argv[]){
	check_user();
	int c, mode = 1; //default promiscous mode with mode = 1
	char *interface = NULL, *expression;
	bpf_u_int32 netaddr=0, mask=0;
	struct bpf_program filter;
	char errbuf[PCAP_ERRBUF_SIZE];
	pcap_t *descr = NULL;
	struct pcap_pkthdr pkthdr;
	const unsigned char *packet= NULL;
	struct sigaction act;

	start_sniff = time(NULL); //start sniff time

	act.sa_sigaction = sighandler;
	act.sa_flags = SA_SIGINFO;

	//options management
	while((c = getopt(argc,argv,"m:hi:e:c::inv")) != -1){
		switch(c){
			case 'i':
				interface = optarg;
				break;
			case 'm':
				mode = atoi(optarg);
				break;
			case 'v':
				view = 1; //verbose
				break;	
			case 'h':
				help();
				break;
			case 'e':
				expression = optarg;
				break;
			case 'c':
				compute_sum = 1;
				break;
			case 'n':
				resolve_name = 1;
			        break;
		}
	}

	if(expression != NULL && interface != NULL){
		descr = pcap_open_live(interface, MAXCAPUTERBYTES, mode, 512, errbuf);

		if(descr == NULL){
			perror(errbuf);
			exit(1);
		}

		if(pcap_lookupnet(interface,&netaddr,&mask,errbuf) == -1){
			perror(errbuf);
			exit(1);
		}

		if(pcap_compile(descr, &filter, expression,1,mask) == -1){
			perror(pcap_geterr(descr));
			exit(1);
		}

		if(pcap_setfilter(descr,&filter) == -1){
			perror(pcap_geterr(descr));
			exit(1);
		}

		//action to bo taken when SIGINT occurs
		sigaction(SIGINT, &act, NULL);

		while(1){
			//get packet
			packet = pcap_next(descr,&pkthdr);

			if(packet != NULL){
				printf("\033[0;34mPacket #: %d\033[0m - Packet size: %d Bytes - %s", ++pktcount, pkthdr.len, ctime(&pkthdr.ts.tv_sec));
				pkt_tot_size += pkthdr.len;
				
				print_packet(packet);
			}
		}
	}
	else{
		fprintf(stderr,"Please choose an interface and a expression\n");
	}

	return 0;
}
Esempio n. 24
0
int main() {

        struct pcap_pkthdr header;       // The header that pcap gives us
        const u_char* packet;            // The actual packet
	char* device;                    // Sniffing device
	char errbuf[PCAP_ERRBUF_SIZE];   // Error message buffer
	pcap_t* handle;                  // Session handle
	struct bpf_program fp;           // The compiled filter expression
	char filter_exp[] = "dst port 80";
//	char filter_exp[] = "dst net 188.93.212.0/24 and not src net 188.93.208.0/21 and dst port 80";   // The filter expression
	bpf_u_int32 mask;                // The netmask of our sniffing device
	bpf_u_int32 net;                 // The IP of our sniffing device
	device = NULL;
	memset(errbuf, 0, PCAP_ERRBUF_SIZE);
	conn = NULL;
	int fd;
	struct stat sbuf;
	pid_t pid;

	// MYSQL connect
	if ( !(conn = mysql_conn())) {
		fprintf(stderr, "Can't connect to MySQL server");
		exit(1);
	}

	if ( (fd = open("capturefile", O_RDWR)) < 0) {
		fprintf(stderr, "Can't open output file");
		exit(1);
	}
	ftruncate(fd, FILE_SIZE);
	data = mmap((caddr_t)0, FILE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
        if (stat("capturefile", &sbuf) <0) {
                fprintf(stderr, "Can't stat");
                exit(1);
        }
        if (data == (caddr_t)(-1)) {
                fprintf(stderr, "Can't mmap");
                exit(1);
        }

			
	// Get device for capture
	device = pcap_lookupdev(errbuf);
	printf("Device: %s\n", device);
	printf("filter: %s\n", filter_exp);
	if (pcap_lookupnet(device, &net, &mask, errbuf) == -1) {
		fprintf(stderr, "Can't get netmask for device %s\n", device);
		net = 0;
		mask = 0;
	}

	handle = pcap_open_live(device, 1514, 0, 1, errbuf);
	// Compile filter for capture
	if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) {
		fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle));
		exit(1);
	}
	// Apply compiled filter
	if (pcap_setfilter(handle, &fp) == -1) {
		fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle));
		exit(1);
	}
	if ( (pid = fork()) < 0) {
		fprintf(stderr, "Can't fork");
		exit(1);
	} else if (pid == 0) {		
		// Capture
		pcap_loop(handle, 0, pget, NULL);	
	} else {
                while(1) {
                        flock(fd, LOCK_EX);
                        printf("sleep...\n");
                        sleep(10);
                        printf("truncate!\n");
                        ftruncate(fd, 0);
                        ftruncate(fd, FILE_SIZE);
                        flock(fd, LOCK_UN);
                }

	}
	
	pcap_close(handle);
	mysql_close(conn);

	return 0;
}
Esempio n. 25
0
main()
{
pcap_if_t *alldevs;
pcap_if_t *d;
int inum;
int i=0;
pcap_t *adhandle;
int res;
char errbuf[PCAP_ERRBUF_SIZE];
struct tm *ltime;
char timestr[16];
struct pcap_pkthdr *header;
u_char *pkt_data;
	
    
	/* Retrieve the device list on the local machine */
	if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1)
	{
		fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
		exit(1);
	}
    
    /* Print the list */
    for(d=alldevs; d; d=d->next)
    {
        printf("%d. %s", ++i, d->name);
        if (d->description)
            printf(" (%s)\n", d->description);
        else
            printf(" (No description available)\n");
    }
	
    if(i==0)
    {
        printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
        return -1;
    }
    
    printf("Enter the interface number (1-%d):",i);
    scanf("%d", &inum);
    
    if(inum < 1 || inum > i)
    {
        printf("\nInterface number out of range.\n");
        /* Free the device list */
        pcap_freealldevs(alldevs);
        return -1;
    }
	
    /* Jump to the selected adapter */
    for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
    
	/* Open the device */
	if ( (adhandle= pcap_open(d->name,			// name of the device
							  65536,			// portion of the packet to capture. 
												// 65536 guarantees that the whole packet will be captured on all the link layers
							  PCAP_OPENFLAG_PROMISCUOUS, 	// promiscuous mode
							  1000,				// read timeout
							  NULL,				// authentication on the remote machine
							  errbuf			// error buffer
							  ) ) == NULL)
	{
		fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);
		/* Free the device list */
		pcap_freealldevs(alldevs);
		return -1;
	}
    
    printf("\nlistening on %s...\n", d->description);
	
    /* At this point, we don't need any more the device list. Free it */
    pcap_freealldevs(alldevs);
	
	/* Retrieve the packets */
	while((res = pcap_next_ex( adhandle, &header, &pkt_data)) >= 0){
		
		if(res == 0)
			/* Timeout elapsed */
			continue;
		
		/* convert the timestamp to readable format */
		ltime=localtime(&header->ts.tv_sec);
		strftime( timestr, sizeof timestr, "%H:%M:%S", ltime);
		
		printf("%s,%.6d len:%d\n", timestr, header->ts.tv_usec, header->len);
	}
	
	if(res == -1){
		printf("Error reading the packets: %s\n", pcap_geterr(adhandle));
		return -1;
	}
	
    return 0;
}
Esempio n. 26
0
/* currently only works for ETHERNET and FDDI */
static int
pread_tcpdump(
    struct timeval	*ptime,
    int		 	*plen,
    int		 	*ptlen,
    void		**pphys,
    int			*pphystype,
    struct ip		**ppip,
    void		**pplast)
{
    int ret;

    while (1) {
        if ((ret = pcap_dispatch(pcap,1,(pcap_handler)callback,0)) != 1) { //Sriharsha Gangam
        //if ((ret = pcap_offline_read(pcap,1,(pcap_handler)callback,0)) != 1) {
	    /* prob EOF */

	    if (ret == -1) {
		char *error;
		error = pcap_geterr(pcap);

		if (error && *error)
		    fprintf(stderr,"PCAP error: '%s'\n",pcap_geterr(pcap));
		/* else, it's just EOF */
	    }
	    
	    return(0);
	}

	/* at least one tcpdump implementation (AIX) seems to be */
	/* storing NANOseconds in the usecs field of the timestamp. */
	/* This confuses EVERYTHING.  Try to compensate. */
	{
	    static Bool bogus_nanoseconds = FALSE;
	    if ((callback_phdr->ts.tv_usec >= US_PER_SEC) ||
		(bogus_nanoseconds)) {
		if (!bogus_nanoseconds) {
		    fprintf(stderr,
			    "tcpdump: attempting to adapt to bogus nanosecond timestamps\n");
		    bogus_nanoseconds = TRUE;
		}
		callback_phdr->ts.tv_usec /= 1000;
	    }
	}

	/* fill in all of the return values */
	*pphys     = &eth_header;/* everything assumed to be ethernet */
	*pphystype = PHYS_ETHER; /* everything assumed to be ethernet */
	*ppip      = (struct ip *) ip_buf;
	*pplast    = callback_plast; /* last byte in IP packet */
	/* (copying time structure in 2 steps to avoid RedHat brain damage) */
	ptime->tv_usec = callback_phdr->ts.tv_usec;
	ptime->tv_sec = callback_phdr->ts.tv_sec;
	*plen      = callback_phdr->len;
	*ptlen     = callback_phdr->caplen;

	/* if it's not IP, then skip it */
	if ((ntohs(eth_header.ether_type) != ETHERTYPE_IP) &&
	    (ntohs(eth_header.ether_type) != ETHERTYPE_IPV6)) {
	    if (debug > 2)
		fprintf(stderr,"pread_tcpdump: not an IP packet\n");
	    continue;
	}

	return(1);
    }
}
Esempio n. 27
0
int main(int argc, char **argv){
	extern char		*optarg;
	int				r, sel;
	fd_set			sset, rset;
#if defined(sun) || defined(__sun) || defined (__linux__)
	struct timeval		timeout;
#endif
	struct target_ipv6	targetipv6;

	static struct option longopts[] = {
		{"interface", required_argument, 0, 'i'},
		{"src-address", required_argument, 0, 's'},
		{"dst-address", required_argument, 0, 'd'},
		{"hop-limit", required_argument, 0, 'A'},
		{"dst-opt-hdr", required_argument, 0, 'u'},
		{"dst-opt-u-hdr", required_argument, 0, 'U'},
		{"hbh-opt-hdr", required_argument, 0, 'H'},
		{"frag-hdr", required_argument, 0, 'y'},
		{"link-src-addr", required_argument, 0, 'S'},
		{"link-dst-addr", required_argument, 0, 'D'},
		{"target", required_argument, 0, 't'},
		{"router", no_argument, 0, 'r'},
		{"solicited", no_argument, 0, 'c'},
		{"override", no_argument, 0, 'o'},
		{"target-addr-opt", required_argument, 0, 'E'},
		{"add-target-opt", no_argument, 0, 'e'},
		{"block-src-addr", required_argument, 0, 'j'},
		{"block-dst-addr", required_argument, 0, 'k'},
		{"block-link-src-addr", required_argument, 0, 'J'},
		{"block-link-dst-addr", required_argument, 0, 'K'},
		{"block-target-addr", required_argument, 0, 'w'},
		{"accept-src-addr", required_argument, 0, 'b'},
		{"accept-dst-addr", required_argument, 0, 'g'},
		{"accept-link-src-addr", required_argument, 0, 'B'},
		{"accept-link-dst-addr", required_argument, 0, 'G'},
		{"accept-target-addr", required_argument, 0, 'W'},
		{"flood-sources", required_argument, 0, 'F'},
		{"flood-targets", required_argument, 0, 'T'},
		{"loop", no_argument, 0, 'l'},
		{"sleep", required_argument, 0, 'z'},
		{"listen", no_argument, 0, 'L'},
		{"verbose", no_argument, 0, 'v'},
		{"help", no_argument, 0, 'h'},
		{0, 0, 0,  0 }
	};

	char shortopts[]= "i:s:d:A:u:U:H:y:S:D:t:roceE:j:k:J:K:w:b:g:B:G:W:T:F:lz:vhL";

	char option;

	if(argc<=1){
		usage();
		exit(EXIT_FAILURE);
	}

    hoplimit=255;

	/* Initialize filters structure */
	if(init_filters(&filters) == -1){
		puts("Error initializing internal data structure");
		exit(EXIT_FAILURE);
	}

	if(init_iface_data(&idata) == FAILURE){
		puts("Error initializing internal data structure");
		exit(EXIT_FAILURE);
	}

	while((r=getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) {
		option= r;

		switch(option) {
			case 'i':  /* Interface */
				strncpy(idata.iface, optarg, IFACE_LENGTH-1);
				idata.iface[IFACE_LENGTH-1]=0;
				idata.iface_f=TRUE;
				break;

			case 's':	/* IPv6 Source Address */
				if(idata.srcaddr_f){
					puts("Error: Multiple '-s' options have been specified");
					exit(EXIT_FAILURE);
				}

				if((charptr = strtok_r(optarg, "/", &lasts)) == NULL){
					puts("Error in Source Address");
					exit(EXIT_FAILURE);
				}

				if ( inet_pton(AF_INET6, charptr, &(idata.srcaddr)) <= 0){
					puts("inet_pton(): Source Address not valid");
					exit(EXIT_FAILURE);
				}

				idata.srcaddr_f = 1;
		
				if((charptr = strtok_r(NULL, " ", &lasts)) != NULL){
					idata.srcpreflen = atoi(charptr);
		
					if(idata.srcpreflen>128){
						puts("Prefix length error in IPv6 Source Address");
						exit(EXIT_FAILURE);
					}

					sanitize_ipv6_prefix(&(idata.srcaddr), idata.srcpreflen);
					idata.srcprefix_f=1;
				}

				break;
	    
			case 'd':	/* IPv6 Destination Address */
				strncpy( targetipv6.name, optarg, NI_MAXHOST);
				targetipv6.name[NI_MAXHOST-1]= 0;
				targetipv6.flags= AI_CANONNAME;

				if( (r=get_ipv6_target(&targetipv6)) != 0){

					if(r < 0){
						printf("Unknown Destination: %s\n", gai_strerror(targetipv6.res));
					}
					else{
						puts("Unknown Destination: No IPv6 address found for specified destination");
					}

					exit(1);
				}

				idata.dstaddr= targetipv6.ip6;
				idata.dstaddr_f = 1;
				break;

			case 'A':	/* Hop Limit */
				hoplimit= atoi(optarg);
				hoplimit_f=1;
				break;

			case 'y':	/* Fragment header */
				nfrags= atoi(optarg);
				if(nfrags < 8){
					puts("Error in Fragmentation option: Fragment Size must be at least 8 bytes");
					exit(EXIT_FAILURE);
				}
		
				nfrags = (nfrags +7) & 0xfff8;
				idata.fragh_f= 1;
				break;

			case 'u':	/* Destinations Options Header */
				if(ndstopthdr >= MAX_DST_OPT_HDR){
					puts("Too many Destination Options Headers");
					exit(EXIT_FAILURE);
				}

				hdrlen= atoi(optarg);
		
				if(hdrlen < 8){
					puts("Bad length in Destination Options Header");
					exit(EXIT_FAILURE);
				}
		    
				hdrlen = ((hdrlen+7)/8) * 8;
				dstopthdrlen[ndstopthdr]= hdrlen;

				if( (dstopthdr[ndstopthdr]= malloc(hdrlen)) == NULL){
					puts("Not enough memory for Destination Options Header");
					exit(EXIT_FAILURE);
				}

				ptrhdr= dstopthdr[ndstopthdr] + 2;
				ptrhdrend= dstopthdr[ndstopthdr] + hdrlen;

				while( ptrhdr < ptrhdrend){

					if( (ptrhdrend-ptrhdr)>257)
						pad= 257;
					else
						pad= ptrhdrend-ptrhdr;
			
					if(!insert_pad_opt(ptrhdr, ptrhdrend, pad)){
						puts("Destination Options Header Too Big");
						exit(EXIT_FAILURE);
					}
		    
					ptrhdr= ptrhdr + pad;
				}

				*(dstopthdr[ndstopthdr]+1)= (hdrlen/8)-1;
				ndstopthdr++;
				dstopthdr_f=1;
				break;

			case 'U':	/* Destination Options Header (Unfragmentable Part) */
				if(ndstoptuhdr >= MAX_DST_OPT_U_HDR){
					puts("Too many Destination Options Headers (Unfragmentable Part)");
					exit(EXIT_FAILURE);
				}

				hdrlen= atoi(optarg);
		
				if(hdrlen < 8){
					puts("Bad length in Destination Options Header (Unfragmentable Part)");
					exit(EXIT_FAILURE);
				}

				hdrlen = ((hdrlen+7)/8) * 8;
				dstoptuhdrlen[ndstoptuhdr]= hdrlen;
		
				if( (dstoptuhdr[ndstoptuhdr]= malloc(hdrlen)) == NULL){
					puts("Not enough memory for Destination Options Header (Unfragmentable Part)");
					exit(EXIT_FAILURE);
				}

				ptrhdr= dstoptuhdr[ndstoptuhdr]+2;
				ptrhdrend= dstoptuhdr[ndstoptuhdr] + hdrlen;
		
				while( ptrhdr < ptrhdrend){

					if( (ptrhdrend-ptrhdr)>257)
						pad= 257;
					else
						pad= ptrhdrend-ptrhdr;

					if(!insert_pad_opt(ptrhdr, ptrhdrend, pad)){
						puts("Destination Options Header (Unfragmentable Part) Too Big");
						exit(EXIT_FAILURE);
					}

					ptrhdr = ptrhdr + pad;
				}

				*(dstoptuhdr[ndstoptuhdr]+1)= (hdrlen/8) - 1;
				ndstoptuhdr++;
				dstoptuhdr_f=1;
				break;

			case 'H':	/* Hop-by-Hop Options Header */
				if(nhbhopthdr >= MAX_HBH_OPT_HDR){
					puts("Too many Hop-by-Hop Options Headers");
					exit(EXIT_FAILURE);
				}

				hdrlen= atoi(optarg);
		
				if(hdrlen < 8){
					puts("Bad length in Hop-by-Hop Options Header");
					exit(EXIT_FAILURE);
				}
		    
				hdrlen = ((hdrlen+7)/8) * 8;
				hbhopthdrlen[nhbhopthdr]= hdrlen;
		
				if( (hbhopthdr[nhbhopthdr]= malloc(hdrlen)) == NULL){
					puts("Not enough memory for Hop-by-Hop Options Header");
					exit(EXIT_FAILURE);
				}

				ptrhdr= hbhopthdr[nhbhopthdr] + 2;
				ptrhdrend= hbhopthdr[nhbhopthdr] + hdrlen;
		
				while( ptrhdr < ptrhdrend){

					if( (ptrhdrend-ptrhdr)>257)
						pad= 257;
					else
						pad= ptrhdrend-ptrhdr;

					if(!insert_pad_opt(ptrhdr, ptrhdrend, pad)){
						puts("Hop-by-Hop Options Header Too Big");
						exit(EXIT_FAILURE);
					}

					ptrhdr = ptrhdr + pad;
				}

				*(hbhopthdr[nhbhopthdr]+1)= (hdrlen/8) - 1;
				nhbhopthdr++;
				hbhopthdr_f=1;
				break;

			case 'S':	/* Source Ethernet address */
				if(ether_pton(optarg, &(idata.hsrcaddr), sizeof(idata.hsrcaddr)) == 0){
					puts("Error in Source link-layer address.");
					exit(EXIT_FAILURE);
				}
		
				idata.hsrcaddr_f = 1;
				break;

			case 'D':	/* Destination Ethernet Address */
				if(ether_pton(optarg, &(idata.hdstaddr), sizeof(idata.hdstaddr)) == 0){
					puts("Error in Source link-layer address.");
					exit(EXIT_FAILURE);
				}
		
				idata.hdstaddr_f = 1;
				break;

			case 't':	/* NA Target address */
				if((charptr = strtok_r(optarg, "/", &lasts)) == NULL){
					puts("Target Address not valid");
					exit(EXIT_FAILURE);
				}

				if ( inet_pton(AF_INET6, charptr, &targetaddr) <= 0){
					puts("inet_pton(): Target Address not valid");
					exit(EXIT_FAILURE);
				}

				targetaddr_f = 1;
		
				if((charptr = strtok_r(NULL, " ", &lasts)) != NULL){
					targetpreflen = atoi(charptr);
		
					if(targetpreflen>128){
						puts("Prefix length error in Target Address");
						exit(EXIT_FAILURE);
					}

					sanitize_ipv6_prefix(&targetaddr, targetpreflen);
					targetprefix_f=1;
				}

				break;

			case 'r':	/* "Router" flag */
				router_f = ND_NA_FLAG_ROUTER;
				break;
	
			case 'o':	/* "Override" flag */
				override_f = ND_NA_FLAG_OVERRIDE;
				break;	    	    

			case 'c':	/* Solicited flag */
				solicited_f = ND_NA_FLAG_SOLICITED;
				break;
		
			case 'E':	/* Target link-layer option */
				tllaopt_f = 1;
				if(ether_pton(optarg, &linkaddr[nlinkaddr], sizeof(struct ether_addr)) == 0){
					puts("Error in Source link-layer address option.");
					exit(EXIT_FAILURE);
				}

				nlinkaddr++;		
				tllaopta_f=1;
				break;

			case 'e':	/* Add target link-layer option */
				tllaopt_f = 1;
				break;

			case 'j':	/* IPv6 Source Address (block) filter */
				if(filters.nblocksrc >= MAX_BLOCK_SRC){
					puts("Too many IPv6 Source Address (block) filters.");
					exit(EXIT_FAILURE);
				}
	    
				if((pref = strtok_r(optarg, "/", &lasts)) == NULL){
					printf("Error in IPv6 Source Address (block) filter number %u.\n", \
												filters.nblocksrc+1);
					exit(EXIT_FAILURE);
				}

				if ( inet_pton(AF_INET6, pref, &(filters.blocksrc[filters.nblocksrc])) <= 0){
					printf("Error in IPv6 Source Address (block) filter number %u.", \
											    filters.nblocksrc+1);
					exit(EXIT_FAILURE);
				}

				if((charptr = strtok_r(NULL, " ", &lasts)) == NULL){
		    			filters.blocksrclen[filters.nblocksrc] = 128;
				}
				else{
					filters.blocksrclen[filters.nblocksrc] = atoi(charptr);

					if(filters.blocksrclen[filters.nblocksrc]>128){
						printf("Length error in IPv6 Source Address (block) filter number %u.\n", \
													filters.nblocksrc+1);
						exit(EXIT_FAILURE);
		    			}
				}

				sanitize_ipv6_prefix(&(filters.blocksrc[filters.nblocksrc]), filters.blocksrclen[filters.nblocksrc]);
				(filters.nblocksrc)++;
				break;

			case 'k':	/* IPv6 Destination Address (block) filter */
				if(filters.nblockdst >= MAX_BLOCK_DST){
					puts("Too many IPv6 Destination Address (block) filters.");
					exit(EXIT_FAILURE);
				}

				if((pref = strtok_r(optarg, "/", &lasts)) == NULL){
					printf("Error in IPv6 Destination Address (block) filter number %u.\n", \
													filters.nblockdst+1);
					exit(EXIT_FAILURE);
				}

				if ( inet_pton(AF_INET6, pref, &(filters.blockdst[filters.nblockdst])) <= 0){
					printf("Error in IPv6 Source Address (block) filter number %u.", \
											    filters.nblockdst+1);
					exit(EXIT_FAILURE);
				}

				if((charptr = strtok_r(NULL, " ", &lasts)) == NULL){
					filters.blockdstlen[filters.nblockdst] = 128;
				}
				else{
					filters.blockdstlen[filters.nblockdst] = atoi(charptr);
		
					if(filters.blockdstlen[filters.nblockdst]>128){
						printf("Length error in IPv6 Source Address (block) filter number %u.\n", \
													    filters.nblockdst+1);
						exit(EXIT_FAILURE);
					}
				}
		
				sanitize_ipv6_prefix(&(filters.blockdst[filters.nblockdst]), filters.blockdstlen[filters.nblockdst]);
				(filters.nblockdst)++;
				break;

			case 'J':	/* Link Source Address (block) filter */
				if(filters.nblocklinksrc > MAX_BLOCK_LINK_SRC){
					puts("Too many link-layer Source Address (accept) filters.");
					exit(EXIT_FAILURE);
				}

				if(ether_pton(optarg, &(filters.blocklinksrc[filters.nblocklinksrc]), sizeof(struct ether_addr)) == 0){
					printf("Error in link-layer Source Address (blick) filter number %u.\n", \
												    filters.nblocklinksrc+1);
					exit(EXIT_FAILURE);
				}
		
				(filters.nblocklinksrc)++;
				break;

			case 'K':	/* Link Destination Address (block) filter */
				if(filters.nblocklinkdst > MAX_BLOCK_LINK_DST){
					puts("Too many link-layer Destination Address (block) filters.");
					exit(EXIT_FAILURE);
				}

				if(ether_pton(optarg, &(filters.blocklinkdst[filters.nblocklinkdst]), sizeof(struct ether_addr)) == 0){
					printf("Error in link-layer Destination Address (blick) filter number %u.\n", \
												    filters.nblocklinkdst+1);
					exit(EXIT_FAILURE);
				}
		
				filters.nblocklinkdst++;
				break;

			case 'b':	/* IPv6 Source Address (accept) filter */
				if(filters.nacceptsrc > MAX_ACCEPT_SRC){
					puts("Too many IPv6 Source Address (accept) filters.");
					exit(EXIT_FAILURE);
				}

				if((pref = strtok_r(optarg, "/", &lasts)) == NULL){
					printf("Error in IPv6 Source Address (accept) filter number %u.\n", \
												filters.nacceptsrc+1);
					exit(EXIT_FAILURE);
				}

				if ( inet_pton(AF_INET6, pref, &(filters.acceptsrc[filters.nacceptsrc])) <= 0){
					printf("Error in IPv6 Source Address (accept) filter number %u.\n", \
												filters.nacceptsrc+1);
					exit(EXIT_FAILURE);
				}
		
				if((charptr = strtok_r(NULL, " ", &lasts)) == NULL){
					filters.acceptsrclen[filters.nacceptsrc] = 128;
				}
				else{
					filters.acceptsrclen[filters.nacceptsrc] = atoi(charptr);

					if(filters.acceptsrclen[filters.nacceptsrc]>128){
						printf("Length error in IPv6 Source Address (accept) filter number %u.\n", \
														filters.nacceptsrc+1);
						exit(EXIT_FAILURE);
					}
				}

				sanitize_ipv6_prefix(&(filters.acceptsrc[filters.nacceptsrc]), filters.acceptsrclen[filters.nacceptsrc]);
				(filters.nacceptsrc)++;
				filters.acceptfilters_f=1;
				break;


			case 'g':	/* IPv6 Destination Address (accept) filter */
				if(filters.nacceptdst > MAX_ACCEPT_DST){
					puts("Too many IPv6 Destination Address (accept) filters.");
					exit(EXIT_FAILURE);
				}

				if((pref = strtok_r(optarg, "/", &lasts)) == NULL){
					printf("Error in IPv6 Destination Address (accept) filter number %u.\n", \
													filters.nacceptdst+1);
					exit(EXIT_FAILURE);
				}

				if ( inet_pton(AF_INET6, pref, &(filters.acceptdst[filters.nacceptdst])) <= 0){
					printf("Error in IPv6 Source Address (accept) filter number %u.\n", \
												    filters.nacceptdst+1);
					exit(EXIT_FAILURE);
				}

				if((charptr = strtok_r(NULL, " ", &lasts)) == NULL){
					filters.acceptdstlen[filters.nacceptdst] = 128;
				}
				else{
					filters.acceptdstlen[filters.nacceptdst] = atoi(charptr);
		
					if(filters.acceptdstlen[filters.nacceptdst] > 128){
						printf("Length error in IPv6 Source Address (accept) filter number %u.\n", \
													    filters.nacceptdst+1);
						exit(EXIT_FAILURE);
					}
				}
		
				sanitize_ipv6_prefix(&(filters.acceptdst[filters.nacceptdst]), filters.acceptdstlen[filters.nacceptdst]);
				(filters.nacceptdst)++;
				filters.acceptfilters_f=1;
				break;

			case 'B':	/* Link-layer Source Address (accept) filter */
				if(filters.nacceptlinksrc > MAX_ACCEPT_LINK_SRC){
					puts("Too many link-later Source Address (accept) filters.");
					exit(EXIT_FAILURE);
				}

				if(ether_pton(optarg, &(filters.acceptlinksrc[filters.nacceptlinksrc]), sizeof(struct ether_addr)) == 0){
					printf("Error in link-layer Source Address (accept) filter number %u.\n", \
											    filters.nacceptlinksrc+1);
					exit(EXIT_FAILURE);
				}
		
				(filters.nacceptlinksrc)++;
				filters.acceptfilters_f=1;
				break;

			case 'G':	/* Link Destination Address (accept) filter */
				if(filters.nacceptlinkdst > MAX_ACCEPT_LINK_DST){
					puts("Too many link-layer Destination Address (accept) filters.");
					exit(EXIT_FAILURE);
				}

				if(ether_pton(optarg, &(filters.acceptlinkdst[filters.nacceptlinkdst]), sizeof(struct ether_addr)) == 0){
					printf("Error in link-layer Destination Address (accept) filter number %u.\n",\
												    filters.nacceptlinkdst+1);
					exit(EXIT_FAILURE);
				}
		
				(filters.nacceptlinkdst)++;
				filters.acceptfilters_f=1;
				break;

			case 'w':	/* ND Target Address (block) filter */
				if(filters.nblocktarget > MAX_BLOCK_TARGET){
					puts("Too many Target Address (block) filters.");
					exit(EXIT_FAILURE);
				}
	    
				if((pref = strtok_r(optarg, "/", &lasts)) == NULL){
					printf("Error in Target Address (block) filter number %u.\n", filters.nblocktarget+1);
					exit(EXIT_FAILURE);
				}

				if ( inet_pton(AF_INET6, pref, &(filters.blocktarget[filters.nblocktarget])) <= 0){
					printf("Error in Target Address (block) filter number %u.\n", filters.nblocktarget+1);
					exit(EXIT_FAILURE);
				}

				if((charptr = strtok_r(NULL, " ", &lasts)) == NULL){
					filters.blocktargetlen[filters.nblocktarget] = 128;
				}
				else{
					filters.blocktargetlen[filters.nblocktarget] = atoi(charptr);
		
					if(filters.blocktargetlen[filters.nblocktarget]>128){
						printf("Length error in Target Address (block) filter number %u.\n", filters.nblocktarget+1);
						exit(EXIT_FAILURE);
					}
				}

				sanitize_ipv6_prefix(&(filters.blocktarget[filters.nblocktarget]), filters.blocktargetlen[filters.nblocktarget]);
				filters.nblocktarget++;
				break;

			case 'W':	/* ND Target Address (accept) filter */
				if(filters.naccepttarget >= MAX_ACCEPT_TARGET){
					puts("Too many Target Address (accept) filters.");
					exit(EXIT_FAILURE);
				}
	    
				if((pref = strtok_r(optarg, "/", &lasts)) == NULL){
					printf("Error in Target Address (accept) filter number %u.\n", filters.naccepttarget+1);
					exit(EXIT_FAILURE);
				}

				if ( inet_pton(AF_INET6, pref, &(filters.accepttarget[filters.naccepttarget])) <= 0){
					printf("Error in Target Address (accept) filter number %u.\n", filters.naccepttarget+1);
					exit(EXIT_FAILURE);
				}
		
				if((charptr = strtok_r(NULL, " ", &lasts)) == NULL){
					filters.accepttargetlen[filters.naccepttarget] = 128;
				}
				else{
					filters.accepttargetlen[filters.naccepttarget] = atoi(charptr);
		
					if(filters.accepttargetlen[filters.naccepttarget]>128){
						printf("Length error in Target Address (accept) filter number %u.\n", \
									    filters.naccepttarget+1);
						exit(EXIT_FAILURE);
					}
				}

				sanitize_ipv6_prefix(&(filters.accepttarget[filters.naccepttarget]), filters.accepttargetlen[filters.naccepttarget]);
				filters.naccepttarget++;
				filters.acceptfilters_f=1;
				break;

			case 'L':	/* "Listen mode */
				listen_f = 1;
				break;

			case 'T':	/* Flood targets */
				ntargets= atoi(optarg);
				if(ntargets == 0){
					puts("Invalid number of Target Addresses in option -T");
					exit(EXIT_FAILURE);
				}
		
				floodt_f= 1;
				break;

			case 'F':	/* Flood sources */
				nsources= atoi(optarg);
				if(nsources == 0){
					puts("Invalid number of sources in option -F");
					exit(EXIT_FAILURE);
				}
		
				floods_f= 1;
				break;

			case 'l':	/* "Loop mode */
				loop_f = 1;
				break;

			case 'z':	/* Sleep option */
				nsleep=atoi(optarg);
				if(nsleep==0){
					puts("Invalid number of seconds in '-z' option");
					exit(EXIT_FAILURE);
				}
	
				sleep_f=1;
				break;

			case 'v':	/* Be verbose */
				idata.verbose_f++;
				break;
		
			case 'h':	/* Help */
				print_help();
				exit(EXIT_FAILURE);
				break;

			default:
				usage();
				exit(EXIT_FAILURE);
				break;	
		} /* switch */
	} /* while(getopt) */

	if(geteuid()) {
		puts("na6 needs root privileges to run.");
		exit(EXIT_FAILURE);
	}

	if(!idata.iface_f){
		puts("Must specify the network interface with the -i option");
		exit(EXIT_FAILURE);
	}

	if(load_dst_and_pcap(&idata, LOAD_PCAP_ONLY) == FAILURE){
		puts("Error while learning Souce Address and Next Hop");
		exit(EXIT_FAILURE);
	}

	release_privileges();

	if(listen_f && loop_f){
		puts("'Error: listen' mode and 'loop' mode are incompatible");
		exit(EXIT_FAILURE);
	}

	if(listen_f && floodt_f){
		puts("Error: 'listen' mode and 'flood targets' are incompatible");
		exit(EXIT_FAILURE);
	}

	if(pcap_compile(idata.pfd, &pcap_filter, PCAP_ICMPV6_NS_FILTER, 0, PCAP_NETMASK_UNKNOWN) == -1){
		printf("pcap_compile(): %s", pcap_geterr(idata.pfd));
		exit(EXIT_FAILURE);
	}

   
	if(pcap_setfilter(idata.pfd, &pcap_filter) == -1){
		printf("pcap_setfilter(): %s", pcap_geterr(idata.pfd));
		exit(EXIT_FAILURE);
	}

	pcap_freecode(&pcap_filter);

	srandom(time(NULL));
    
	if(!(idata.srcaddr_f) && !floods_f){
		/* When randomizing a link-local IPv6 address, select addresses that belong to the
		   prefix fe80::/64 (that's what a link-local address looks-like in legitimate cases).
		   The KAME implementation discards addresses in which the second high-order 16 bits
		   (srcaddr.s6_addr16[1] in our case) are not zero.
		 */  

		if(idata.ip6_local_flag){
			idata.srcaddr= idata.ip6_local;
		}
		else{
			if ( inet_pton(AF_INET6, "fe80::", &(idata.srcaddr)) <= 0){
				puts("inet_pton(): Error when converting address");
				exit(EXIT_FAILURE);
			}

			randomize_ipv6_addr(&(idata.srcaddr), &(idata.srcaddr), 64);
		}
	}

	/*
	   If the flood option ("-F") has been specified, but no prefix has been specified,
	   select the random Source Addresses from the link-local unicast prefix (fe80::/64).
	 */
	if(floods_f && !idata.srcprefix_f){
		if ( inet_pton(AF_INET6, "fe80::", &(idata.srcaddr)) <= 0){
			puts("inet_pton(): Error when converting address");
			exit(EXIT_FAILURE);
		}

		randomize_ipv6_addr(&(idata.srcaddr), &(idata.srcaddr), 64);
	
		idata.srcpreflen=64;
	}

	if(!idata.dstaddr_f){		/* Destination Address defaults to all-nodes (ff02::1) */
		if( inet_pton(AF_INET6, ALL_NODES_MULTICAST_ADDR, &(idata.dstaddr)) <= 0){
			puts("inet_pton(): Error converting all-nodes multicast address");
			exit(EXIT_FAILURE);
		}
	}

	if(!idata.hdstaddr_f)		/* Destination link-layer address defaults to all-nodes */
		if(ether_pton(ETHER_ALLNODES_LINK_ADDR, &(idata.hdstaddr), sizeof(idata.hdstaddr)) == 0){
			puts("ether_pton(): Error converting all-nodes multicast address");
			exit(EXIT_FAILURE);
		}
    
	if(tllaopt_f && !tllaopta_f){	/* The value of the target link-layer address      */
		linkaddr[0] = idata.hsrcaddr;		/* option defaults to the Ethernet Source Address  */
		nlinkaddr++;
	}


	/*
	   If the flood target option ("-T") was specified, but no prefix was specified,
	   select the random Target Addresses from the link-local unicast prefix (fe80::/64).
	 */
	if(floodt_f && !targetprefix_f){
		if ( inet_pton(AF_INET6, "fe80::", &targetaddr) <= 0){
			puts("inet_pton(): Error when converting address");
			exit(EXIT_FAILURE);
		}

		randomize_ipv6_addr(&targetaddr, &targetaddr, 64);
		targetpreflen=64;
	}

	if(!floods_f)
		nsources=1;

	if(!floodt_f)
		ntargets=1;

	if(!sleep_f)
		nsleep=1;

	if(!idata.fragh_f && dstoptuhdr_f){
		puts("Dst. Options Header (Unfragmentable Part) set, but Fragmentation not specified");
		exit(EXIT_FAILURE);
	}
    
	if(idata.verbose_f){
		print_attack_info(&idata);
	}

	/* Set initial contents of the attack packet */
	init_packet_data(&idata);
    
	/* Fire a Neighbor Advertisement if a IPv6 Destination Address or an Ethernet
	 * Destination Address were specified
	 */
	if((idata.dstaddr_f || idata.hdstaddr_f) && (targetaddr_f || floodt_f)){
		if(send_packet(&idata, NULL, NULL) == FAILURE){
			puts("Error while sending packet");
			exit(EXIT_FAILURE);
		}

		if(idata.verbose_f)    
			puts("Initial attack packet(s) sent successfully.");

		if(loop_f){
			if(idata.verbose_f)
				printf("Now sending Neighbor Advertisements every %u second%s...\n", nsleep, \
											((nsleep>1)?"s":""));
			while(loop_f){
				sleep(nsleep);
				if(send_packet(&idata, NULL, NULL) == FAILURE){
					puts("Error while sending packet");
					exit(EXIT_FAILURE);
				}
	 		}

			exit(EXIT_SUCCESS);
		}
	}

	if(listen_f){
		FD_ZERO(&sset);
		FD_SET(idata.fd, &sset);

		if(idata.verbose_f){
			print_filters(&idata, &filters);
			puts("Listening to incoming ICMPv6 Neighbor Solicitation messages...");
		}

		while(listen_f){
			rset= sset;

#if defined(sun) || defined(__sun) || defined(__linux__)
			timeout.tv_usec=1000;
			timeout.tv_sec= 0;
			if((sel=select(idata.fd+1, &rset, NULL, NULL, &timeout)) == -1){
#else
			if((sel=select(idata.fd+1, &rset, NULL, NULL, NULL)) == -1){
#endif
				if(errno == EINTR){
					continue;
				}
				else{
					puts("Error in select()");
					exit(EXIT_FAILURE);
				}
			}

#if defined(sun) || defined(__sun) || defined(__linux__)
			if(TRUE){
#else
			if(sel && FD_ISSET(idata.fd, &rset)){
#endif
				/* Read a Neighbor Solicitation message */
				if((r=pcap_next_ex(idata.pfd, &pkthdr, &pktdata)) == -1){
					printf("pcap_next_ex(): %s", pcap_geterr(idata.pfd));
					exit(EXIT_FAILURE);
				}
				else if(r == 1 && pktdata != NULL){
					/* XXX Code assumes no IPv6 Extension Headers */
					pkt_ether = (struct ether_header *) pktdata;
					pkt_ipv6 = (struct ip6_hdr *)((char *) pkt_ether + idata.linkhsize);
					pkt_ns = (struct nd_neighbor_solicit *) ((char *) pkt_ipv6 + MIN_IPV6_HLEN);
					pkt_icmp6= (struct icmp6_hdr *) pkt_ns;

					/* XXX This should probably be removed when pcap filter problem is solved */
					if(pkt_ipv6->ip6_nxt != IPPROTO_ICMPV6 || pkt_icmp6->icmp6_type != ND_NEIGHBOR_SOLICIT || \
						pkt_icmp6->icmp6_code != 0)
						continue;

					accepted_f=0;

					if(idata.type == DLT_EN10MB && !(idata.flags & IFACE_LOOPBACK)){
						if(filters.nblocklinksrc){
							if(match_ether(filters.blocklinksrc, filters.nblocklinksrc, &(pkt_ether->src))){
								if(idata.verbose_f>1)
									print_filter_result(&idata, pktdata, BLOCKED);
		
								continue;
							}
						}

						if(filters.nblocklinkdst){
							if(match_ether(filters.blocklinkdst, filters.nblocklinkdst, &(pkt_ether->dst))){
								if(idata.verbose_f>1)
									print_filter_result(&idata, pktdata, BLOCKED);
		
								continue;
							}
						}
					}
	
					if(filters.nblocksrc){
						if(match_ipv6(filters.blocksrc, filters.blocksrclen, filters.nblocksrc, &(pkt_ipv6->ip6_src))){
							if(idata.verbose_f>1)
								print_filter_result(&idata, pktdata, BLOCKED);
		
							continue;
						}
					}
	
					if(filters.nblockdst){
						if(match_ipv6(filters.blockdst, filters.blockdstlen, filters.nblockdst, &(pkt_ipv6->ip6_dst))){
							if(idata.verbose_f>1)
								print_filter_result(&idata, pktdata, BLOCKED);
		
							continue;
						}
					}

					if(filters.nblocktarget){
						if(match_ipv6(filters.blocktarget, filters.blocktargetlen, filters.nblocktarget, &(pkt_ns->nd_ns_target))){
							if(idata.verbose_f>1)
								print_filter_result(&idata, pktdata, BLOCKED);
		
							continue;
						}
					}

					if(idata.type == DLT_EN10MB && !(idata.flags & IFACE_LOOPBACK)){	
						if(filters.nacceptlinksrc){
							if(match_ether(filters.acceptlinksrc, filters.nacceptlinksrc, &(pkt_ether->src)))
								accepted_f=1;
						}

						if(filters.nacceptlinkdst && !accepted_f){
							if(match_ether(filters.acceptlinkdst, filters.nacceptlinkdst, &(pkt_ether->dst)))
								accepted_f= 1;
						}
					}

					if(filters.nacceptsrc && !accepted_f){
						if(match_ipv6(filters.acceptsrc, filters.acceptsrclen, filters.nacceptsrc, &(pkt_ipv6->ip6_src)))
							accepted_f= 1;
					}

					if(filters.nacceptdst && !accepted_f){
						if(match_ipv6(filters.acceptdst, filters.acceptdstlen, filters.nacceptdst, &(pkt_ipv6->ip6_dst)))
							accepted_f=1;
					}

					if(filters.naccepttarget && !accepted_f){
						if(match_ipv6(filters.accepttarget, filters.accepttargetlen, filters.naccepttarget, &(pkt_ns->nd_ns_target)))
							accepted_f=1;
					}
	
					if(filters.acceptfilters_f && !accepted_f){
						if(idata.verbose_f>1)
							print_filter_result(&idata, pktdata, BLOCKED);

						continue;
					}

					if(idata.verbose_f)
						print_filter_result(&idata, pktdata, ACCEPTED);

					/* Send a Neighbor Advertisement */
					if(send_packet(&idata, pkthdr, pktdata) == FAILURE){
						puts("Error while sending packet");
						exit(EXIT_FAILURE);
					}
				}
			}
		}
    
		exit(EXIT_SUCCESS);
	}
    

	if(!((idata.dstaddr_f || idata.hdstaddr_f) && (targetaddr_f || floodt_f)) && !listen_f){
		puts("Error: Nothing to send! (Destination Address or ND Target Address missing?)");
		exit(EXIT_FAILURE);
	}

	exit(EXIT_SUCCESS);
}



/*
 * Function: init_packet_data()
 *
 * Initialize the contents of the attack packet (Ethernet header, IPv6 Header, and ICMPv6 header)
 * that are expected to remain constant for the specified attack.
 */
void init_packet_data(struct iface_data *idata){
	struct dlt_null *dlt_null;
	ethernet= (struct ether_header *) buffer;
	dlt_null= (struct dlt_null *) buffer;
	v6buffer = buffer + idata->linkhsize;
	ipv6 = (struct ip6_hdr *) v6buffer;

	if(idata->type == DLT_EN10MB){
		ethernet->ether_type = htons(ETHERTYPE_IPV6);

	if(!(idata->flags & IFACE_LOOPBACK)){
			ethernet->src = idata->hsrcaddr;
			ethernet->dst = idata->hdstaddr;
		}
	}
	else if(idata->type == DLT_NULL){
		dlt_null->family= PF_INET6;
	}
#if defined (__OpenBSD__)
	else if(idata->type == DLT_LOOP){
		dlt_null->family= htonl(PF_INET6);
	}
#endif

	ipv6->ip6_flow=0;
	ipv6->ip6_vfc= 0x60;
	ipv6->ip6_hlim= hoplimit;
	ipv6->ip6_src= idata->srcaddr;
	ipv6->ip6_dst= idata->dstaddr;

	prev_nh = (unsigned char *) &(ipv6->ip6_nxt);

	ptr = (unsigned char *) v6buffer + MIN_IPV6_HLEN;
    
	if(hbhopthdr_f){
		hbhopthdrs=0;
	
		while(hbhopthdrs < nhbhopthdr){
			if((ptr+ hbhopthdrlen[hbhopthdrs]) > (v6buffer+ idata->mtu)){
				puts("Packet too large while processing HBH Opt. Header");
				exit(EXIT_FAILURE);
			}
	    
			*prev_nh = IPPROTO_HOPOPTS;
			prev_nh = ptr;
			memcpy(ptr, hbhopthdr[hbhopthdrs], hbhopthdrlen[hbhopthdrs]);
			ptr = ptr + hbhopthdrlen[hbhopthdrs];
			hbhopthdrs++;
		}
	}

	if(dstoptuhdr_f){
		dstoptuhdrs=0;
	
		while(dstoptuhdrs < ndstoptuhdr){
			if((ptr+ dstoptuhdrlen[dstoptuhdrs]) > (v6buffer+ idata->mtu)){
				puts("Packet too large while processing Dest. Opt. Header (Unfrag. Part)");
				exit(EXIT_FAILURE);
			}

			*prev_nh = IPPROTO_DSTOPTS;
			prev_nh = ptr;
			memcpy(ptr, dstoptuhdr[dstoptuhdrs], dstoptuhdrlen[dstoptuhdrs]);
			ptr = ptr + dstoptuhdrlen[dstoptuhdrs];
			dstoptuhdrs++;
		}
	}

	/* Everything that follows is the Fragmentable Part of the packet */
	fragpart = ptr;

	if(idata->fragh_f){
		/* Check that we are able to send the Unfragmentable Part, together with a 
		   Fragment Header and a chunk data over our link layer
		 */
		if( (fragpart+sizeof(fraghdr)+nfrags) > (v6buffer+idata->mtu)){
			printf("Unfragmentable part too large for current MTU (%u bytes)\n", idata->mtu);
			exit(EXIT_FAILURE);
		}

		/* We prepare a separete Fragment Header, but we do not include it in the packet to be sent.
		   This Fragment Header will be used (an assembled with the rest of the packet by the 
		   send_packet() function.
		*/
		memset(&fraghdr, 0, FRAG_HDR_SIZE);
		*prev_nh = IPPROTO_FRAGMENT;
		prev_nh = (unsigned char *) &fraghdr;
	}

	if(dstopthdr_f){
		dstopthdrs=0;
	
		while(dstopthdrs < ndstopthdr){
			if((ptr+ dstopthdrlen[dstopthdrs]) > (v6buffer+idata->max_packet_size)){
			puts("Packet too large while processing Dest. Opt. Header (should be using the Frag. option?)");
			exit(EXIT_FAILURE);
			}
    
			*prev_nh = IPPROTO_DSTOPTS;
			prev_nh = ptr;
			memcpy(ptr, dstopthdr[dstopthdrs], dstopthdrlen[dstopthdrs]);
			ptr = ptr + dstopthdrlen[dstopthdrs];
			dstopthdrs++;
		}
	}


	*prev_nh = IPPROTO_ICMPV6;

	if( (ptr+sizeof(struct nd_neighbor_advert)) > (v6buffer+idata->max_packet_size)){
		puts("Packet too large while inserting Neighbor Advertisement header (should be using Frag. option?)");
		exit(EXIT_FAILURE);
	}

	na= (struct nd_neighbor_advert *) ptr;

	na->nd_na_type = ND_NEIGHBOR_ADVERT;
	na->nd_na_code = 0;
	na->nd_na_flags_reserved = router_f | solicited_f | override_f;
	na->nd_na_target = targetaddr;
    
	ptr += sizeof(struct nd_neighbor_advert);

	if(tllaopt_f && nlinkaddr==1){
		if( (ptr+sizeof(struct nd_opt_tlla)) <= (v6buffer+idata->max_packet_size) ){
			tllaopt = (struct nd_opt_tlla *) ptr;
			tllaopt->type= ND_OPT_TARGET_LINKADDR;
			tllaopt->length= TLLA_OPT_LEN;
			memcpy(tllaopt->address, linkaddr[0].a, ETH_ALEN);
			ptr += sizeof(struct nd_opt_tlla);
		}
		else{
			puts("Packet Too Large while processing target link-layer address option");
			exit(EXIT_FAILURE);
		}
	}

	startofprefixes=ptr;
}



/*
 * Function: send_packet()
 *
 * Initialize the remaining fields of the Neighbor Advertisement Message, and
 * send the attack packet(s).
 */
int send_packet(struct iface_data *idata, struct pcap_pkthdr *pkthdr, const u_char *pktdata){
	if(pktdata == NULL){
		sources=0;
	}
	else{   /* Sending a response to a Neighbor Solicitation message */
		pkt_ether = (struct ether_header *) pktdata;
		pkt_ipv6 = (struct ip6_hdr *)((char *) pkt_ether + idata->linkhsize);
		pkt_ns = (struct nd_neighbor_solicit *) ((char *) pkt_ipv6 + MIN_IPV6_HLEN);
	
		/* If the IPv6 Source Address of the incoming Neighbor Solicitation is the unspecified 
		   address (::), the Neighbor Advertisement must be directed to the IPv6 all-nodes 
		   multicast address (and the Ethernet Destination address should be 33:33:33:00:00:01). 
		   Otherwise, the Neighbor Advertisement is sent to the IPv6 Source Address (and 
		   Ethernet Source Address) of the incoming Neighbor Solicitation message
		 */
		pkt_ipv6addr = &(pkt_ipv6->ip6_src);

		na->nd_na_flags_reserved = router_f | solicited_f | override_f;

		if(IN6_IS_ADDR_UNSPECIFIED(pkt_ipv6addr)){
			if ( inet_pton(AF_INET6, ALL_NODES_MULTICAST_ADDR, &(ipv6->ip6_dst)) <= 0){
				puts("inetr_pton(): Error converting all-nodes multicast address");
				return(FAILURE);
			}

			if(ether_pton(ETHER_ALLNODES_LINK_ADDR, &(ethernet->dst), ETHER_ADDR_LEN) == 0){
				puts("ether_pton(): Error converting all-nodes link-local address");
				return(FAILURE);
			}
		}
		else{
			ipv6->ip6_dst = pkt_ipv6->ip6_src;
			ethernet->dst = pkt_ether->src;

			/* 
			   Set the "Solicited" flag if NS was sent from an address other than the unspecified
			   address (i.e., the response will be unicast). 
			 */ 

			na->nd_na_flags_reserved = na->nd_na_flags_reserved | ND_NA_FLAG_SOLICITED;
		}

		pkt_ipv6addr = &(pkt_ipv6->ip6_dst);

		/* 
		   If the Neighbor Solicitation message was directed to a unicast address (unlikely), the
		   IPv6 Source Address and the Ethernet Source Address of the Neighbor Advertisement are set
		   to the IPv6 Destination Address and the Ethernet Destination Address	of the incoming
		   Neighbor Solicitation, respectively. Otherwise, the IPv6 Source Address is set to the
		   ND Target Address (unless a specific IPv6 Source Address was specified with the "-s"
		   option), and the Ethernet is set to that specified by the "-S" option (or randomized).
		 */
		if(IN6_IS_ADDR_MULTICAST(pkt_ipv6addr)){
			if( !idata->srcaddr_f && IN6_IS_ADDR_LINKLOCAL(&(pkt_ns->nd_ns_target)) )
				ipv6->ip6_src = pkt_ns->nd_ns_target;
			else
				ipv6->ip6_src = idata->srcaddr;

			ethernet->src = idata->hsrcaddr;
			sources=0;
			multicastdst_f=1;
		}
		else{
			ipv6->ip6_src = pkt_ipv6->ip6_dst;
			ethernet->src = pkt_ether->dst;
			sources=nsources;
			multicastdst_f=0;
		}

		na->nd_na_target= pkt_ns->nd_ns_target;
	}


	do{
		if(floods_f && (pktdata==NULL || (pktdata != NULL && multicastdst_f))){
			/* 
			   Randomizing the IPv6 Source address based on the prefix specified by 
			   "srcaddr" and prefix length.
			 */  
			randomize_ipv6_addr(&(ipv6->ip6_src), &(idata->srcaddr), idata->srcpreflen);

			if(!idata->hsrcaddr_f){
				randomize_ether_addr(&(ethernet->src));
			}
	    
			if(tllaopt_f && !tllaopta_f){
				memcpy(tllaopt->address, ethernet->src.a, ETH_ALEN);
			}
		}

		targets=0;

		do{
			if(floodt_f){
				/* 
				   Randomizing the ND Target Address based on the prefix specified by "targetaddr" 
				   and targetpreflen.
				 */  
				randomize_ipv6_addr(&(na->nd_na_target), &targetaddr, targetpreflen);
			}

			/*
			 * If a single target link-layer address option is to be included, it is included
			 * by init_packet_data()
			 */
			if(nlinkaddr==1)
				linkaddrs=1;
			else
				linkaddrs=0;

			do{
				newdata_f=0;
				ptr=startofprefixes;

				while(linkaddrs<nlinkaddr && ((ptr+sizeof(struct nd_opt_tlla))-v6buffer)<=idata->max_packet_size){
					tllaopt = (struct nd_opt_tlla *) ptr;
					tllaopt->type= ND_OPT_TARGET_LINKADDR;
					tllaopt->length= TLLA_OPT_LEN;
					memcpy(tllaopt->address, linkaddr[linkaddrs].a, ETH_ALEN);
					ptr += sizeof(struct nd_opt_tlla);
					linkaddrs++;
					newdata_f=1;
				}

				na->nd_na_cksum = 0;
				na->nd_na_cksum = in_chksum(v6buffer, na, ptr-((unsigned char *)na), IPPROTO_ICMPV6);


				if(!idata->fragh_f){
					ipv6->ip6_plen = htons((ptr - v6buffer) - MIN_IPV6_HLEN);

					if((nw=pcap_inject(idata->pfd, buffer, ptr - buffer)) == -1){
						printf("pcap_inject(): %s\n", pcap_geterr(idata->pfd));
						return(FAILURE);
					}

					if(nw != (ptr-buffer)){
						printf("pcap_inject(): only wrote %lu bytes (rather than %lu bytes)\n", (LUI) nw, \
																					(LUI) (ptr-buffer));
						return(FAILURE);
					}
				}
				else{
					ptrend= ptr;
					ptr= fragpart;
					fptr = fragbuffer;
					fipv6 = (struct ip6_hdr *) (fragbuffer + ETHER_HDR_LEN);
					fptrend = fptr + ETHER_HDR_LEN+MIN_IPV6_HLEN+MAX_IPV6_PAYLOAD;
					memcpy(fptr, buffer, fragpart-buffer);
					fptr = fptr + (fragpart-buffer);

					if( (fptr+FRAG_HDR_SIZE)> fptrend){
						puts("Unfragmentable Part is Too Large");
						return(FAILURE);
					}

					memcpy(fptr, (char *) &fraghdr, FRAG_HDR_SIZE);
					fh= (struct ip6_frag *) fptr;
					fh->ip6f_ident=random();
					startoffragment = fptr + FRAG_HDR_SIZE;

					/*
					 * Check that the selected fragment size is not larger than the largest 
					 * fragment size that can be sent
					 */
					if(nfrags <= (fptrend - fptr))
						fragsize=nfrags;
					else
						fragsize= (fptrend-fptr) & IP6F_OFF_MASK;

					m=IP6F_MORE_FRAG;

					while((ptr< ptrend) && m==IP6F_MORE_FRAG){
						fptr= startoffragment;

						if( (ptrend-ptr) <= fragsize){
							fragsize= ptrend-ptr;
							m=0;
						}

						memcpy(fptr, ptr, fragsize);
						fh->ip6f_offlg = (htons(ptr-fragpart) & IP6F_OFF_MASK) | m;
						ptr+=fragsize;
						fptr+=fragsize;

						fipv6->ip6_plen = htons((fptr - fragbuffer) - MIN_IPV6_HLEN - ETHER_HDR_LEN);
		
						if((nw=pcap_inject(idata->pfd, fragbuffer, fptr - fragbuffer)) == -1){
							printf("pcap_inject(): %s\n", pcap_geterr(idata->pfd));
							return(FAILURE);
						}

						if(nw != (fptr- fragbuffer)){
							printf("pcap_inject(): only wrote %lu bytes (rather than %lu bytes)\n"\
													, (LUI) nw, (LUI) (ptr-buffer));
							return(FAILURE);
						}
					}
				}
			}while(linkaddrs<nlinkaddr && newdata_f);

			targets++;

		}while(targets<ntargets);

		sources++;
	}while(sources<nsources);

	return(SUCCESS);
}



/*
 * Function: usage()
 *
 * Prints the syntax of the na6 tool
 */
void usage(void){
    puts("usage: na6 -i INTERFACE [-s SRC_ADDR[/LEN]] [-d DST_ADDR] [-S LINK_SRC_ADDR] "
	 "[-y FRAG_SIZE] [-u DST_OPT_HDR_SIZE] [-U DST_OPT_U_HDR_SIZE] [-H HBH_OPT_HDR_SIZE] "
	 "[-D LINK-DST-ADDR] [-t TARGET_ADDR[/LEN]] [-r] [-c] [-o] [-E LINK_ADDR] [-e] "
	 "[-j PREFIX[/LEN]] [-k PREFIX[/LEN]] [-J LINK_ADDR] [-K LINK_ADDR] [-w PREFIX[/LEN]] "
	 "[-b PREFIX[/LEN]] [-g PREFIX[/LEN]] [-B LINK_ADDR] [-G LINK_ADDR] [-W PREFIX[/LEN]] "
	 "[-F N_SOURCES] [-T N_TARGETS] [-L | -l] [-z] [-v] [-V] [-h]");
}


/*
 * Function: print_help()
 *
 * Prints help information for the na6 tool
 */
void print_help(void){
	puts(SI6_TOOLKIT);
	puts("na6: Security Assessment tool for attack vectors based on NA messages\n");
	usage();
    
    puts("\nOPTIONS:\n"
	"  --interface, -i            Network interface\n"
	"  --src-address, -s          IPv6 Source Address\n"
	"  --dst-address, -d          IPv6 Destination Address\n"
	"  --frag-hdr. -y             Fragment Header\n"
	"  --dst-opt-hdr, -u          Destination Options Header (Fragmentable Part)\n"
	"  --dst-opt-u-hdr, -U        Destination Options Header (Unfragmentable Part)\n"
	"  --hbh-opt-hdr, -H          Hop by Hop Options Header\n"
	"  --link-src-address, -S     Link-layer Destination Address\n"
	"  --link-dst-address, -D     Link-layer Source Address\n"
	"  --target, -t               ND IPv6 Target Address\n"
	"  --target-lla-opt, -E       Source link-layer address option\n"
	"  --add-tlla-opt, -e         Add Source link-layer address option\n"
	"  --router, -r               Set the 'Router Flag'\n"
	"  --solicited, -c            Set the 'Solicited' flag\n"
	"  --override, -o             Set the 'Override' flag\n"
	"  --block-src, -j            Block IPv6 Source Address prefix\n"
	"  --block-dst, -k            Block IPv6 Destination Address prefix\n"
	"  --block-link-src, -J       Block Ethernet Source Address\n"
	"  --block-link-dst, -K       Block Ethernet Destination Address\n"
	"  --block-target, -w         Block ND Target IPv6 prefix\n"
	"  --accept-src, -b           Accept IPv6 Source Addres prefix\n"
	"  --accept-dst, -g           Accept IPv6 Destination Addres prefix\n"
	"  --accept-link-src, -B      Accept Ethernet Source Address\n"
	"  --accept-link-dst, -G      Accept Ethernet Destination Address\n"
	"  --accept-target, -W        Accept ND Target IPv6 prefix\n"
	"  --flood-targets, -T        Flood with NA's for multiple Target Addresses\n"
	"  --flood-sources, -F        Number of Source Addresses to forge randomly\n"
	"  --listen, -L               Listen to Neighbor Solicitation messages\n"
	"  --loop, -l                 Send periodic Neighbor Advertisements\n"
	"  --sleep, -z                Pause between sending NA messages\n"
	"  --help, -h                 Print help for the na6 tool\n"
	"  --verbose, -v              Be verbose\n"
	"\n"
	"Programmed by Fernando Gont for SI6 Networks <http://www.si6networks.com>\n"
	"Please send any bug reports to <*****@*****.**>\n"
	);
}
Esempio n. 28
0
int main (int argc, char *argv[])
{
	char * device;
	char errbuf[PCAP_ERRBUF_SIZE];

	char * bpf_s;
	char * bpf_default = BPF_DEFAULT;
	struct bpf_program bpf;

#if __DEBUG__
	char *       dump_fname;
	unsigned int dump_fname_sz;
#endif

	struct sigaction act;

	int i;
#define OPT_DEVICE      (0x1 << 0)
#define OPT_PROMISCUOUS (0x1 << 1)
#define OPT_BPF         (0x1 << 2)
	uint8_t opt_flags;

	opt_flags = 0;
	memset(errbuf, 0, PCAP_ERRBUF_SIZE);

	while ((i = getopt(argc, argv, "hvf:pi:")) != -1) {
		switch(i) {
			case 'h':
				fprintf(stderr,
					"Use: %s [-h] [-v] [-f bpf] [-p] -i interface\n", argv[0]);
				return -1;
				break;
			case 'v':
				fprintf(stderr, "Build:\t%s\t%s\n", __DATE__, __TIME__);
				return -1;
				break;
			case 'f':
				bpf_s = optarg;
				opt_flags |= OPT_BPF;
				break;
			case 'p':
				opt_flags |= OPT_PROMISCUOUS;
				break;
			case 'i':
				device = optarg;
				opt_flags |= OPT_DEVICE;
				break;
			default:
				break;
		}
	}

	if (!(opt_flags & OPT_DEVICE)) {
		fprintf(stderr, "[FATAL] Missing target interface. Try with -h.\n");
		return -1;
	}

#if __DEBUG__
#if !__BIG_ENDIAN__
	fprintf(stderr, "LITTLE_ENDIAN\n");
#else
	fprintf(stderr, "BIG_ENDIAN\n");
#endif
#endif

	fprintf(stdout, "[*] PID: %u\n", getpid());

	fprintf(stdout, "[*] Device: '%s'\n", device);

	/* BPF is not set. We'll use the default. */
	if (!(opt_flags & OPT_BPF)) {
		bpf_s = bpf_default;
		opt_flags |= OPT_BPF;
	}

	fprintf(stdout, "[*] Promiscuous: %s%d\033[0m\n",
		(PROMISCUOUS?"\033[1;32m":"\033[1;31m"), PROMISCUOUS);

	if (!(pcap_handle =
		pcap_open_live(device, SNAPLEN, PROMISCUOUS, PCAP_TIMEOUT, errbuf))) {
		fprintf(stderr, "[FATAL] %s\n", errbuf);
		return -1;
	}

	if (opt_flags & OPT_BPF) {
		fprintf(stdout, "[*] BPF: '\033[1;32m%s\033[0m'\n", bpf_s);
	} else {
		fprintf(stdout, "[*] BPF: \033[1;31mNONE\033[0m\n");
	}

	if (opt_flags & OPT_BPF) {
		if (pcap_compile(pcap_handle, &bpf, BPF, BPF_OPTIMIZE,
			PCAP_NETMASK_UNKNOWN) == -1) {
			fprintf(stderr, "[FATAL] Couldn't parse filter. %s\n",
				pcap_geterr(pcap_handle));
			pcap_close(pcap_handle);
			return -1;
		}

		if (pcap_setfilter(pcap_handle, &bpf) == -1) {
			fprintf(stderr, "[FATAL] Couldn't install filter. %s\n",
			pcap_geterr(pcap_handle));
			pcap_close(pcap_handle);
			return -1;
		}

		pcap_freecode(&bpf);
	}

	act.sa_handler = signal_handler;
	sigemptyset (&act.sa_mask);
	act.sa_flags = 0;

	if (sigaction(SIGINT, &act, NULL)) {
		perror("sigaction");
		fprintf(stderr,
			"[WARNING] Failed to set signal handler for SIGINT.\n");
	}

	if (sigaction(SIGTERM, &act, NULL)) {
		perror("sigaction");
		fprintf(stderr,
			"[WARNING] Failed to set signal handler for SIGTERM.\n");
	}

	if (sigaction(SIGUSR1, &act, NULL)) {
		perror("sigaction");
		fprintf(stderr,
			"[WARNING] Failed to set signal handler for SIGUSR1.\n");
	}

#if __WITH_THREADS__
	if (pthread_create(&my_thread, NULL, &status_thread, NULL)) {
		fprintf(stderr, "[WARNING] Failed to create thread.\n");
	}
#endif

#if __DEBUG__
	dump_fname_sz = strlen(device) + strlen(".pcap") + 1;
	if ((dump_fname = malloc(sizeof(char) * dump_fname_sz)) == NULL) {
		perror("malloc");
		return -1;
	}
	snprintf(dump_fname, dump_fname_sz, "%s%s", device, ".pcap");
	if (!(pcap_dumper_handle = pcap_dump_open(pcap_handle, dump_fname))) {
		pcap_geterr(pcap_handle);
	}
	free(dump_fname);
#endif

	fprintf(stdout, "Capturing ...\n");

	if (pcap_loop(pcap_handle, -1, &my_pcap_handler, NULL) == -1) {
		fprintf(stderr, "[FATAL] pcap_loop failed. %s\n",
			pcap_geterr(pcap_handle));
	}

	pcap_close(pcap_handle);

#if __DEBUG__
	pcap_dump_close(pcap_dumper_handle);
#endif

#if __WITH_THREADS__
	if (pthread_cancel(my_thread)) {
		fprintf(stderr, "[WARNING] Failed to cancel thread.\n");
	}
	if (pthread_join(my_thread, &my_thread_retval)) {
		fprintf(stderr, "[WARNING] Failed to join thread.\n");
	}
	if (my_thread_retval != PTHREAD_CANCELED) {
		fprintf(stderr, "[WARNING] Thread hasn't been canceled.\n");
	}
#endif

	fprintf(stdout, "Goodbye\n");

	return 0;
}
Esempio n. 29
0
int main(int argc, char *argv[])
{
	char *dev = argv[1];		/* Device to sniff on  */
	char errbuf[PCAP_ERRBUF_SIZE];	/* Error string  */
	pcap_t *handle;			/* Session handle  */
	struct bpf_program fp;		/* The compiled filter expression */
	char filter_exp[] = "tcp port 2222";	/* The filter expression */
	bpf_u_int32 mask;		/* The netmask of our sniffing device */
	bpf_u_int32 net;		/* The IP of our sniffing device */
	struct pcap_pkthdr header;	/* The header that pcap gives us */
	const u_char *packet;		/* The actual packet */
	int num_packets = 1000;		/* number of packets to capture */
	
	print_app_usage();
	printf("\n");
	if (dev == NULL) 
	{
		fprintf(stderr, "Couldn't find default device: %s\n", errbuf);
		return(2);
	}
	
	/* print capture info */
        printf("Device: %s\n", dev);
        printf("Number of packets: %d\n", num_packets);
        printf("Filter expression: %s\n", filter_exp);
	
	//printf("Device: %s\n", dev);
	//printf("\n");
	
	if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) 
	{
		fprintf(stderr, "Can't get netmask for device %s\n", dev);
		net = 0;
		mask = 0;
	}
	
	//printf("Device IP is: %i %i", net, mask);
	//printf("\n");
	
	handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);
        if (handle == NULL)
        {
                fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
                return(2);
        }
        printf("Opened Device succesfully: %s\n", dev);
        printf("\n");
	
	//Filter
	if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) 
	{
		 fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle));
		 return(2);
	}
	if (pcap_setfilter(handle, &fp) == -1) 
	{
		 fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle));
		 return(2);
	}
	printf("Sucessfully places filter");
	printf("\n");

	/* now we can set our callback function */
	pcap_loop(handle, num_packets, got_packet, NULL);

	/* cleanup */
	pcap_freecode(&fp);
	pcap_close(handle);

	printf("\nCapture complete.\n");
	
	return(0);
}
Esempio n. 30
0
int main(int argc, char *argv[])
{
	const char *from_dev = NULL;			/* Capture from device */
	const char *from_file = NULL;			/* Read from pcap file */
	int from_stdin = 0;				/* Read from stdin */
	
	pcap_t *in;					/* PCAP input handle */
	
	int limit = -1;					/* How many packets to sniff */
	
	char errbuf[PCAP_ERRBUF_SIZE];			/* Error buffer */

	char *to_file = NULL;				/* PCAP output file */
	
	char *pcap_filter = NULL;			/* PCAP filter string */
	char *radius_filter = NULL;
	int port = 1812;
	
	struct bpf_program fp;				/* Holds compiled filter */
	bpf_u_int32 ip_mask = PCAP_NETMASK_UNKNOWN;	/* Device Subnet mask */
	bpf_u_int32 ip_addr = 0;			/* Device IP */
	
	char buffer[1024];

	int opt;
	FR_TOKEN parsecode;
	const char *radius_dir = RADIUS_DIR;
	
	fr_debug_flag = 2;
	log_dst = stdout;

	/*
	 *  Get options
	 */
	while ((opt = getopt(argc, argv, "c:d:Ff:hi:I:p:qr:s:Svw:xX")) != EOF) {
		switch (opt)
		{
		case 'c':
			limit = atoi(optarg);
			if (limit <= 0) {
				fprintf(stderr, "radsniff: Invalid number of packets \"%s\"\n", optarg);
				exit(1);
			}
			break;
		case 'd':
			radius_dir = optarg;
			break;
		case 'F':
			from_stdin = 1;
			to_stdout = 1;
			break;
		case 'f':
			pcap_filter = optarg;
			break;
		case 'h':
			usage(0);
			break;
		case 'i':
			from_dev = optarg;
			break;
		case 'I':
			from_file = optarg;
			break;
		case 'p':
			port = atoi(optarg);
			break;
		case 'q':
			if (fr_debug_flag > 0) {
				fr_debug_flag--;
			}
			break;
		case 'r':
			radius_filter = optarg;
			break;
		case 's':
			radius_secret = optarg;
			break;
		case 'S':
			do_sort = 1;
			break;
		case 'v':
			INFO(log_dst, "%s %s\n", radsniff_version, pcap_lib_version());
			exit(0);
			break;
		case 'w':
			to_file = optarg;
			break;
		case 'x':
		case 'X':
		  	fr_debug_flag++;
			break;
		default:
			usage(64);
		}
	}
	
	/* What's the point in specifying -F ?! */
	if (from_stdin && from_file && to_file) {
		usage(64);
	}
	
	/* Can't read from both... */
	if (from_file && from_dev) {
		usage(64);
	}
	
	/* Reading from file overrides stdin */
	if (from_stdin && (from_file || from_dev)) {
		from_stdin = 0;
	}
	
	/* Writing to file overrides stdout */
	if (to_file && to_stdout) {
		to_stdout = 0;
	}
	
	/*
	 *  If were writing pcap data stdout we *really* don't want to send
	 *  logging there as well.
	 */
 	log_dst = to_stdout ? stderr : stdout;

#if !defined(HAVE_PCAP_FOPEN_OFFLINE) || !defined(HAVE_PCAP_DUMP_FOPEN)
	if (from_stdin || to_stdout) {
		fprintf(stderr, "radsniff: PCAP streams not supported.\n");
		exit(64);
	}
#endif

	if (!pcap_filter) {
		pcap_filter = buffer;
		snprintf(buffer, sizeof(buffer), "udp port %d or %d or %d",
			 port, port + 1, 3799);
	}
	
	/*
	 *  There are times when we don't need the dictionaries.
	 */
	if (!to_stdout) {
		if (dict_init(radius_dir, RADIUS_DICTIONARY) < 0) {
			fr_perror("radsniff");
			exit(64);
		}
	}

	if (radius_filter) {
		parsecode = userparse(radius_filter, &filter_vps);
		if (parsecode == T_OP_INVALID) {
			fprintf(stderr, "radsniff: Invalid RADIUS filter \"%s\" (%s)\n", radius_filter, fr_strerror());
			exit(64);
		}
		
		if (!filter_vps) {
			fprintf(stderr, "radsniff: Empty RADIUS filter \"%s\"\n", radius_filter);
			exit(64);
		}

		filter_tree = rbtree_create((rbcmp) fr_packet_cmp, free, 0);
		if (!filter_tree) {
			fprintf(stderr, "radsniff: Failed creating filter tree\n");
			exit(1);
		}
	}

	/*
	 *  Setup the request tree
	 */
	request_tree = rbtree_create((rbcmp) fr_packet_cmp, free, 0);
	if (!request_tree) {
		fprintf(stderr, "radsniff: Failed creating request tree\n");
		exit(1);
	}

	/*
	 *  Allocate a null packet for decrypting attributes in CoA requests
	 */
	nullpacket = rad_alloc(NULL, 0);
	if (!nullpacket) {
		fprintf(stderr, "radsniff: Out of memory\n");
		exit(1);
	}

	/*
	 *  Get the default capture device
	 */
	if (!from_stdin && !from_file && !from_dev) {
		from_dev = pcap_lookupdev(errbuf);
		if (!from_dev) {
			fprintf(stderr, "radsniff: Failed discovering default interface (%s)\n", errbuf);
			exit(1);
		}

		INFO(log_dst, "Capturing from interface \"%s\"\n", from_dev);
	}
	
	/*
	 *  Print captures values which will be used
	 */
	if (fr_debug_flag > 2) {
				DEBUG1(log_dst, "Sniffing with options:\n");
		if (from_dev)	DEBUG1(log_dst, "  Device		   : [%s]\n", from_dev);
		if (limit > 0)	DEBUG1(log_dst, "  Capture limit (packets)  : [%d]\n", limit);
				DEBUG1(log_dst, "  PCAP filter	      : [%s]\n", pcap_filter);
				DEBUG1(log_dst, "  RADIUS secret	    : [%s]\n", radius_secret);
		if (filter_vps){DEBUG1(log_dst, "  RADIUS filter	    :\n");
			vp_printlist(log_dst, filter_vps);
		}
	}

	/*
	 *  Figure out whether were doing a reading from a file, doing a live
	 *  capture or reading from stdin.
	 */
	if (from_file) {
		in = pcap_open_offline(from_file, errbuf);
#ifdef HAVE_PCAP_FOPEN_OFFLINE
	} else if (from_stdin) {
		in = pcap_fopen_offline(stdin, errbuf);
#endif
	} else if (from_dev) {
		pcap_lookupnet(from_dev, &ip_addr, &ip_mask, errbuf);
		in = pcap_open_live(from_dev, 65536, 1, 1, errbuf);
	} else {
		fprintf(stderr, "radsniff: No capture devices available\n");
	}
	
	if (!in) {
		fprintf(stderr, "radsniff: Failed opening input (%s)\n", errbuf);
		exit(1);
	}

	if (to_file) {
		out = pcap_dump_open(in, to_file);
		if (!out) {
			fprintf(stderr, "radsniff: Failed opening output file (%s)\n", pcap_geterr(in));
			exit(1);
		}
#ifdef HAVE_PCAP_DUMP_FOPEN
	} else if (to_stdout) {
		out = pcap_dump_fopen(in, stdout);
		if (!out) {
			fprintf(stderr, "radsniff: Failed opening stdout (%s)\n", pcap_geterr(in));
			exit(1);
		}
#endif
	}

	/*
	 *  Apply the rules
	 */
	if (pcap_compile(in, &fp, pcap_filter, 0, ip_mask) < 0) {
		fprintf(stderr, "radsniff: Failed compiling PCAP filter (%s)\n", pcap_geterr(in));
		exit(1);
	}
	
	if (pcap_setfilter(in, &fp) < 0) {
		fprintf(stderr, "radsniff: Failed applying PCAP filter (%s)\n", pcap_geterr(in));
		exit(1);
	}

	/*
	 *  Enter the main capture loop...
	 */
	pcap_loop(in, limit, got_packet, NULL);
	
	/*
	 *  ...were done capturing.
	 */
	pcap_close(in);
	if (out) {
		pcap_dump_close(out);
	}
	
	if (filter_tree) {
		rbtree_free(filter_tree);
	}
	
	INFO(log_dst, "Done sniffing\n");
	
	return 0;
}