Dél*_*nio 7 networking kernel tcp sysctl socket
我需要运行一个二进制文件,它使用bind零端口参数,从系统中获取一个随机的空闲端口。有没有办法限制允许内核选择的端口范围?
在 Linux 上,你会做类似的事情
sudo sysctl -w net.ipv4.ip_local_port_range="60000 61000"
Run Code Online (Sandbox Code Playgroud)
可以在例如http://www.ncftp.com/ncftpd/doc/misc/ephemeral_ports.html找到更改其他 unices 上的临时端口范围的说明
如果您想在无法访问其源代码的情况下更改二进制文件的运行方式,有时可以使用 shim,一段代码,在您的示例中,它将bind()通过调用您提供的可以操作的函数来替换调用调用真正的函数之前的数据。见LD_PRELOAD在man ld.so。
这里有一些 C 正是这样做的,shim_bind.c,将端口覆盖为 7777,并假设一个 AF_INET 套接字。编译它gcc -Wall -O2 -fpic -shared -ldl -o shim_bind.so shim_bind.c并通过将它放在LD_PRELOAD=shim_bind.so您的命令前面来使用它。
/*
* 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);
}
Run Code Online (Sandbox Code Playgroud)