16+
Понедельник
19 ноября
Вход |Карта сайта | |Upload |codebook | PARTS

 О смысле всего сущего 0xFF

 Средства и методы разработки

 Мобильная и беспроводная связь

 Блошиный рынок Объявления

caxapa

Микроконтроллеры ARM 

AVR PIC MSP PLD,FPGA,DSP 

Кибернетика Технологии 

Схемы, платы, компоненты 

Средства и методы разработки

 
   Новая тема Правила Регистрация Поиск »» Архив
Вернуться в конференциюТопик полностью
fk0  (02.10.2018 00:43) , в ответ на Если не разделять IP по подсетям, то как тогда "объяснять" хост-процессу, через какой из IP нужно выходить на конкретное устройство? автор: Nikolay_Po
Ну если разделять по подсетям, то и другой прибор нужно в другую подсеть унести... Объяснять можно путём фиксации адреса в момент открытия сокета (bind(2) вызвать после socket(2)). Как-то так, как ниже показано. Компилировать через gcc file.c 
-shared -o libfakebind.so и через LD_PRELOAD подгружать перед использованием. В переменной окружения FAKEBIND=1.2.3.4 задаётся как бы адрес своего порта/интерфейса. Здесь предполагается, что bind(2) таки вызовется программой-клиентом (а если бы не вызывалось, а порт назначался автомагически -- то и проблемы бы не было).
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <assert.h>
#include <err.h>
#include <dlfcn.h>

static in_addr_t force_addr = 0;

void __attribute__ ((constructor)) fakebind_init(void)
{
	const char *args = getenv("FAKEBIND");
	if (args == NULL) return;

	struct addrinfo hints, *result, *rp;
	memset(&hints, 0, sizeof(hints));
	hints.ai_family=AF_INET;
	hints.ai_socktype=SOCK_DGRAM;
	int e = getaddrinfo(args, NULL, &hints, &result);
	if (e!=0)
		errx(1, "fakebind: getaddrinfo %s: %s\n", args, gai_strerror(e));

	for (rp=result; rp!=NULL; rp=rp->ai_next) {
		if (rp->ai_family == AF_INET) {
			force_addr = ((struct sockaddr_in*)rp->ai_addr)->sin_addr.s_addr;
			#if 1
			struct in_addr in; in.s_addr = force_addr;
			fprintf(stderr, "bind 0.0.0.0 to %s\n", inet_ntoa(in));
			#endif
			break;
		}
	}
	freeaddrinfo(result);
	if (rp==NULL)
		errx(1, "fakebind: %s: no INET address to bind\n", args);
}

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{
	struct sockaddr_in subst;

	int val;
	socklen_t len = sizeof(val);
	if (getsockopt(sockfd, SOL_SOCKET, SO_DOMAIN, &val, &len) < 0)
		warn("getsockopt");

	else if (force_addr != 0) {
		const struct sockaddr_in *in = (struct sockaddr_in*)addr;
		if (in->sin_family==AF_INET) {
			assert(addrlen >= sizeof(struct sockaddr_in));
			if (in->sin_addr.s_addr == 0) {
				subst = *in;
				subst.sin_addr.s_addr = force_addr;
				addr = (struct sockaddr*)&subst;
				addrlen = sizeof(subst);
			}
		}
	}

	int (*real_bind)(int, const struct sockaddr *, socklen_t) = dlsym(RTLD_NEXT, "bind");
	assert(real_bind!=NULL);
	return real_bind(sockfd, addr, addrlen);
}

[ZX]
Главная | Карта сайта | О проекте | Проекты | Файлообменник | Регистрация | Вебмастер | RSS
Лето 7527 от сотворения мира. При использовании материалов сайта ссылка на caxapу обязательна.
MMI © MMXVIII