Linux bind any address

Linux bind any address

#include /* См. ЗАМЕЧАНИЯ */
#include
int bind(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);

ОПИСАНИЕ

После создания с помощью socket(2), сокет появляется в адресном пространстве (семействе адресов), но без назначенного адреса. bind() назначает адрес, заданный в addr, сокету, указываемому дескриптором файла sockfd. В аргументе addrlen задаётся размер структуры адреса (в байтах), на которую указывает addr. В силу традиции, эта операция называется «присваивание сокету имени». Обычно, сокету типа SOCK_STREAM нужно назначить локальный адрес с помощью bind() до того, как он сможет принимать соединения (см. accept(2)). Правила, используемые при привязке имён, отличаются в разных семействах адресов. Подробности см. в соответствующем справочных страницах в разделе 7. Описание AF_INET находится в ip(7), AF_INET6 в ipv6(7), AF_UNIX в unix(7), AF_APPLETALK в ddp(7), AF_PACKET в packet(7), AF_X25 в x25(7), а AF_NETLINK в netlink(7). Реальная структура, передаваемая через addr, зависит от семейства адресов. Структура sockaddr определяется так:

Единственным смыслом этой структуры является преобразование указателя структуры, передаваемого в addr, чтобы избежать предупреждений компилятора. См. ПРИМЕР ниже.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

При успешном выполнении возвращается 0. В случае ошибки возвращается -1, а errno устанавливается в соответствующее значение.

ОШИБКИ

EACCES Адрес защищён, или пользователь не является суперпользователем. EADDRINUSE Указанный адрес уже используется. EADDRINUSE (доменные сокеты Интернета) В структуре адреса сокета указан номер порта равный нулю, но при попытке привязаться к эфемеридному порту, было определено, что все номера в диапазоне эфемеридных портов уже используются. Смотрите обсуждение /proc/sys/net/ipv4/ip_local_port_range в ip(7). EBADF Значение sockfd не является правильным файловым дескриптором. EINVAL Сокет уже привязан к адресу. EINVAL Некорректное значение addrlen, или в addr указан некорректный адрес для этого доменного сокета. ENOTSOCK Файловый дескриптор sockfd указывает не на каталог. Следующие ошибки только для сокетов домена UNIX (AF_UNIX): EACCES Поиск запрещён из-за одного из частей префикса пути (см. также path_resolution(7)). EADDRNOTAVAIL Запрошен несуществующий интерфейс или запрашиваемый адрес не является локальным. EFAULT addr указывает вне адресного пространства, доступного пользователю. ELOOP При определении addr превышено количество переходов по символьной ссылке. ENAMETOOLONG Аргумент addr слишком большой. ENOENT Компонент из каталожного префикса пути сокета не существует. ENOMEM Недостаточное количество памяти ядра. ENOTDIR Компонент в префиксе пути не является каталогом. EROFS Попытка создания inode сокета на файловой системе, доступной только для чтения.

СООТВЕТСТВИЕ СТАНДАРТАМ

ЗАМЕЧАНИЯ

В POSIX.1 не требуется включение , и этот заголовочный файл не требуется в Linux. Однако, для некоторых старых реализаций (BSD) требует данный файл, и в переносимых приложениях для предосторожности, вероятно, лучше его указать. Третий аргумент bind() в действительности имеет тип int (в 4.x BSD, libc4 и libc5). Ситуация несколько запуталась с введением POSIX для него отдельного типа socklen_t, также используемого в glibc. См. также accept(2).

ДЕФЕКТЫ

ПРИМЕР

Пример использования bind() с сокетами домена Internet можно найти в getaddrinfo(3). Следующий пример показывает как привязать потоковый сокет к домену UNIX (AF_UNIX) и принимать соединения:

#include #include #include #include #include #define MY_SOCK_PATH "/somepath" #define LISTEN_BACKLOG 50 #define handle_error(msg) \ do < perror(msg); exit(EXIT_FAILURE); >while (0) int main(int argc, char *argv[]) < int sfd, cfd; struct sockaddr_un my_addr, peer_addr; socklen_t peer_addr_size; sfd = socket(AF_UNIX, SOCK_STREAM, 0); if (sfd == -1) handle_error("socket"); memset(&my_addr, 0, sizeof(struct sockaddr_un)); /* Очистка структуры */ my_addr.sun_family = AF_UNIX; strncpy(my_addr.sun_path, MY_SOCK_PATH, sizeof(my_addr.sun_path) - 1); if (bind(sfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr_un)) == -1) handle_error("bind"); if (listen(sfd, LISTEN_BACKLOG) == -1) handle_error("listen"); /* Теперь мы можем принимать входящие соединения по одному с помощью accept(2) */ peer_addr_size = sizeof(struct sockaddr_un); cfd = accept(sfd, (struct sockaddr *) &peer_addr, &peer_addr_size); if (cfd == -1) handle_error("accept"); /* Код обработки входящего соединения(й). */ /* Если имя пути сокета, MY_SOCK_PATH, больше не требуется, то его нужно удалить с помощью unlink(2) или remove(3) */ >

Источник

Читайте также:  Kali linux on a chromebook

Linux bind any address

The bind() function shall assign a local socket address address to a socket identified by descriptor socket that has no local socket address assigned. Sockets created with the socket() function are initially unnamed; they are identified only by their address family. The bind() function takes the following arguments: socket Specifies the file descriptor of the socket to be bound. address Points to a sockaddr structure containing the address to be bound to the socket. The length and format of the address depend on the address family of the socket. address_len Specifies the length of the sockaddr structure pointed to by the address argument. The socket specified by socket may require the process to have appropriate privileges to use the bind() function.

RETURN VALUE

Upon successful completion, bind() shall return 0; otherwise, -1 shall be returned and errno set to indicate the error.

ERRORS

The bind() function shall fail if: EADDRINUSE The specified address is already in use. EADDRNOTAVAIL The specified address is not available from the local machine. EAFNOSUPPORT The specified address is not a valid address for the address family of the specified socket. EBADF The socket argument is not a valid file descriptor. EINVAL The socket is already bound to an address, and the protocol does not support binding to a new address; or the socket has been shut down. ENOTSOCK The socket argument does not refer to a socket. EOPNOTSUPP The socket type of the specified socket does not support binding to an address. If the address family of the socket is AF_UNIX, then bind() shall fail if: EACCES A component of the path prefix denies search permission, or the requested name requires writing in a directory with a mode that denies write permission. EDESTADDRREQ or EISDIR The address argument is a null pointer. EIO An I/O error occurred. ELOOP A loop exists in symbolic links encountered during resolution of the pathname in address. ENAMETOOLONG A component of a pathname exceeded characters, or an entire pathname exceeded characters. ENOENT A component of the pathname does not name an existing file or the pathname is an empty string. ENOTDIR A component of the path prefix of the pathname in address is not a directory. EROFS The name would reside on a read-only file system. The bind() function may fail if: EACCES The specified address is protected and the current user does not have permission to bind to it. EINVAL The address_len argument is not a valid length for the address family. EISCONN The socket is already connected. ELOOP More than symbolic links were encountered during resolution of the pathname in address. ENAMETOOLONG Pathname resolution of a symbolic link produced an intermediate result whose length exceeds . ENOBUFS Insufficient resources were available to complete the call. The following sections are informative.

Читайте также:  Восстановить удаленные данные линукс

Источник

bind(2) — Linux man page

When a socket is created with socket(2), it exists in a name space (address family) but has no address assigned to it. bind() assigns the address specified by addr to the socket referred to by the file descriptor sockfd. addrlen specifies the size, in bytes, of the address structure pointed to by addr. Traditionally, this operation is called «assigning a name to a socket».

It is normally necessary to assign a local address using bind() before a SOCK_STREAM socket may receive connections (see accept(2)).

The rules used in name binding vary between address families. Consult the manual entries in Section 7 for detailed information. For AF_INET see ip(7), for AF_INET6 see ipv6(7), for AF_UNIX see unix(7), for AF_APPLETALK see ddp(7), for AF_PACKET see packet(7), for AF_X25 see x25(7) and for AF_NETLINK see netlink(7).

The actual structure passed for the addr argument will depend on the address family. The sockaddr structure is defined as something like:

The only purpose of this structure is to cast the structure pointer passed in addr in order to avoid compiler warnings. See EXAMPLE below.

Return Value

On success, zero is returned. On error, -1 is returned, and errno is set appropriately.

Errors

The address is protected, and the user is not the superuser. EADDRINUSE The given address is already in use. EBADF

sockfd is not a valid descriptor.

The socket is already bound to an address. ENOTSOCK sockfd is a descriptor for a file, not a socket. The following errors are specific to UNIX domain (AF_UNIX) sockets: EACCES

Search permission is denied on a component of the path prefix. (See also path_resolution(7).) EADDRNOTAVAIL A nonexistent interface was requested or the requested address was not local. EFAULT

addr points outside the user’s accessible address space.

The addrlen is wrong, or the socket was not in the AF_UNIX family.

Too many symbolic links were encountered in resolving addr. ENAMETOOLONG addr is too long. ENOENT

Insufficient kernel memory was available. ENOTDIR A component of the path prefix is not a directory. EROFS

The socket inode would reside on a read-only file system.

Conforming To

SVr4, 4.4BSD, POSIX.1-2001 (bind() first appeared in 4.2BSD).

Notes

POSIX.1-2001 does not require the inclusion of , and this header file is not required on Linux. However, some historical (BSD) implementations required this header file, and portable applications are probably wise to include it.

The third argument of bind() is in reality an int (and this is what 4.x BSD and libc4 and libc5 have). Some POSIX confusion resulted in the present socklen_t, also used by glibc. See also accept(2).

Читайте также:  Установка anaconda python linux

Bugs

The transparent proxy options are not described.

Example

An example of the use of bind() with Internet domain sockets can be found in getaddrinfo(3).

The following example shows how to bind a stream socket in the UNIX (AF_UNIX) domain, and accept connections:

#include sys/socket.h> #include sys/un.h> #include stdlib.h> #include stdio.h> #include string.h> #define MY_SOCK_PATH "/somepath" #define LISTEN_BACKLOG 50 #define handle_error(msg) \ do < perror(msg); exit(EXIT_FAILURE); >while (0) int main(int argc, char *argv[]) < int sfd, cfd; struct sockaddr_un my_addr, peer_addr; socklen_t peer_addr_size; sfd = socket(AF_UNIX, SOCK_STREAM, 0); if (sfd == -1) handle_error("socket"); memset(&my_addr, 0, sizeof(struct sockaddr_un)); /* Clear structure */ my_addr.sun_family = AF_UNIX; strncpy(my_addr.sun_path, MY_SOCK_PATH, sizeof(my_addr.sun_path) - 1); if (bind(sfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr_un)) == -1) handle_error("bind"); if (listen(sfd, LISTEN_BACKLOG) == -1) handle_error("listen"); /* Now we can accept incoming connections one at a time using accept(2) */ peer_addr_size = sizeof(struct sockaddr_un); cfd = accept(sfd, (struct sockaddr *) &peer_addr, &peer_addr_size); if (cfd == -1) handle_error("accept"); /* Code to deal with incoming connection(s). */ /* When no longer required, the socket pathname, MY_SOCK_PATH should be deleted using unlink(2) or remove(3) */ >

Источник

How can I allow applications to bind to any address in a subnet assigned to an interface?

I recently got a static IPv6 /56 prefix of my own from Freenet6, and am trying to allow applications to bind arbitrary addresses in the prefix. I modified the tunnel creation script that gogoc uses in order to assign both the client address (here we’ll call it 2001:5c0:1000::cccc/128 ) and the entire subnet I have allocated (here called 2001:5c0:2000:5800::/56 ) to tun and tun:1 , respectively. I can bind an application to listen on 2001:5c0::cccc or 2001:5c0:5800:: just fine, and using IPv6 open port testers indicates that the connection is succeeding. However, the dilemma lies in that I am unable to bind an address like 2001:5c0:2000:5800:1111:2222:3333:4444 , which is part of the subnet I assigned to tun:1 , getting EADDRNOTAVAIL as an error code. socat reads:

2014/05/10 12:12:06 socat[16940] E bind(3, , 28): Cannot assign requested address 

The application I wish to use does not support IP_FREEBIND or IP_TRANSPARENT . Is there a kernel setting I can use to implicitly free-bind sockets? Or perhaps a way to intercept socket creation from a given process, and attach socket options to that creation? ip addr :

1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000 link/ether 04:7d:7b:XX:XX:XX brd ff:ff:ff:ff:ff:ff 3: wlan0: mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether 9c:b7:0d:XX:XX:XX brd ff:ff:ff:ff:ff:ff 5: wlan1: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:c0:ff:XX:XX:XX brd ff:ff:ff:ff:ff:ff inet 192.168.2.8/24 brd 192.168.2.255 scope global wlan1 valid_lft forever preferred_lft forever inet6 fe80::2c0:ffff:feff:70d1/64 scope link valid_lft forever preferred_lft forever 11: tun: mtu 1280 qdisc pfifo_fast state UNKNOWN group default qlen 500 link/none inet6 2001:5c0:1103:5800::/56 scope global valid_lft forever preferred_lft forever inet6 2001:5c0:1000:b::5225/128 scope global valid_lft forever preferred_lft forever 

Источник

Оцените статью
Adblock
detector