no Linux, você faria algo como
sudo sysctl -w net.ipv4.ip_local_port_range="60000 61000"
instruções para alterar o intervalo de portas efêmeras em outros unices podem ser encontradas, por exemplo, no link
Existe um binário que preciso executar, que usa bind
com um argumento de porta igual a zero, para obter uma porta livre aleatória do sistema. Existe uma maneira de restringir o intervalo de portas que o kernel pode escolher?
no Linux, você faria algo como
sudo sysctl -w net.ipv4.ip_local_port_range="60000 61000"
instruções para alterar o intervalo de portas efêmeras em outros unices podem ser encontradas, por exemplo, no link
Se você quiser alterar a maneira como um binário é executado sem ter acesso às fontes, às vezes você pode usar um shim, um trecho de código que, no seu exemplo, substituirá a chamada em bind()
por uma chamada para um função que você fornece que pode manipular os dados antes de chamar a função real. Veja LD_PRELOAD
em man ld.so
.
Aqui está um pouco de C que faz exatamente isso, shim_bind.c, sobrescrevendo a porta para 7777 e assumindo um socket AF_INET. Compile com gcc -Wall -O2 -fpic -shared -ldl -o shim_bind.so shim_bind.c
e use-o colocando LD_PRELOAD=shim_bind.so
na frente do seu comando.
/*
* capture calls to a routine and replace with your code
* http://unix.stackexchange.com/a/305336/119298
* gcc -Wall -O2 -fpic -shared -ldl -o shim_bind.so shim_bind.c
* LD_PRELOAD=/path/to/shim_bind.so ./test
*/
#define _GNU_SOURCE /* needed to get RTLD_NEXT defined in dlfcn.h */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <dlfcn.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen){
static int (*real_bind)(int sockfd, const struct sockaddr *addr,
socklen_t addrlen) = NULL;
int port = 7777;
struct sockaddr_in theaddr;
if (!real_bind) {
real_bind = dlsym(RTLD_NEXT, "bind");
char *error = dlerror();
if (error != NULL) {
fprintf(stderr, "%s\n", error);
exit(1);
}
}
fprintf(stderr, "binding: port %d\n", port);
memcpy(&theaddr, addr, sizeof(theaddr));
theaddr.sin_port = htons((unsigned short)port);
return real_bind(sockfd, (struct sockaddr*)&theaddr, addrlen);
}
Tags kernel networking tcp socket sysctl