Пример #1
0
static void enter_mode_rx_only_or_dump(struct mode *mode)
{
	int sock, irq, ifindex, fd = 0, ret;
	unsigned int size, it = 0;
	unsigned long fcnt = 0;
	short ifflags = 0;
	uint8_t *packet;
	struct ring rx_ring;
	struct pollfd rx_poll;
	struct frame_map *hdr;
	struct sock_fprog bpf_ops;

	if (!device_up_and_running(mode->device_in))
		panic("Device not up and running!\n");

	set_memcpy();
	sock = pf_socket();

	if (mode->dump) {
		struct stat tmp;
		memset(&tmp, 0, sizeof(tmp));
		ret = stat(mode->device_out, &tmp);
		if (ret < 0) {
			mode->dump_dir = 0;
			goto try_file;
		}
		mode->dump_dir = !!S_ISDIR(tmp.st_mode);
		if (mode->dump_dir) {
			fd = begin_multi_pcap_file(mode);
		} else {
try_file:
			fd = begin_single_pcap_file(mode);
		}
	}

	memset(&rx_ring, 0, sizeof(rx_ring));
	memset(&rx_poll, 0, sizeof(rx_poll));
	memset(&bpf_ops, 0, sizeof(bpf_ops));

	ifindex = device_ifindex(mode->device_in);
	size = ring_size(mode->device_in, mode->reserve_size);

	enable_kernel_bpf_jit_compiler();
	bpf_parse_rules(mode->filter, &bpf_ops);
	bpf_attach_to_sock(sock, &bpf_ops);

	setup_rx_ring_layout(sock, &rx_ring, size, mode->jumbo_support);
	create_rx_ring(sock, &rx_ring);
	mmap_rx_ring(sock, &rx_ring);
	alloc_rx_ring_frames(&rx_ring);
	bind_rx_ring(sock, &rx_ring, ifindex);

	prepare_polling(sock, &rx_poll);
	dissector_init_all(mode->print_mode);

	if (mode->cpu >= 0 && ifindex > 0) {
		irq = device_irq_number(mode->device_in);
		device_bind_irq_to_cpu(mode->cpu, irq);
		printf("IRQ: %s:%d > CPU%d\n", mode->device_in, irq, 
		       mode->cpu);
	}

	if (mode->promiscuous == true) {
		ifflags = enter_promiscuous_mode(mode->device_in);
		printf("PROMISC\n");
	}

	printf("BPF:\n");
	bpf_dump_all(&bpf_ops);
	printf("MD: RX %s\n\n", mode->dump ? pcap_ops[mode->pcap]->name : "");

	while (likely(sigint == 0)) {
		while (user_may_pull_from_rx(rx_ring.frames[it].iov_base)) {
			hdr = rx_ring.frames[it].iov_base;
			packet = ((uint8_t *) hdr) + hdr->tp_h.tp_mac;
			fcnt++;

			if (mode->packet_type != PACKET_ALL)
				if (mode->packet_type != hdr->s_ll.sll_pkttype)
					goto next;
			if (unlikely(rx_ring.layout.tp_frame_size <
				     hdr->tp_h.tp_snaplen)) {
				fprintf(stderr, "Skipping too large packet! "
					"No jumbo support selected?\n");
				fflush(stderr);
				goto next;
			}
			if (mode->dump) {
				struct pcap_pkthdr phdr;
				tpacket_hdr_to_pcap_pkthdr(&hdr->tp_h, &phdr);
				ret = pcap_ops[mode->pcap]->write_pcap_pkt(fd, &phdr,
									   packet, phdr.len);
				if (unlikely(ret != sizeof(phdr) + phdr.len))
					panic("Write error to pcap!\n");
			}

			show_frame_hdr(hdr, mode->print_mode, RING_MODE_INGRESS);
			dissector_entry_point(packet, hdr->tp_h.tp_snaplen,
					      mode->link_type);

			if (frame_cnt_max != 0 && fcnt >= frame_cnt_max) {
				sigint = 1;
				break;
			}
next:
			kernel_may_pull_from_rx(&hdr->tp_h);
			next_slot(&it, &rx_ring);

			if (unlikely(sigint == 1))
				break;
			if (mode->dump && next_dump) {
				struct tpacket_stats kstats;
				socklen_t slen = sizeof(kstats);
				memset(&kstats, 0, sizeof(kstats));
				getsockopt(sock, SOL_PACKET, PACKET_STATISTICS,
					   &kstats, &slen);
				fd = next_multi_pcap_file(mode, fd);
				next_dump = false;
				if (mode->print_mode == FNTTYPE_PRINT_NONE) {
					printf(".(+%u/-%u)", kstats.tp_packets - kstats.tp_drops,
					       kstats.tp_drops);
					fflush(stdout);
				}
			}
		}

		poll(&rx_poll, 1, -1);
		poll_error_maybe_die(sock, &rx_poll);
	}

	if (!(mode->dump_dir && mode->print_mode == FNTTYPE_PRINT_NONE))
		sock_print_net_stats(sock);
	else {
		printf("\n\n");
		fflush(stdout);
	}
	dissector_cleanup_all();
	destroy_rx_ring(sock, &rx_ring);
	if (mode->promiscuous == true)
		leave_promiscuous_mode(mode->device_in, ifflags);
	close(sock);
	if (mode->dump) {
		if (mode->dump_dir)
			finish_multi_pcap_file(mode, fd);
		else
			finish_single_pcap_file(mode, fd);
	}
}
Пример #2
0
static void enter_mode_pcap_to_tx(struct mode *mode)
{
	int irq, ifindex, fd = 0, ret;
	unsigned int size, it = 0;
	struct ring tx_ring;
	struct frame_map *hdr;
	struct sock_fprog bpf_ops;
	struct tx_stats stats;
	uint8_t *out = NULL;

	if (!device_up_and_running(mode->device_out))
		panic("Device not up and running!\n");

	set_memcpy();
	tx_sock = pf_socket();

	if (!pcap_ops[mode->pcap])
		panic("pcap group not supported!\n");
	fd = open_or_die(mode->device_in, O_RDONLY | O_LARGEFILE | O_NOATIME);
	ret = pcap_ops[mode->pcap]->pull_file_header(fd);
	if (ret)
		panic("error reading pcap header!\n");
	if (pcap_ops[mode->pcap]->prepare_reading_pcap) {
		ret = pcap_ops[mode->pcap]->prepare_reading_pcap(fd);
		if (ret)
			panic("error prepare reading pcap!\n");
	}

	memset(&tx_ring, 0, sizeof(tx_ring));
	memset(&bpf_ops, 0, sizeof(bpf_ops));
	memset(&stats, 0, sizeof(stats));

	ifindex = device_ifindex(mode->device_out);
	size = ring_size(mode->device_out, mode->reserve_size);

	bpf_parse_rules(mode->filter, &bpf_ops);

	set_packet_loss_discard(tx_sock);
	setup_tx_ring_layout(tx_sock, &tx_ring, size, mode->jumbo_support);
	create_tx_ring(tx_sock, &tx_ring);
	mmap_tx_ring(tx_sock, &tx_ring);
	alloc_tx_ring_frames(&tx_ring);
	bind_tx_ring(tx_sock, &tx_ring, ifindex);

	dissector_init_all(mode->print_mode);

	if (mode->cpu >= 0 && ifindex > 0) {
		irq = device_irq_number(mode->device_out);
		device_bind_irq_to_cpu(mode->cpu, irq);
		printf("IRQ: %s:%d > CPU%d\n", mode->device_out, irq, 
		       mode->cpu);
	}

	if (mode->kpull)
		interval = mode->kpull;

	itimer.it_interval.tv_sec = 0;
	itimer.it_interval.tv_usec = interval;
	itimer.it_value.tv_sec = 0;
	itimer.it_value.tv_usec = interval;
	setitimer(ITIMER_REAL, &itimer, NULL); 

	printf("BPF:\n");
	bpf_dump_all(&bpf_ops);
	printf("MD: TX %luus %s\n\n", interval, pcap_ops[mode->pcap]->name);

	while (likely(sigint == 0)) {
		while (user_may_pull_from_tx(tx_ring.frames[it].iov_base)) {
			struct pcap_pkthdr phdr;
			hdr = tx_ring.frames[it].iov_base;
			/* Kernel assumes: data = ph.raw + po->tp_hdrlen -
			 * sizeof(struct sockaddr_ll); */
			out = ((uint8_t *) hdr) + TPACKET_HDRLEN -
			      sizeof(struct sockaddr_ll);

			do {
				ret = pcap_ops[mode->pcap]->read_pcap_pkt(fd, &phdr,
						out, ring_frame_size(&tx_ring));
				if (unlikely(ret <= 0))
					goto out;
			} while (mode->filter && !bpf_run_filter(&bpf_ops, out, phdr.len));
			pcap_pkthdr_to_tpacket_hdr(&phdr, &hdr->tp_h);

			stats.tx_bytes += hdr->tp_h.tp_len;;
			stats.tx_packets++;

			show_frame_hdr(hdr, mode->print_mode, RING_MODE_EGRESS);
			dissector_entry_point(out, hdr->tp_h.tp_snaplen,
					      mode->link_type);

			kernel_may_pull_from_tx(&hdr->tp_h);
			next_slot(&it, &tx_ring);

			if (unlikely(sigint == 1))
				break;
			if (frame_cnt_max != 0 &&
			    stats.tx_packets >= frame_cnt_max) {
				sigint = 1;
				break;
			}
		}
	}
out:
	fflush(stdout);
	printf("\n");
	printf("\r%12lu frames outgoing\n", stats.tx_packets);
	printf("\r%12lu bytes outgoing\n", stats.tx_bytes);

	dissector_cleanup_all();
	destroy_tx_ring(tx_sock, &tx_ring);

	close(tx_sock);
	if (pcap_ops[mode->pcap]->prepare_close_pcap)
		pcap_ops[mode->pcap]->prepare_close_pcap(fd, PCAP_MODE_READ);
	close(fd);
}
Пример #3
0
/* If netsniff-ngs in device is on a tap, it can efficiently filter out 
 * some interesting packets and give them to the out device for testing
 * or debugging for instance. */
static void enter_mode_rx_to_tx(struct mode *mode)
{
	int rx_sock, ifindex_in, ifindex_out;
	unsigned int size_in, size_out, it_in = 0, it_out = 0;
	unsigned long fcnt = 0;
	uint8_t *in, *out;
	short ifflags = 0;
	struct frame_map *hdr_in, *hdr_out;
	struct ring tx_ring;
	struct ring rx_ring;
	struct pollfd rx_poll;
	struct sock_fprog bpf_ops;

	if (!strncmp(mode->device_in, mode->device_out,
		     strlen(mode->device_in)))
		panic("Ingress/egress devices must be different!\n");
	if (!device_up_and_running(mode->device_out))
		panic("Egress device not up and running!\n");
	if (!device_up_and_running(mode->device_in))
		panic("Ingress device not up and running!\n");

	set_memcpy();
	rx_sock = pf_socket();
	tx_sock = pf_socket();

	memset(&tx_ring, 0, sizeof(tx_ring));
	memset(&rx_ring, 0, sizeof(rx_ring));
	memset(&rx_poll, 0, sizeof(rx_poll));
	memset(&bpf_ops, 0, sizeof(bpf_ops));

	ifindex_in = device_ifindex(mode->device_in);
	size_in = ring_size(mode->device_in, mode->reserve_size);

	ifindex_out = device_ifindex(mode->device_out);
	size_out = ring_size(mode->device_out, mode->reserve_size);

	enable_kernel_bpf_jit_compiler();
	bpf_parse_rules(mode->filter, &bpf_ops);
	bpf_attach_to_sock(rx_sock, &bpf_ops);

	setup_rx_ring_layout(rx_sock, &rx_ring, size_in, mode->jumbo_support);
	create_rx_ring(rx_sock, &rx_ring);
	mmap_rx_ring(rx_sock, &rx_ring);
	alloc_rx_ring_frames(&rx_ring);
	bind_rx_ring(rx_sock, &rx_ring, ifindex_in);
	prepare_polling(rx_sock, &rx_poll);

	set_packet_loss_discard(tx_sock);
	setup_tx_ring_layout(tx_sock, &tx_ring, size_out, mode->jumbo_support);
	create_tx_ring(tx_sock, &tx_ring);
	mmap_tx_ring(tx_sock, &tx_ring);
	alloc_tx_ring_frames(&tx_ring);
	bind_tx_ring(tx_sock, &tx_ring, ifindex_out);

	mt_init_by_seed_time();
	dissector_init_all(mode->print_mode);

	 if (mode->promiscuous == true) {
		ifflags = enter_promiscuous_mode(mode->device_in);
		printf("PROMISC\n");
	}

	if (mode->kpull)
		interval = mode->kpull;

	itimer.it_interval.tv_sec = 0;
	itimer.it_interval.tv_usec = interval;
	itimer.it_value.tv_sec = 0;
	itimer.it_value.tv_usec = interval;
	setitimer(ITIMER_REAL, &itimer, NULL);

	printf("BPF:\n");
	bpf_dump_all(&bpf_ops);
	printf("MD: RXTX %luus\n\n", interval);
	printf("Running! Hang up with ^C!\n\n");

	while (likely(sigint == 0)) {
		while (user_may_pull_from_rx(rx_ring.frames[it_in].iov_base)) {
			hdr_in = rx_ring.frames[it_in].iov_base;
			in = ((uint8_t *) hdr_in) + hdr_in->tp_h.tp_mac;
			fcnt++;
			if (mode->packet_type != PACKET_ALL)
				if (mode->packet_type != hdr_in->s_ll.sll_pkttype)
					goto next;

			hdr_out = tx_ring.frames[it_out].iov_base;
			out = ((uint8_t *) hdr_out) + TPACKET_HDRLEN -
			      sizeof(struct sockaddr_ll);

			/* If we cannot pull, look for a different slot. */
			for (; !user_may_pull_from_tx(tx_ring.frames[it_out].iov_base) &&
			       likely(!sigint);) {
				if (mode->randomize)
					next_rnd_slot(&it_out, &tx_ring);
				else
					next_slot(&it_out, &tx_ring);
				hdr_out = tx_ring.frames[it_out].iov_base;
				out = ((uint8_t *) hdr_out) + TPACKET_HDRLEN -
				      sizeof(struct sockaddr_ll);
			}

			tpacket_hdr_clone(&hdr_out->tp_h, &hdr_in->tp_h);
			__memcpy(out, in, hdr_in->tp_h.tp_len);

			kernel_may_pull_from_tx(&hdr_out->tp_h);
			if (mode->randomize)
				next_rnd_slot(&it_out, &tx_ring);
			else
				next_slot(&it_out, &tx_ring);

			/* Should actually be avoided ... */
			show_frame_hdr(hdr_in, mode->print_mode, RING_MODE_INGRESS);
			dissector_entry_point(in, hdr_in->tp_h.tp_snaplen,
					      mode->link_type);

			if (frame_cnt_max != 0 && fcnt >= frame_cnt_max) {
				sigint = 1;
				break;
			}
next:
			kernel_may_pull_from_rx(&hdr_in->tp_h);
			next_slot(&it_in, &rx_ring);

			if (unlikely(sigint == 1))
				goto out;
		}

		poll(&rx_poll, 1, -1);
		poll_error_maybe_die(rx_sock, &rx_poll);
	}
out:
	sock_print_net_stats(rx_sock);

	dissector_cleanup_all();
	destroy_tx_ring(tx_sock, &tx_ring);
	destroy_rx_ring(rx_sock, &rx_ring);

	if (mode->promiscuous == true)
		leave_promiscuous_mode(mode->device_in, ifflags);

	close(tx_sock);
	close(rx_sock);
}
Пример #4
0
EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
	InitializeLib(ImageHandle, SystemTable);
	CallConstructors();

	EFI_STATUS Status;

	const char16_t* searchdir = u"\\EFI\\ChaiOS\\";
	if (Status = SetWorkingDirectory(searchdir))
		printf(u"Error setting working directory: %s\r\n", getError(Status));

	CHAIOS_BOOT_FILES* bootfile = nullptr;
	while (bootfile = iterateBootFiles(bootfile))
	{
		if (bootfile->loadLocation != nullptr)
			continue;		//Support in-memory images

		EFI_FILE* file = OpenFile(bootfile->fileName, "r");
		if (!file)
		{
			printf(u"Error: could not open %s: %s\r\n", bootfile->fileName, getError(getErrno()));
		}
		UINT64 fileSize = GetFileSize(file);
		VOID* bootfilebuf = kmalloc(fileSize+1);
		UINTN read = ReadFile(bootfilebuf, 1, fileSize, file);
		if (read < fileSize)
			printf(u"Read %d bytes, failed\r\n", read);
		else
			printf(u"Successfully read %d bytes\r\n", read);
		//Boot file is now loaded into memory
		CloseFile(file);
		bootfile->loadLocation = bootfilebuf;
		bootfile->fileSize = fileSize;
		if (bootfile->bootType == CHAIOS_BOOT_CONFIGURATION)
		{
			//We need to parse this now. INI format
			((char*)bootfilebuf)[fileSize] = '\0';
			ini_parse_string((const char*)bootfilebuf, &bootini_handler, nullptr);
		}
	}

	//size_t value = GetIntegerInput(u"Enter scrolling lines configuration: ");
	//set_scrolllines(value);

	UINT32 AutoMode = IterateGraphicsMode(&match_config_resoultion);
	EFI_GRAPHICS_OUTPUT_MODE_INFORMATION* info; UINTN SizeOfInfo;
	if (AutoMode == UINT32_MAX)
	{
		if (!EFI_ERROR(GetGraphicsModeInfo(AutoMode, &info, &SizeOfInfo)))
		{
			IterateGraphicsMode(&print_graphics_mode);
			size_t value = GetIntegerInput(u"Enter boot graphics mode: ");
			SetGraphicsMode(value);
			AutoMode = value;
		}
	}
	else
	{
		SetGraphicsMode(AutoMode);
	}
	if (!EFI_ERROR(GetGraphicsModeInfo(AutoMode, &info, &SizeOfInfo)))
	{
		printf(u"Graphics mode %d: %dx%d\r\n", AutoMode, info->HorizontalResolution, info->VerticalResolution);
	}

	puts(u"ChaiOS 0.09 UEFI Loader\r\n");
	int majorver = SystemTable->Hdr.Revision / (1 << 16);
	int minorver = SystemTable->Hdr.Revision % (1 << 16);
	printf(u"Firmware Vendor: %s, version: %d (UEFI:%d.%d)\r\n", SystemTable->FirmwareVendor, SystemTable->FirmwareRevision, majorver, minorver);
	//Read ACPI configuration tables
	//startup_acpi(SystemTable);
	//startup_multiprocessor();

	const size_t EARLY_PAGE_STACK_SIZE = 1024*1024;
	EFI_PHYSICAL_ADDRESS earlyPhypageStack = 0;
	if (EFI_ERROR(SystemTable->BootServices->AllocatePages(AllocateAnyPages, EfiLoaderData, EARLY_PAGE_STACK_SIZE / EFI_PAGE_SIZE, &earlyPhypageStack)))
	{
		puts(u"Could not allocate page stack\r\n");
		return EFI_OUT_OF_RESOURCES;
	}

	SystemTable->BootServices->SetWatchdogTimer(0, 0, 0, nullptr);

	PrepareExitBootServices();

	EfiMemoryMap map;
	map.MemMapSize = map.MapKey = map.DescriptorSize = map.DescriptorVersion = 0;

	SystemTable->BootServices->GetMemoryMap(&map.MemMapSize, nullptr, &map.MapKey, &map.DescriptorSize, &map.DescriptorVersion);
	//Give a nice bit of room to spare (memory map can change)
	map.MemMapSize += 16 * map.DescriptorSize;
	map.memmap = (EFI_MEMORY_DESCRIPTOR*)kmalloc(map.MemMapSize);	//Allocate a nice buffer

	SystemTable->BootServices->GetMemoryMap(&map.MemMapSize, map.memmap, &map.MapKey, &map.DescriptorSize, &map.DescriptorVersion);
	printf(u"EFI Memory Map: Descriptor size %d\n", map.DescriptorSize);
#if 0
	//Dump the UEFI memory map to a file for testing
	EFI_FILE* file = OpenFile(u"efimap.dat", "w");
	if (!file)
	{
		printf(u"Error: could not open %s: %s\r\n", u"efimap.dat", getError(getErrno()));
	}
	WriteFile(map.memmap, 1, map.MemMapSize, file);
	CloseFile(file);
#endif
	if (EFI_ERROR(Status = SystemTable->BootServices->ExitBootServices(ImageHandle, map.MapKey)))
	{
		printf(u"Failed to exit boot services: %s\r\n", getError(Status));
		UINTN index;
		SystemTable->BootServices->WaitForEvent(1, &SystemTable->ConIn->WaitForKey, &index);
		return EFI_SUCCESS;
	}
	//We need to take control of the hardware now. Setup basic memory management
	setLiballocAllocator(nullptr, nullptr);

	InitializePmmngr(map, (void*)earlyPhypageStack, EARLY_PAGE_STACK_SIZE);
	puts(u"Physical memory manager intialized\n");
	arch_initialize_paging();
	puts(u"Paging initialized\n");
	setLiballocAllocator(&arch_allocate_pages, &arch_free_pages);
	//Now load the OS!
	bootfile = nullptr;
	kimage_entry kentry = nullptr;
	KLOAD_HANDLE kernel = NULL;
	while (bootfile = iterateBootFiles(bootfile))
	{
		printf(u"Boot file: %s @ %x, length %d, type %d\n", bootfile->fileName, bootfile->loadLocation, bootfile->fileSize, bootfile->bootType);
		if (!bootfile->loadLocation)
			continue;
		if (bootfile->bootType == CHAIOS_DLL)
		{
			KLOAD_HANDLE dll = LoadImage(bootfile->loadLocation, bootfile->fileName);
			if (GetProcAddress(dll, "memcpy"))
			{
				set_memcpy((memcpy_proc)GetProcAddress(dll, "memcpy"));
			}
		}
		else if (bootfile->bootType == CHAIOS_KERNEL)
		{
			kernel = LoadImage(bootfile->loadLocation, bootfile->fileName);
			kentry = GetEntryPoint(kernel);
		}
	}

	size_t kstacksize = GetStackSize(kernel);

	if (!paging_map(stackaddr, PADDR_T_MAX, kstacksize, PAGE_ATTRIBUTE_WRITABLE))
	{
		puts(u"Error: could not allocate kernel stack\n");
		while (1);
	}

	KERNEL_BOOT_INFO bootinfo;
	fill_pmmngr_info(bootinfo.pmmngr_info);
	fill_arch_paging_info(bootinfo.paging_info);
	fill_modloader_info(bootinfo.modloader_info);
	get_framebuffer_info(bootinfo.fbinfo);
	populate_kterm_info(bootinfo.kterm_status);
	bootinfo.efi_system_table = SystemTable;
	bootinfo.memory_map = &map;
	bootinfo.loaded_files = &bootfiles;
	bootinfo.boottype = CHAIOS_BOOT_TYPE_UEFI;
	bootinfo.printf_proc = &printf;
	bootinfo.puts_proc = &puts;

	printf(u"Success: Kernel entry point at %x, stack at %x, length %x\n", kentry, stackaddr, kstacksize);
	call_kernel(&bootinfo, kentry, stackaddr, kstacksize);
	puts(u"Kernel returned");
	while (1);
}