Reusing wintun Session variable - c

I have a simple code that creates a simple layer 3 interface using the Wintun library. I want to read and write packets to this interface from a different process. While I'm able to read packets from this interface using Winsock, I'm unable to write packets to the interface using either Winsock/npcap. The only solution that worked is using the WintunSendPacket method from their library. But this method takes the Session variable as a parameter. Things that I've tried till now:-
Tried to inject packet to the interface using npcap
Attempted to create a new session variable using the Adapter obtained by using the WintunOpenAdapter function. (Results in error)
Tried to write the Session variable into a mmap using CreateFileMappingA and MapViewOfFile functions.
None of the solutions seems to be yielding any results. Any help would be much appreciated.
interface.c (gcc -I include/ interface.c -lwsock32 -lWs2_32 -liphlpapi -o interface)
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2018-2021 WireGuard LLC. All Rights Reserved.
*/
// gcc -I include/ example.c -lwsock32 -lWs2_32 -liphlpapi
#include <winsock2.h>
#include <Windows.h>
#include <ws2ipdef.h>
#include <iphlpapi.h>
#include <mstcpip.h>
#include <in6addr.h>
#include <winternl.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <sal.h>
#include <winerror.h>
#include <netioapi.h>
#include <stdint.h>
#if !defined(_Must_inspect_result_)
#define _Must_inspect_result_
#endif
#if !defined(_Return_type_success_)
#define _Return_type_success_(x)
#endif
#if !defined(_Post_writable_byte_size_)
#define _Post_writable_byte_size_(x)
#endif
#if !defined(_In_reads_bytes_)
#define _In_reads_bytes_(x)
#endif
#if !defined(_Out_writes_bytes_all_)
#define _Out_writes_bytes_all_(x)
#endif
#if !defined(LOAD_LIBRARY_SEARCH_APPLICATION_DIR)
#define LOAD_LIBRARY_SEARCH_APPLICATION_DIR 0x00000200
#endif
#if !defined(LOAD_LIBRARY_SEARCH_SYSTEM32)
#define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800
#endif
#include "wintun.h"
#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")
static WINTUN_CREATE_ADAPTER_FUNC *WintunCreateAdapter;
static WINTUN_CLOSE_ADAPTER_FUNC *WintunCloseAdapter;
static WINTUN_OPEN_ADAPTER_FUNC *WintunOpenAdapter;
static WINTUN_GET_ADAPTER_LUID_FUNC *WintunGetAdapterLUID;
static WINTUN_GET_RUNNING_DRIVER_VERSION_FUNC *WintunGetRunningDriverVersion;
static WINTUN_DELETE_DRIVER_FUNC *WintunDeleteDriver;
static WINTUN_SET_LOGGER_FUNC *WintunSetLogger;
static WINTUN_START_SESSION_FUNC *WintunStartSession;
static WINTUN_END_SESSION_FUNC *WintunEndSession;
static WINTUN_GET_READ_WAIT_EVENT_FUNC *WintunGetReadWaitEvent;
static WINTUN_RECEIVE_PACKET_FUNC *WintunReceivePacket;
static WINTUN_RELEASE_RECEIVE_PACKET_FUNC *WintunReleaseReceivePacket;
static WINTUN_ALLOCATE_SEND_PACKET_FUNC *WintunAllocateSendPacket;
static WINTUN_SEND_PACKET_FUNC *WintunSendPacket;
WINTUN_ADAPTER_HANDLE Adapter;
WINTUN_SESSION_HANDLE Session;
HMODULE Wintun;
static HMODULE InitializeWintun(void)
{
HMODULE Wintun =
LoadLibraryExW(L"wintun.dll", NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32);
if (!Wintun)
return NULL;
#define X(Name) ((*(FARPROC *)&Name = GetProcAddress(Wintun, #Name)) == NULL)
if (X(WintunCreateAdapter) || X(WintunCloseAdapter) || X(WintunOpenAdapter) || X(WintunGetAdapterLUID) ||
X(WintunGetRunningDriverVersion) || X(WintunDeleteDriver) || X(WintunSetLogger) || X(WintunStartSession) ||
X(WintunEndSession) || X(WintunGetReadWaitEvent) || X(WintunReceivePacket) || X(WintunReleaseReceivePacket) ||
X(WintunAllocateSendPacket) || X(WintunSendPacket))
#undef X
{
DWORD LastError = GetLastError();
FreeLibrary(Wintun);
SetLastError(LastError);
return NULL;
}
return Wintun;
}
static void showError()
{
wchar_t err[256];
memset(err, 0, 256);
printf("%ld\n", GetLastError());
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), err, 255, NULL);
int msgboxID = MessageBoxW(NULL,
err,
(LPCWSTR)L"☠",
MB_OK);
}
void handleCleanup()
{
WintunEndSession(Session);
WintunCloseAdapter(Adapter);
FreeLibrary(Wintun);
exit(0);
}
BOOL WINAPI consoleHandler(DWORD signal)
{
if (signal == CTRL_C_EVENT)
{
handleCleanup();
}
return TRUE;
}
int main()
{
DWORD LastError;
GUID ExampleGuid = {0x4d1e55b2, 0xf16f, 0x11cf, 0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30};
DWORD Version;
MIB_UNICASTIPADDRESS_ROW AddressRow;
Wintun = InitializeWintun();
if (!Wintun)
{
printf("Failed to initialize wintun\n");
showError();
}
Adapter = WintunCreateAdapter(L"Sclera", L"Wintun", &ExampleGuid);
if (!Adapter)
{
showError();
handleCleanup();
}
InitializeUnicastIpAddressEntry(&AddressRow);
WintunGetAdapterLUID(Adapter, &AddressRow.InterfaceLuid);
AddressRow.Address.Ipv4.sin_family = AF_INET;
AddressRow.Address.Ipv4.sin_addr.S_un.S_addr = htonl((10 << 24) | (10 << 16) | (10 << 8) | (9 << 0));
AddressRow.OnLinkPrefixLength = 24;
AddressRow.DadState = IpDadStatePreferred;
LastError = CreateUnicastIpAddressEntry(&AddressRow);
if (LastError != ERROR_SUCCESS && LastError != ERROR_OBJECT_ALREADY_EXISTS)
{
showError();
handleCleanup();
}
Session = WintunStartSession(Adapter, WINTUN_MAX_RING_CAPACITY);
if (!Session)
{
showError();
handleCleanup();
}
HANDLE hMap = CreateFileMappingA(
INVALID_HANDLE_VALUE,
NULL,
PAGE_READWRITE,
0,
sizeof(WINTUN_SESSION_HANDLE),
"ScleraSessionStruct");
WINTUN_SESSION_HANDLE *sharedSession = (WINTUN_SESSION_HANDLE *)MapViewOfFile(hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
if (sharedSession == NULL)
{
showError();
}
{
Sleep(INT32_MAX);
}
}
main.c (gcc -I include/ main.c -lwsock32 -lWs2_32 -liphlpapi -o main)
#include <winsock2.h>
#include <Windows.h>
#include <ws2ipdef.h>
#include <iphlpapi.h>
#include <mstcpip.h>
#include <in6addr.h>
#include <winternl.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <sal.h>
#include <winerror.h>
#include <netioapi.h>
#include <stdint.h>
#if !defined(_Must_inspect_result_)
#define _Must_inspect_result_
#endif
#if !defined(_Return_type_success_)
#define _Return_type_success_(x)
#endif
#if !defined(_Post_writable_byte_size_)
#define _Post_writable_byte_size_(x)
#endif
#if !defined(_In_reads_bytes_)
#define _In_reads_bytes_(x)
#endif
#if !defined(_Out_writes_bytes_all_)
#define _Out_writes_bytes_all_(x)
#endif
#if !defined(LOAD_LIBRARY_SEARCH_APPLICATION_DIR)
#define LOAD_LIBRARY_SEARCH_APPLICATION_DIR 0x00000200
#endif
#if !defined(LOAD_LIBRARY_SEARCH_SYSTEM32)
#define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800
#endif
#include "wintun.h"
#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")
static WINTUN_CREATE_ADAPTER_FUNC *WintunCreateAdapter;
static WINTUN_CLOSE_ADAPTER_FUNC *WintunCloseAdapter;
static WINTUN_OPEN_ADAPTER_FUNC *WintunOpenAdapter;
static WINTUN_GET_ADAPTER_LUID_FUNC *WintunGetAdapterLUID;
static WINTUN_GET_RUNNING_DRIVER_VERSION_FUNC *WintunGetRunningDriverVersion;
static WINTUN_DELETE_DRIVER_FUNC *WintunDeleteDriver;
static WINTUN_SET_LOGGER_FUNC *WintunSetLogger;
static WINTUN_START_SESSION_FUNC *WintunStartSession;
static WINTUN_END_SESSION_FUNC *WintunEndSession;
static WINTUN_GET_READ_WAIT_EVENT_FUNC *WintunGetReadWaitEvent;
static WINTUN_RECEIVE_PACKET_FUNC *WintunReceivePacket;
static WINTUN_RELEASE_RECEIVE_PACKET_FUNC *WintunReleaseReceivePacket;
static WINTUN_ALLOCATE_SEND_PACKET_FUNC *WintunAllocateSendPacket;
static WINTUN_SEND_PACKET_FUNC *WintunSendPacket;
static HMODULE InitializeWintun(void)
{
HMODULE Wintun =
LoadLibraryExW(L"wintun.dll", NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32);
if (!Wintun)
return NULL;
#define X(Name) ((*(FARPROC *)&Name = GetProcAddress(Wintun, #Name)) == NULL)
if (X(WintunCreateAdapter) || X(WintunCloseAdapter) || X(WintunOpenAdapter) || X(WintunGetAdapterLUID) ||
X(WintunGetRunningDriverVersion) || X(WintunDeleteDriver) || X(WintunSetLogger) || X(WintunStartSession) ||
X(WintunEndSession) || X(WintunGetReadWaitEvent) || X(WintunReceivePacket) || X(WintunReleaseReceivePacket) ||
X(WintunAllocateSendPacket) || X(WintunSendPacket))
#undef X
{
DWORD LastError = GetLastError();
FreeLibrary(Wintun);
SetLastError(LastError);
return NULL;
}
return Wintun;
}
static void showError()
{
wchar_t err[256];
memset(err, 0, 256);
printf("%ld\n", GetLastError());
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), err, 255, NULL);
int msgboxID = MessageBoxW(NULL,
err,
(LPCWSTR)L"☠",
MB_OK);
}
int main()
{
WINTUN_ADAPTER_HANDLE Adapter;
WINTUN_SESSION_HANDLE Session;
HMODULE Wintun = InitializeWintun();
if (!Wintun)
{
printf("Failed to initialize wintun\n");
showError();
}
printf("Wintun initialized successfully....\n");
Adapter = WintunOpenAdapter(L"Sclera");
if (!Adapter)
{
showError();
}
printf("Adapter opened successfully....\n");
HANDLE hMap = CreateFileMappingA(
INVALID_HANDLE_VALUE,
NULL,
PAGE_READONLY,
0,
sizeof(WINTUN_SESSION_HANDLE),
"ScleraSessionStruct");
WINTUN_SESSION_HANDLE *sharedSession = (WINTUN_SESSION_HANDLE *)MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);
if (sharedSession == NULL)
{
showError();
}
else
{
printf("Wintun session variable obtained my nigga!\n");
}
printf("Session started successfully\n");
{
Sleep(INT32_MAX);
}
return 1;
}
The idea is that there will be multiple instances of the main.c code running and they will be reading/writing packets from the Wintun interface.
Note: Both programs have to be run in administrator mode

Related

Vulkan Instance creation fails with SDL2. I am not sure where I am wrong

I am trying to create an instance and validate that the code can create that instance.
However, For some reason code compiles and fails to create the instance. I do not know what I am doing wrong. Everything before creating instance works. but When I try to validate instance creation it fails. I am using SDL2 to create the window.
This is my cmakelist file:
cmake_minimum_required(VERSION 3.16)
#COMPIER
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_C_COMPILER "gcc")
set(CMAKE_C_STANDARD 17)
set(CMAKE_C_STANDARD_REQUIRED ON)
#FLAGS
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0 -ggdb3")
set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra")
#PROJECT
project(Vulkan_test LANGUAGES C)
enable_language(C)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
#Find packages installed in your system.
include(FindPkgConfig)
pkg_search_module(SDL2 REQUIRED sdl2)
pkg_search_module(Vulkan REQUIRED vulkan)
#Include global directories
include_directories(
${SDL2_INCLUDE_DIRS}
${Vulkan_INCLUDE_DIRS}
)
#Executable Specific
add_executable(VULKAN_TEST
${CMAKE_CURRENT_SOURCE_DIR}/main.c
)
#Compile options
target_compile_options(VULKAN_TEST PUBLIC -O0 -ggdb3 -std=c2x -Wall -Wextra -Wmissing-prototypes -Wwrite-strings -Wpedantic)
#Libraries to link
target_link_libraries(
VULKAN_TEST
${SDL2_LIBRARIES}
${Vulkan_LIBRARIES}
)
This is the is the main.h file that I have:
#pragma once
/* Required Standard Headers */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <stdint.h>
/* SDL2 */
#include <SDL2/SDL.h>
#include <SDL2/SDL_vulkan.h>
/* Vulkan */
#include <vulkan/vulkan.h>
#define rt_assert(expr, ...) ((void) sizeof ((expr) ? 1 : 0), __extension__ ({ \
if (!(expr)) { \
fprintf(stderr,"At function [%s] in file [%s:%d], assert failed: [(%s)].\n", __func__, __FILE__, __LINE__, (#expr)); \
__VA_ARGS__; \
exit(EXIT_FAILURE); \
} \
}))
typedef struct _App {
SDL_Window *window;
int window_height;
int window_width;
const char* window_name;
SDL_Event sdl_event;
bool quit;
VkInstance inst;
uint32_t sdlExtCount;
const char** extNames;
} App;
/* Function Prototype */
void init_window(App *);
void init_vulkan(App *);
void main_loop(App *);
void cleanup(App *);
/* sub vulkan functions */
void init_vk_instance(App *);
This file my main.c
#include "main.h"
#define SDL_MAIN_HANDLED
#define App_init(X) App (X) = { \
.window = NULL, .window_height = 600, .window_width = 800, \
.window_name = "Vulkan Test", .quit = false, \
.inst = VK_NULL_HANDLE \
}
VkApplicationInfo appInfo = {0};
VkInstanceCreateInfo instInfo = {0};
void init_vk_instance(App *App) {
/* Vulkan VkApplicationInfo */
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
appInfo.pApplicationName = App->window_name;
appInfo.applicationVersion = VK_MAKE_API_VERSION(0, 1, 0, 0);
appInfo.pEngineName = App->window_name;
appInfo.engineVersion = VK_MAKE_API_VERSION(0, 1, 0, 0);
/* This is version I have installed from my linux package manager */
appInfo.apiVersion = VK_MAKE_API_VERSION(0,1,3,231);
appInfo.pNext = NULL;
/* Vulkan Instance info - VkInstanceCreateInfo */
instInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
instInfo.pApplicationInfo = &appInfo;
instInfo.enabledLayerCount = 0;
SDL_Vulkan_GetInstanceExtensions(App->window,&App->sdlExtCount,NULL);
App->extNames = malloc(App->sdlExtCount * sizeof(const char*));
SDL_Vulkan_GetInstanceExtensions(App->window,&App->sdlExtCount,App->extNames);
instInfo.enabledExtensionCount = App->sdlExtCount;
instInfo.ppEnabledExtensionNames = App->extNames;
for(uint32_t i = 0; i < App->sdlExtCount; i++) {
printf("%u : %s\n",i,App->extNames[i]);
}
rt_assert( (vkCreateInstance(&instInfo, NULL, &App->inst) == VK_SUCCESS), printf("Instance creation failed\n"), cleanup(App));
}
void init_vulkan(App *App) {
init_vk_instance(App);
}
void init_window(App *App) {
App->window = SDL_CreateWindow( App->window_name,
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
App->window_width, App->window_height, SDL_WINDOW_SHOWN | SDL_WINDOW_VULKAN |
SDL_WINDOW_RESIZABLE);
}
void cleanup(App *App) {
free(App->extNames);
SDL_DestroyWindow(App->window);
SDL_Quit();
}
void main_loop(App *App) {
while(!App->quit) {
while (SDL_PollEvent(&App->sdl_event)) {
if( App->sdl_event.type == SDL_QUIT ) App->quit = true;
}
}
}
int main ( void ) {
printf("Vulkan-Engine\n");
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS);
App_init(test);
init_window(&test);
init_vulkan(&test);
main_loop(&test);
vkDestroyInstance(test.inst, NULL);
cleanup(&test);
return EXIT_SUCCESS;
}
This the output I get after running my program:
Vulkan-Engine
0 : VK_KHR_surface
1 : VK_KHR_xlib_surface
At function [init_vk_instance] in file [/home/Codes/C/Vulkan/main.c:35], assert failed: [((vkCreateInstance(&instInfo, NULL, &App->inst) == VK_SUCCESS))].
Instance creation failed
CMake output during compilation:
-- The C compiler identification is GNU 12.2.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/gcc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Found PkgConfig: /usr/bin/pkg-config (found version "0.29.2")
-- Checking for one of the modules 'sdl2'
-- Checking for one of the modules 'vulkan'
-- Configuring done
-- Generating done
-- Build files have been written to: /home/Codes/C/Vulkan/build
[ 50%] Building C object CMakeFiles/VULKAN_TEST.dir/main.c.o
[100%] Linking C executable /home/Codes/C/Vulkan/VULKAN_TEST
[100%] Built target VULKAN_TEST
These are the vulkan related package I have installed on my system through package manager:
As you see from the image the vulkan api version is 1.3.231.1_1. Am I using the VK_MAKE_API_VERSION(0,1,3,231) properly?
I think you are missing KHR macro
For example I am using windows 10 and MSYS2
This is what I did
#define VK_USE_PLATFORM_WIN32_KHR
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define SDL_MAIN_HANDLED
#include <SDL2/SDL.h>
#include <SDL2/SDL_vulkan.h>
#include <vulkan/vulkan.h>
#include <vulkan/vulkan_core.h>
int main(int argc, char** argv)
{
if (0 != SDL_Init(SDL_INIT_EVERYTHING))
{
printf("failed to initialize SDL2 with everything\n");
}
SDL_Window* window = SDL_CreateWindow("test", 10, 10, 640, 480, SDL_WINDOW_SHOWN | SDL_WINDOW_VULKAN);
if (NULL == window)
{
printf("failed to create window\n");
}
VkApplicationInfo app_info = { 0 };
app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
app_info.apiVersion = VK_API_VERSION_1_3;
app_info.pApplicationName = "test-app";
app_info.applicationVersion = VK_MAKE_API_VERSION(1, 0, 0, 0);
app_info.pEngineName = "test-engine";
app_info.engineVersion = VK_MAKE_API_VERSION(1, 0, 0, 0);
VkInstanceCreateInfo instance_info = { 0 };
instance_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
instance_info.pApplicationInfo = &app_info;
instance_info.enabledLayerCount = 0;
instance_info.ppEnabledLayerNames = NULL;
unsigned int count = 0;
SDL_Vulkan_GetInstanceExtensions(window, &count, NULL);
const char** extensions = malloc(sizeof(char*) * count);
SDL_Vulkan_GetInstanceExtensions(window, &count, extensions);
for (unsigned int i = 0; i < count; i ++)
{
printf("%u: %s\n", i, extensions[i]);
}
instance_info.enabledExtensionCount = count;
instance_info.ppEnabledExtensionNames = extensions;
VkInstance instance = VK_NULL_HANDLE;
if (0 > vkCreateInstance(&instance_info, NULL, &instance))
{
printf("failed to create instance\n");
}
VkSurfaceKHR surface = VK_NULL_HANDLE;
if (SDL_FALSE == SDL_Vulkan_CreateSurface(window, instance, &surface))
{
printf("failed to create surface, SDL Error: %s", SDL_GetError());
}
return 0;
}
For me it is working fine, so my observation is you need to find a way for defining similar macro like #define VK_USE_PLATFORM_WIN32_KHR
Below are the list extensions assumed in vulkan.h
VK_USE_PLATFORM_ANDROID_KHR
VK_USE_PLATFORM_FUCHSIA
VK_USE_PLATFORM_IOS_MVK
VK_USE_PLATFORM_MACOS_MVK
VK_USE_PLATFORM_METAL_EXT
VK_USE_PLATFORM_VI_NN
VK_USE_PLATFORM_WAYLAND_KHR
VK_USE_PLATFORM_WIN32_KHR
VK_USE_PLATFORM_XCB_KHR
VK_USE_PLATFORM_XLIB_KHR
VK_USE_PLATFORM_DIRECTFB_EXT
VK_USE_PLATFORM_XLIB_XRANDR_EXT
VK_USE_PLATFORM_GGP
VK_USE_PLATFORM_SCREEN_QNX
VK_ENABLE_BETA_EXTENSIONS
This is how I compile in MSYS2
gcc -O0 -g3 -Wall -c -fmessage-length=0 -o "src\\ansi-c.o" "..\\src\\ansi-c.c"
gcc -o ansi-c.exe "src\\ansi-c.o" -lmingw32 -lSDL2main -lSDL2 -lvulkan-1.dll

how I can enforce OpenSSL to use my system's root CA if I make my application for linux or for windows 10 or later?

I am making the following piece of code:
#include <stdio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <shlwapi.h>
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__)
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#include <winsock2.h>
#include <ws2tcpip.h>
#include <shlwapi.h>
// Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib
#pragma comment (lib, "Ws2_32.lib")
//#pragma comment (lib, "Mswsock.lib")
//#pragma comment (lib, "AdvApi32.lib")
#define WIN32_LEAN_AND_MEAN
int verifyCerts( SSL_CTX* ctx )
{
// directory where executable is
char path[MAX_PATH] = "";
memset(path, 0, MAX_PATH);
GetModuleFileName(0, path, MAX_PATH);
PathRemoveFileSpec(path);
sprintf(path,"%s\\%s",path,"certificates");
printf("\nCert path %s\n",path);
sprintf(path,"%s\\%s",path,"certificates");
printf("\nCert path %s\n",path);
int value = SSL_CTX_load_verify_locations(ctx,NULL,path);
}
#else // By default use system's CA root
int verifyCerts( SSL_CTX* ctx )
{
}
#endif
SSL_CTX* InitCTX(void)
{
OpenSSL_add_all_algorithms();
SSL_load_error_strings();
const SSL_METHOD* method = SSLv23_method();
SSL_CTX* ctx = SSL_CTX_new(method);
SSL_CTX_set_options(ctx, SSL_OP_ALL | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1);
if (ctx == NULL)
{
ERR_print_errors_fp(stderr);
abort();
}
int value = verifyCerts( ctx );
if(value == 0) {
printf("Certificate error\n");
exit(1);
}
SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,NULL);
return ctx;
}
In my case I want to do the following:
For windows XP (legacy application) to provide certificates alongside to my application so I can mame my application as sacure as possible.
At any other case (for linux systems or windows 10 or above) I'll use the OS's default CA certs (no hussle to provide my own).
So how I can ensure that the latter case is applicable as well?
At #else section just place the following code:
int verifyCerts( SSL_CTX* ctx )
{
const char *path = getenv(X509_get_default_cert_dir_env());
if (!path){
path = X509_get_default_cert_dir();
}
return SSL_CTX_load_verify_locations(ctx,NULL,path);
}
That will allow for linux systems to verify using default certs path. So for windows XP only we can use custom mingw flags.

errno = 2 right after call to bpf_object__open_file and libbpf_get_error not saying anything

I wrote a simple ebpf so I opened it with obj = bpf_object__open_file(filename, NULL);
then when I do prog = bpf_object__find_program_by_name(obj, "kprobe/__x64_sys_write");
This function returns NULL and prints message that printf("finding a prog in obj file failed\n");. so basically my function or program could not be found in object file, I like to know what might be the reason for this so I also found after the call to bpf_object__open_file my errno got set to 2 so I like to know what is exactly happening why my errno set to 2 right after bpf_object__open_file and I made sure that file does exists
this condition is also not fullfilling
if (libbpf_get_error(obj)) {
printf("ERROR: opening BPF object file failed\n");
This is a loader program
// SPDX-License-Identifier: GPL-2.0
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/filter.h>
#include <linux/seccomp.h>
#include <sys/prctl.h>
#include <bpf/bpf.h>
#include <bpf/libbpf.h>
#include <sys/resource.h>
#include <errno.h>
//#include "trace_helpers.h"
#ifdef __mips__
#define MAX_ENTRIES 6000 /* MIPS n64 syscalls start at 5000 */
#else
#define MAX_ENTRIES 1024
#endif
/* install fake seccomp program to enable seccomp code path inside the kernel,
* so that our kprobe attached to seccomp_phase1() can be triggered
*/
static void install_accept_all_seccomp(void)
{
struct sock_filter filter[] = {
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
};
struct sock_fprog prog = {
.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
.filter = filter,
};
if (prctl(PR_SET_SECCOMP, 2, &prog))
perror("prctl");
}
int main(int ac, char **argv)
{
struct bpf_link *link = NULL;
struct bpf_program *prog;
struct bpf_object *obj;
int key, fd, progs_fd;
const char *section;
char filename[256]="/home/fawad/bpf/linux-5.13.1/samples/bpf/kern5.o";
printf("%s\n",filename);
FILE *f;
//snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
printf("errono before %d\n",errno);
obj = bpf_object__open_file(filename, NULL);
printf("errono after %d\n",errno);
if (libbpf_get_error(obj)) {
printf("ERROR: opening BPF object file failed\n");
return 0;
}
printf("errno before %d\n",errno);
prog = bpf_object__find_program_by_name(obj, "kprobe/__x64_sys_write");
printf("errno after %d\n",errno);
if (!prog) {
printf("finding a prog in obj file failed\n");
goto cleanup;
}
/* load BPF program */
if (bpf_object__load(obj)) {
fprintf(stderr, "ERROR: loading BPF object file failed\n");
goto cleanup;
}
link = bpf_program__attach(prog);
if (libbpf_get_error(link)) {
fprintf(stderr, "ERROR: bpf_program__attach failed\n");
link = NULL;
goto cleanup;
}
progs_fd = bpf_object__find_map_fd_by_name(obj, "progs");
if (progs_fd < 0) {
fprintf(stderr, "ERROR: finding a map in obj file failed\n");
goto cleanup;
}
bpf_object__for_each_program(prog, obj) {
section = bpf_program__section_name(prog);
/* register only syscalls to PROG_ARRAY */
if (sscanf(section, "kprobe/%d", &key) != 1)
continue;
fd = bpf_program__fd(prog);
bpf_map_update_elem(progs_fd, &key, &fd, BPF_ANY);
}
install_accept_all_seccomp();
f = popen("dd if=/dev/zero of=/dev/null count=5", "r");
(void) f;
// read_trace_pipe();
cleanup:
bpf_link__destroy(link);
bpf_object__close(obj);
return 0;
}
and this is ebpf program
/* Copyright (c) 2015 PLUMgrid, http://plumgrid.com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
* License as published by the Free Software Foundation.
*/
#include <linux/ptrace.h>
#include <linux/version.h>
#include <linux/bpf.h>
#include <linux/seccomp.h>
#include <linux/unistd.h>
//#include "syscall_nrs.h"
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#define PROG(F) SEC("kprobe/"__stringify(F)) int bpf_func_##F
struct {
__uint(type, BPF_MAP_TYPE_PROG_ARRAY);
__uint(key_size, sizeof(int));
__uint(value_size, sizeof(int));
#ifdef __mips__
__uint(max_entries, 6000); /* MIPS n64 syscalls start at 5000 */
#else
__uint(max_entries, 1024);
#endif
} progs SEC(".maps");
/*SEC("kprobe/SYS__NR_write")
int bpf_prog2(struct pt_regs *ctx)
{
struct seccomp_data sd;
bpf_probe_read_kernel(&sd, sizeof(sd), (void *)PT_REGS_PARM2(ctx));
if (sd.args[2] == 512) {
char fmt[] = "write(fd=%d, buf=%p, size=%d)\n";
bpf_trace_printk(fmt, sizeof(fmt),
sd.args[0], sd.args[1], sd.args[2]);
}
return 0;
}*/
SEC("kprobe/__seccomp_filter")
int bpf_prog1(struct pt_regs *ctx)
{
int sc_nr = (int)PT_REGS_PARM1(ctx);
/* dispatch into next BPF program depending on syscall number */
bpf_tail_call(ctx, &progs, sc_nr);
/* fall through -> unknown syscall */
if (sc_nr >= __NR_getuid && sc_nr <= __NR_getsid) {
char fmt[] = "syscall=%d (one of get/set uid/pid/gid)\n";
bpf_trace_printk(fmt, sizeof(fmt), sc_nr);
}
return 0;
}
SEC("kprobe/__x64_sys_write")
/* we jump here when syscall number == __NR_write */
//PROG(SYS__NR_write)(struct pt_regs *ctx)
int __x64_sys_write(struct pt_regs *ctx)
{
struct seccomp_data sd;
bpf_probe_read_kernel(&sd, sizeof(sd), (void *)PT_REGS_PARM2(ctx));
if (sd.args[2] == 512) {
char fmt[] = "write(fd=%d, buf=%p, size=%d)\n";
bpf_trace_printk(fmt, sizeof(fmt),
sd.args[0], sd.args[1], sd.args[2]);
}
return 0;
}
/*
PROG(SYS__NR_read)(struct pt_regs *ctx)
{
struct seccomp_data sd;
bpf_probe_read_kernel(&sd, sizeof(sd), (void *)PT_REGS_PARM2(ctx));
if (sd.args[2] > 128 && sd.args[2] <= 1024) {
char fmt[] = "read(fd=%d, buf=%p, size=%d)\n";
bpf_trace_printk(fmt, sizeof(fmt),
sd.args[0], sd.args[1], sd.args[2]);
}
return 0;
}
#ifdef __NR_mmap2
PROG(SYS__NR_mmap2)(struct pt_regs *ctx)
{
char fmt[] = "mmap2\n";
bpf_trace_printk(fmt, sizeof(fmt));
return 0;
}
#endif
#ifdef __NR_mmap
PROG(SYS__NR_mmap)(struct pt_regs *ctx)
{
char fmt[] = "mmap\n";
bpf_trace_printk(fmt, sizeof(fmt));
return 0;
}
#endif
*/
char _license[] SEC("license") = "GPL";
int _version SEC("version") = LINUX_VERSION_CODE;
compiling userspace loader like
clang -L /usr/lib/usr/lib64/ -I /usr/include/ -I /usr/lib/usr/include/ tracex5_user.c -o user1.o -lbpf
compiling kernel ebpf program like
sudo clang -Wall -O2 -g -target bpf -I /usr/lib/usr/include -I /usr/include/x86_64-linux-gnu/ -I /usr/include/linux/ -c syscall_tp_kern.c -o kern5.o
Please try this command
bpftool prog load bpf_test.o /sys/fs/bpf/vfs_create
In my scenario, I got the error:
libbpf: failed to find BTF for extern 'PT_REGS_PARM2': -3

Logging node activity in contiki and send it to a sink

I'm trying to build an application in contiki3.0 where several nodes broadcast their sensor data while writing it in a log and then every 3 min send the log to a sink and start a new log.
I also want the sink to acknowledge receiving the log.
I've been trying to do that for a month but I couldn't get the code to work properly, I would appreciate any help.
This is the code of the nodes:
#include "contiki-conf.h"
#include "dev/button-sensor.h"
#include "dev/light-sensor.h"
#include "dev/leds.h"
#include "net/linkaddr.h"
#include "contiki.h"
#include "lib/random.h"
#include "sys/ctimer.h"
#include "sys/etimer.h"
#include "net/ip/uip.h"
#include "net/ipv6/uip-ds6.h"
#include "event-post.h"
#include "simple-udp.h"
#include <limits.h>
#include <stdio.h>
#include <string.h>
#define UDP_PORT 1234
#define SEND_INTERVAL (20 * CLOCK_SECOND)
#define SEND_TIME (random_rand() % (SEND_INTERVAL))
/*---------------------------------------------------------------------------*/
static struct simple_udp_connection broadcast_connection;
static process_event_t event_data_ready;
/*---------------------------------------------------------------------------*/
PROCESS(sara, "broadcast");
PROCESS(broadcast_example_process, "BB");
AUTOSTART_PROCESSES(&sara, &broadcast_example_process);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(sara, ev, data)
{
static struct etimer timer;
static struct event_struct es;
PROCESS_BEGIN();
es.s_val = SHRT_MAX-2;
es.i_val = INT_MAX-2;
es.l_val = LONG_MAX-2;
/* sizeof(long long) == sizeof(long) on sensinodes - see other examples*/
es.ll_val = LONG_MAX-2;
/* and some typedef-ed unsigned variables */
es.u8_val = UCHAR_MAX-2;
es.u16_val = USHRT_MAX-2;
es.u32_val = ULONG_MAX-2;
event_data_ready = process_alloc_event();
printf("Contiki allocated event ID %d.\r\n", event_data_ready);
etimer_set(&timer, CLOCK_CONF_SECOND * 2);
while(1){
printf("Sensor process: Wait for timer event...\r\n");
/* Wait on our timer */
PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);
/* blip */
/* leds_toggle(LEDS_BLUE); */
/* Set the 'sensor' value before throwing the event */
printf("Sensor Process: Incrementing values...%d,%d,%d,%d,%d,%d, %d\r\n", es.s_val++, es.i_val++, es.l_val++, es.ll_val++, es.u8_val++, es.u16_val++,es.u32_val++);
/* Post our event.
* N.B. es is declared static.
* Try passing a volatile variable and observe the results... */
printf("Sensor Process: Generating 'Data Ready' event.\r\n");
process_post(&broadcast_example_process, event_data_ready, &es);
/* reset the timer so we can wait on it again */
etimer_reset(&timer);
}
SENSORS_ACTIVATE(button_sensor);
SENSORS_ACTIVATE(light_sensor);
static int counter=0;
printf("Light: \%u\n", light_sensor);
counter++;
if (counter == 4){
printf("Hello, world you have read the light 4 times \n");
}
PROCESS_END();
}
static void
receiver(struct simple_udp_connection *c,
const uip_ipaddr_t *sender_addr,
uint16_t sender_port,
const uip_ipaddr_t *receiver_addr,
uint16_t receiver_port,
const uint8_t *data,
uint16_t datalen)
{
printf("Data received on port %d from port %d with length %d\n",
receiver_port, sender_port, datalen);
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(broadcast_example_process, ev, data)
{
static struct etimer periodic_timer;
static struct etimer send_timer;
uip_ipaddr_t addr;
PROCESS_BEGIN();
simple_udp_register(&broadcast_connection, UDP_PORT,
NULL, UDP_PORT,
receiver);
etimer_set(&periodic_timer, SEND_INTERVAL);
while(1) {
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&periodic_timer));
etimer_reset(&periodic_timer);
etimer_set(&send_timer, SEND_TIME);
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&send_timer));
printf("Sending broadcast\n");
uip_create_linklocal_allnodes_mcast(&addr);
simple_udp_sendto(&broadcast_connection, data, sizeof(data), &addr);
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
and this is the sink code, which is a udp-sink code from Contiki examples:
#include "contiki.h"
#include "contiki-lib.h"
#include "contiki-net.h"
#include "net/ip/uip.h"
#include "net/rpl/rpl.h"
#include "net/linkaddr.h"
#include "net/netstack.h"
#include "dev/button-sensor.h"
#include "dev/serial-line.h"
#if CONTIKI_TARGET_Z1
#include "dev/uart0.h"
#else
#include "dev/uart1.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "collect-common.h"
#include "collect-view.h"
#define DEBUG DEBUG_PRINT
#include "net/ip/uip-debug.h"
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
#define UDP_CLIENT_PORT 8775
#define UDP_SERVER_PORT 5688
static struct uip_udp_conn *server_conn;
PROCESS(udp_server_process, "UDP server process");
AUTOSTART_PROCESSES(&udp_server_process,&collect_common_process);
/*---------------------------------------------------------------------------*/
void
collect_common_set_sink(void)
{
}
/*---------------------------------------------------------------------------*/
void
collect_common_net_print(void)
{
printf("I am sink!\n");
}
/*---------------------------------------------------------------------------*/
void
collect_common_send(void)
{
/* Server never sends */
}
/*---------------------------------------------------------------------------*/
void
collect_common_net_init(void)
{
#if CONTIKI_TARGET_Z1
uart0_set_input(serial_line_input_byte);
#else
uart1_set_input(serial_line_input_byte);
#endif
serial_line_init();
PRINTF("I am sink!\n");
}
/*---------------------------------------------------------------------------*/
static void
tcpip_handler(void)
{
uint8_t *appdata;
linkaddr_t sender;
uint8_t seqno;
uint8_t hops;
if(uip_newdata()) {
appdata = (uint8_t *)uip_appdata;
sender.u8[0] = UIP_IP_BUF->srcipaddr.u8[15];
sender.u8[1] = UIP_IP_BUF->srcipaddr.u8[14];
seqno = *appdata;
hops = uip_ds6_if.cur_hop_limit - UIP_IP_BUF->ttl + 1;
collect_common_recv(&sender, seqno, hops,
appdata + 2, uip_datalen() - 2);
}
}
/*---------------------------------------------------------------------------*/
static void
print_local_addresses(void)
{
int i;
uint8_t state;
PRINTF("Server IPv6 addresses: ");
for(i = 0; i < UIP_DS6_ADDR_NB; i++) {
state = uip_ds6_if.addr_list[i].state;
if(state == ADDR_TENTATIVE || state == ADDR_PREFERRED) {
PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr);
PRINTF("\n");
/* hack to make address "final" */
if (state == ADDR_TENTATIVE) {
uip_ds6_if.addr_list[i].state = ADDR_PREFERRED;
}
}
}
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(udp_server_process, ev, data)
{
uip_ipaddr_t ipaddr;
struct uip_ds6_addr *root_if;
PROCESS_BEGIN();
PROCESS_PAUSE();
SENSORS_ACTIVATE(button_sensor);
PRINTF("UDP server started\n");
#if UIP_CONF_ROUTER
uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 1);
/* uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); */
uip_ds6_addr_add(&ipaddr, 0, ADDR_MANUAL);
root_if = uip_ds6_addr_lookup(&ipaddr);
if(root_if != NULL) {
rpl_dag_t *dag;
dag = rpl_set_root(RPL_DEFAULT_INSTANCE,(uip_ip6addr_t *)&ipaddr);
uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0);
rpl_set_prefix(dag, &ipaddr, 64);
PRINTF("created a new RPL dag\n");
} else {
PRINTF("failed to create a new RPL DAG\n");
}
#endif /* UIP_CONF_ROUTER */
print_local_addresses();
/* The data sink runs with a 100% duty cycle in order to ensure high
packet reception rates. */
NETSTACK_RDC.off(1);
server_conn = udp_new(NULL, UIP_HTONS(UDP_CLIENT_PORT), NULL);
udp_bind(server_conn, UIP_HTONS(UDP_SERVER_PORT));
PRINTF("Created a server connection with remote address ");
PRINT6ADDR(&server_conn->ripaddr);
PRINTF(" local/remote port %u/%u\n", UIP_HTONS(server_conn->lport),
UIP_HTONS(server_conn->rport));
while(1) {
PROCESS_YIELD();
if(ev == tcpip_event) {
tcpip_handler();
} else if (ev == sensors_event && data == &button_sensor) {
PRINTF("Initiaing global repair\n");
rpl_repair_root(RPL_DEFAULT_INSTANCE);
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

Linux kernel version mismatch

I'm trying to create a simple kernel module which makes the keyboard LEDs flashing. It works fine on Linux 3.16 (Ubuntu 14.04) but it doesn't change the LED status on 4.5 (Arch).
I can't figure out what kind of difference causes it, I didn't find anything useful in demsg. Any idea how could I find about this problem?
Code:
#include <linux/module.h>
#include <linux/device.h>
#include <linux/tty.h>
#include <linux/kd.h>
#include <linux/vt.h>
#include <linux/console_struct.h>
#include <linux/vt_kern.h>
#include "device.h"
#include "timer.h"
#define LEDS_ON 0x07
#define LEDS_OFF 0xFF
static int major_number;
static struct class *class;
static struct tty_driver *driver;
static unsigned long led_status = LEDS_OFF;
static void timer_callbak(void)
{
if (led_status == LEDS_OFF) {
led_status = LEDS_ON;
} else {
led_status = LEDS_OFF;
}
driver->ops->ioctl(vc_cons[fg_console].d->port.tty, KDSETLED, led_status);
}
static long device_ioctl(struct file *file, unsigned int command, unsigned long argument)
{
if (command == ON && led_status == LEDS_OFF) {
timer_init(&timer_callbak);
} else if (command == OFF && led_status == LEDS_OFF){
timer_exit();
} else if (command != OFF && command != ON) {
printk(KERN_WARNING "Invalid ioctl() command");
return -1;
}
return 0;
}
static struct file_operations operations = {
.unlocked_ioctl = device_ioctl
};
dev_t create_dev_type(void)
{
return MKDEV(major_number, 0);
}
void create_device(void)
{
major_number = register_chrdev(0, NAME, &operations);
printk("Keyboard leds registered with major_number \"%d\"", major_number);
class = class_create(THIS_MODULE, NAME);
device_create(class, NULL, create_dev_type(), NULL, NAME);
}
void device_init(void)
{
create_device();
driver = vc_cons[fg_console].d->port.tty->driver;
printk("Keyboard leds device Initialized");
}
void device_exit(void)
{
device_destroy(class, create_dev_type());
class_unregister(class);
class_destroy(class);
unregister_chrdev(major_number, NAME);
printk("Keyboard leds device exited");
}
MODULE_LICENSE("GPL");
That's how I'm trying to invoke it:
#include <sys/ioctl.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include "src/device.h"
int main(void)
{
int fd;
if ((fd = open("/dev/keyboard_leds", O_RDWR|O_NONBLOCK)) < 0) {
perror("Open failed!");
return -1;
}
ioctl(fd, ON);
close(fd);
return 0;
}

Resources