I am trying to bind a ipv6 port to a ipv6 socket. But the port binded is different than the one I specified.
#include <netdb.h>
#include <netinet/tcp.h>
#include <poll.h>
#include <sys/socket.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int unconnected_sock_ =
socket(PF_INET6, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
struct sockaddr_in6 addr = {0};
addr.sin6_family = AF_INET6;
addr.sin6_port = atoi(argv[1]);
addr.sin6_addr = in6addr_any;
if (bind(unconnected_sock_,
(struct sockaddr*)(&addr),
sizeof(addr)) != 0) {
fprintf(stderr, " error : %s\n", strerror(errno));
}
struct sockaddr_in6 sin;
socklen_t len = sizeof(sin);
getsockname(unconnected_sock_, (struct sockaddr *)&sin, &len);
fprintf(stderr, "port number %d\n", ntohs(sin.sin6_port));
}
output:
ubun - main: ~/socket.exe 54682
port number 39637
asked Sep 21, 2021 at 19:54
suresh
4,25210 gold badges47 silver badges59 bronze badges
1 Answer 1
Please note that 54682 is 0xd59a, while 39637 is 0x9ad5. This is the same value, but written in different byte orders.
From man ipv6:
sin6_port is the protocol port (see sin_port in ip(7));
From man 7 ip:
sin_port contains the port in network byte order.
In the line that prints the port that is bind to the socket, you convert the network byte order to the local one:
fprintf(stderr, "port number %d\n", ntohs(sin.sin6_port));
In the line, that sets the requested port number, you are not converting the byte order from native to the network one:
addr.sin6_port = atoi(argv[1]);
To get expected behavior you should amend it to:
addr.sin6_port = htons(atoi(argv[1]));
answered Sep 21, 2021 at 20:27
luantkow
3,02923 silver badges15 bronze badges
Sign up to request clarification or add additional context in comments.
1 Comment
suresh
Thank you very much.
lang-c