int begin_interface(void) { int i = 0; int size = 1; int result = 0; PDEBUG("begin_interface invoked, do the initize\n"); if (down_interruptible(&sem)) { result = -EINTR; goto cleanup_exit; } if (is_device_ready()) { result = -ETXTBSY; goto cleanup; } //get page count for (i = 0; i < PAGE_INCREASE; i++) { size = size * 2; } PDEBUG("now trying to allocate %d pages, total %d bytes\n", size, size << PAGE_SHIFT); //get real size size = size << PAGE_SHIFT; cycle_buffer_size = size; //allocate cycle_buffer = (char *)__get_free_pages(GFP_KERNEL, PAGE_INCREASE); if (NULL == cycle_buffer) { result = -ENOMEM; goto cleanup; } PDEBUG("allocatd %d bytes at 0x%08x\n", size, cycle_buffer); read_ptr = cycle_buffer; write_ptr = cycle_buffer; cleanup: up(&sem); cleanup_exit: return result; }
//write data into interface void write_to_interface(char * buffer, int buffer_size) { if (!is_device_ready()) { return; } if (0 == buffer_size) { return; } PVERBOSE("write %d byte(s) buffer to cache now\n", buffer_size); if (down_interruptible(&sem)) { return; } //we will never let our buffer be full //note when cycle_buffer_size - get_used_size() = buffer_size, all buffer will be filled, then read_ptr = write_ptr //but we have no idea buffer size is 0 or full when read_ptr = write_ptr, so avoid this states if ((cycle_buffer_size - get_used_size()) > buffer_size) { //buffer is enough write_ptr = copy_to_buffer(write_ptr, buffer, buffer_size); PVERBOSE("write complete, read_ptr: 0x%08x, write_ptr: 0x%08x, used size: %d\n", read_ptr, write_ptr, get_used_size()); } else { PWARN("failed while write to interface, buffer is full, used size: %d, need: %d\n", get_used_size(), buffer_size); } up(&sem); }
static int tx_nic_ctx_init(struct netsniff_ng_tx_thread_context * thread_ctx, const char * dev_name, const char * bpf_path, const char * pcap_path) { struct netsniff_ng_tx_nic_context * nic_ctx = NULL; int rc = 0; assert(thread_ctx); assert(dev_name); nic_ctx = &thread_ctx->nic_ctx; if (!is_device_ready(dev_name)) { warn("Device %s is not ready\n", dev_name); return (EAGAIN); } strlcpy(nic_ctx->generic.dev_name, dev_name, IFNAMSIZ); nic_ctx->generic.dev_fd = get_pf_socket(); if (nic_ctx->generic.dev_fd < 0) { warn("Could not open PF_PACKET socket\n"); rc = EPERM; goto error; } if ((rc = packet_loss_discard_set(nic_ctx->generic.dev_fd)) != 0) { goto error; } if (bpf_path) { if(bpf_parse(bpf_path, &nic_ctx->generic.bpf) == 0) { warn("Could not parse BPF file %s\n", bpf_path); rc = EINVAL; goto error; } bpf_kernel_inject(nic_ctx->generic.dev_fd, &nic_ctx->generic.bpf); } if (pcap_path) { if ((nic_ctx->generic.pcap_fd = pcap_open(pcap_path, O_RDONLY)) < 0) { warn("Failed to prepare pcap : %s\n", pcap_path); rc = EINVAL; goto error; } } if ((rc = tx_ring_create(nic_ctx->generic.dev_fd, &nic_ctx->nic_rb, dev_name)) != 0) { goto error; } return(0); error: tx_nic_ctx_destroy(nic_ctx); return (rc); }