From 99693bee5f2762f84b78ed90740753cdec40f394 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Mon, 27 May 2024 13:28:28 +0300 Subject: [PATCH] net: socket: Change the protocol field for AF_PACKET sockets In order to be compatible with Linux AF_PACKET socket calls, the protocol field needs to be in network byte order. So for example, if user wants to receive all packets, then the protocol field needs to be set as "htons(ETH_P_ALL)". See Linux manual page at https://www.man7.org/linux/man-pages/man7/packet.7.html for details. Signed-off-by: Jukka Rissanen --- doc/releases/migration-guide-3.7.rst | 5 +++++ samples/net/dsa/src/main.c | 2 +- samples/net/sockets/packet/src/packet.c | 2 +- samples/net/sockets/txtime/src/main.c | 2 +- subsys/net/lib/sockets/sockets_packet.c | 9 +++++++++ tests/net/ieee802154/l2/src/ieee802154_test.c | 8 ++++---- tests/net/socket/af_packet/src/main.c | 18 +++++++++--------- .../socket/af_packet_ipproto_raw/src/main.c | 2 +- tests/net/socket/register/src/main.c | 8 +++++--- tests/net/socket/udp/src/main.c | 8 ++++---- 10 files changed, 40 insertions(+), 24 deletions(-) diff --git a/doc/releases/migration-guide-3.7.rst b/doc/releases/migration-guide-3.7.rst index a9f6515161c..079c3645bf5 100644 --- a/doc/releases/migration-guide-3.7.rst +++ b/doc/releases/migration-guide-3.7.rst @@ -534,6 +534,11 @@ Networking :kconfig:option:`CONFIG_POSIX_MAX_FDS` are high enough. Unfortunately no exact values for these can be given as it depends on application needs and usage. (:github:`72834`) +* The packet socket (type ``AF_PACKET``) protocol field in ``socket`` API call has changed. + The protocol field should be in network byte order so that we are compatible with Linux + socket calls. Linux expects the protocol field to be ``htons(ETH_P_ALL)`` if it is desired + to receive all the network packets. See details in + https://www.man7.org/linux/man-pages/man7/packet.7.html documentation. (:github:`73338`) Other Subsystems **************** diff --git a/samples/net/dsa/src/main.c b/samples/net/dsa/src/main.c index 4bd2b36d229..a7c0e14dd2c 100644 --- a/samples/net/dsa/src/main.c +++ b/samples/net/dsa/src/main.c @@ -71,7 +71,7 @@ int start_slave_port_packet_socket(struct net_if *iface, struct sockaddr_ll dst; int ret; - pd->sock = socket(AF_PACKET, SOCK_RAW, ETH_P_ALL); + pd->sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); if (pd->sock < 0) { LOG_ERR("Failed to create RAW socket : %d", errno); return -errno; diff --git a/samples/net/sockets/packet/src/packet.c b/samples/net/sockets/packet/src/packet.c index 428a22a907d..ec6e428c325 100644 --- a/samples/net/sockets/packet/src/packet.c +++ b/samples/net/sockets/packet/src/packet.c @@ -86,7 +86,7 @@ static int start_socket(int *sock) *sock = socket(AF_PACKET, IS_ENABLED(CONFIG_NET_SAMPLE_ENABLE_PACKET_DGRAM) ? SOCK_DGRAM : SOCK_RAW, - ETH_P_ALL); + htons(ETH_P_ALL)); if (*sock < 0) { LOG_ERR("Failed to create %s socket : %d", IS_ENABLED(CONFIG_NET_SAMPLE_ENABLE_PACKET_DGRAM) ? diff --git a/samples/net/sockets/txtime/src/main.c b/samples/net/sockets/txtime/src/main.c index 481312d1afe..2bd41df40ac 100644 --- a/samples/net/sockets/txtime/src/main.c +++ b/samples/net/sockets/txtime/src/main.c @@ -273,7 +273,7 @@ static int create_socket(struct net_if *iface, struct sockaddr *peer) if (IS_ENABLED(CONFIG_NET_SAMPLE_PACKET_SOCKET)) { struct sockaddr_ll *addr; - sock = socket(AF_PACKET, SOCK_RAW, ETH_P_ALL); + sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); if (sock < 0) { LOG_ERR("Cannot create %s socket (%d)", "packet", -errno); diff --git a/subsys/net/lib/sockets/sockets_packet.c b/subsys/net/lib/sockets/sockets_packet.c index ec8e77c43ad..4fb75ece18c 100644 --- a/subsys/net/lib/sockets/sockets_packet.c +++ b/subsys/net/lib/sockets/sockets_packet.c @@ -55,6 +55,14 @@ static int zpacket_socket(int family, int type, int proto) if (type == SOCK_RAW) { proto = IPPROTO_RAW; } + } else { + /* For example in Linux, the protocol parameter can be given + * as htons(ETH_P_ALL) to receive all the network packets. + * So convert the proto field back to host byte order so that + * we do not need to change the protocol field handling in + * other part of the network stack. + */ + proto = ntohs(proto); } ret = net_context_get(family, type, proto, &ctx); @@ -480,6 +488,7 @@ static bool packet_is_supported(int family, int type, int proto) { switch (type) { case SOCK_RAW: + proto = ntohs(proto); return proto == ETH_P_ALL || proto == ETH_P_ECAT || proto == ETH_P_IEEE802154 diff --git a/tests/net/ieee802154/l2/src/ieee802154_test.c b/tests/net/ieee802154/l2/src/ieee802154_test.c index c3163957673..f984e529db5 100644 --- a/tests/net/ieee802154/l2/src/ieee802154_test.c +++ b/tests/net/ieee802154/l2/src/ieee802154_test.c @@ -405,7 +405,7 @@ static int set_up_recv_socket(enum net_sock_type socket_type) }; int fd; - fd = zsock_socket(AF_PACKET, socket_type, ETH_P_IEEE802154); + fd = zsock_socket(AF_PACKET, socket_type, htons(ETH_P_IEEE802154)); if (fd < 0) { NET_ERR("*** Failed to create recv socket : %d", errno); return fd; @@ -697,7 +697,7 @@ static bool test_dgram_packet_sending(void *dst_sll, uint8_t dst_sll_halen, uint } NET_INFO("- Sending DGRAM packet via AF_PACKET socket"); - fd = zsock_socket(AF_PACKET, SOCK_DGRAM, ETH_P_IEEE802154); + fd = zsock_socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_IEEE802154)); if (fd < 0) { NET_ERR("*** Failed to create DGRAM socket : %d", errno); goto reset_security; @@ -924,7 +924,7 @@ static bool test_raw_packet_sending(void) NET_INFO("- Sending RAW packet via AF_PACKET socket"); - fd = zsock_socket(AF_PACKET, SOCK_RAW, ETH_P_IEEE802154); + fd = zsock_socket(AF_PACKET, SOCK_RAW, htons(ETH_P_IEEE802154)); if (fd < 0) { NET_ERR("*** Failed to create RAW socket : %d", errno); goto out; @@ -1108,7 +1108,7 @@ static bool test_recv_and_send_ack_reply(struct ieee802154_pkt_test *t) NET_INFO("- Sending ACK reply to a data packet"); - fd = zsock_socket(AF_PACKET, SOCK_DGRAM, ETH_P_IEEE802154); + fd = zsock_socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_IEEE802154)); if (fd < 0) { NET_ERR("*** Failed to create DGRAM socket : %d", errno); goto out; diff --git a/tests/net/socket/af_packet/src/main.c b/tests/net/socket/af_packet/src/main.c index e82af239e26..4560850b0db 100644 --- a/tests/net/socket/af_packet/src/main.c +++ b/tests/net/socket/af_packet/src/main.c @@ -201,10 +201,10 @@ static void __test_packet_sockets(int *sock1, int *sock2) zassert_not_null(ud.first, "1st Ethernet interface not found"); zassert_not_null(ud.second, "2nd Ethernet interface not found"); - *sock1 = setup_socket(ud.first, SOCK_RAW, ETH_P_ALL); + *sock1 = setup_socket(ud.first, SOCK_RAW, htons(ETH_P_ALL)); zassert_true(*sock1 >= 0, "Cannot create 1st socket (%d)", *sock1); - *sock2 = setup_socket(ud.second, SOCK_RAW, ETH_P_ALL); + *sock2 = setup_socket(ud.second, SOCK_RAW, htons(ETH_P_ALL)); zassert_true(*sock2 >= 0, "Cannot create 2nd socket (%d)", *sock2); ret = bind_socket(*sock1, ud.first); @@ -311,10 +311,10 @@ ZTEST(socket_packet, test_packet_sockets_dgram) zassert_not_null(ud.first, "1st Ethernet interface not found"); zassert_not_null(ud.second, "2nd Ethernet interface not found"); - sock1 = setup_socket(ud.first, SOCK_DGRAM, ETH_P_TSN); + sock1 = setup_socket(ud.first, SOCK_DGRAM, htons(ETH_P_TSN)); zassert_true(sock1 >= 0, "Cannot create 1st socket (%d)", sock1); - sock2 = setup_socket(ud.second, SOCK_DGRAM, ETH_P_TSN); + sock2 = setup_socket(ud.second, SOCK_DGRAM, htons(ETH_P_TSN)); zassert_true(sock2 >= 0, "Cannot create 2nd socket (%d)", sock2); ret = bind_socket(sock1, ud.first); @@ -421,10 +421,10 @@ ZTEST(socket_packet, test_raw_and_dgram_socket_exchange) zassert_not_null(ud.first, "1st Ethernet interface not found"); zassert_not_null(ud.second, "2nd Ethernet interface not found"); - sock1 = setup_socket(ud.first, SOCK_DGRAM, ETH_P_ALL); + sock1 = setup_socket(ud.first, SOCK_DGRAM, htons(ETH_P_ALL)); zassert_true(sock1 >= 0, "Cannot create 1st socket (%d)", sock1); - sock2 = setup_socket(ud.second, SOCK_RAW, ETH_P_ALL); + sock2 = setup_socket(ud.second, SOCK_RAW, htons(ETH_P_ALL)); zassert_true(sock2 >= 0, "Cannot create 2nd socket (%d)", sock2); ret = bind_socket(sock1, ud.first); @@ -520,13 +520,13 @@ ZTEST(socket_packet, test_raw_and_dgram_socket_recv) zassert_not_null(ud.first, "1st Ethernet interface not found"); zassert_not_null(ud.second, "2nd Ethernet interface not found"); - sock1 = setup_socket(ud.first, SOCK_DGRAM, ETH_P_ALL); + sock1 = setup_socket(ud.first, SOCK_DGRAM, htons(ETH_P_ALL)); zassert_true(sock1 >= 0, "Cannot create 1st socket (%d)", sock1); - sock2 = setup_socket(ud.second, SOCK_RAW, ETH_P_ALL); + sock2 = setup_socket(ud.second, SOCK_RAW, htons(ETH_P_ALL)); zassert_true(sock2 >= 0, "Cannot create 2nd socket (%d)", sock2); - sock3 = setup_socket(ud.second, SOCK_RAW, ETH_P_ALL); + sock3 = setup_socket(ud.second, SOCK_RAW, htons(ETH_P_ALL)); zassert_true(sock3 >= 0, "Cannot create 2nd socket (%d)", sock3); ret = bind_socket(sock1, ud.first); diff --git a/tests/net/socket/af_packet_ipproto_raw/src/main.c b/tests/net/socket/af_packet_ipproto_raw/src/main.c index 9eace58bf13..4eb28edb70f 100644 --- a/tests/net/socket/af_packet_ipproto_raw/src/main.c +++ b/tests/net/socket/af_packet_ipproto_raw/src/main.c @@ -120,7 +120,7 @@ ZTEST(net_sckt_packet_raw_ip, test_sckt_raw_packet_raw_ip) char receive_buffer[128]; int sock; - sock = zsock_socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW); + sock = zsock_socket(AF_PACKET, SOCK_RAW, htons(IPPROTO_RAW)); zassert_true(sock >= 0, "Could not create a socket"); dst.sll_ifindex = net_if_get_by_iface(iface); diff --git a/tests/net/socket/register/src/main.c b/tests/net/socket/register/src/main.c index 2bc8d515bc1..43eec0e8845 100644 --- a/tests/net/socket/register/src/main.c +++ b/tests/net/socket/register/src/main.c @@ -103,7 +103,7 @@ static const struct test_result { /* 10 */ .test_case.family = AF_PACKET, .test_case.type = SOCK_RAW, - .test_case.proto = ETH_P_ALL, + .test_case.proto = htons(ETH_P_ALL), .result = 0, }, { @@ -147,14 +147,14 @@ static const struct test_result { /* 16 */ .test_case.family = AF_PACKET, .test_case.type = SOCK_RAW, - .test_case.proto = ETH_P_IEEE802154, + .test_case.proto = htons(ETH_P_IEEE802154), .result = 0, }, { /* 17 */ .test_case.family = AF_PACKET, .test_case.type = SOCK_DGRAM, - .test_case.proto = ETH_P_IEEE802154, + .test_case.proto = htons(ETH_P_IEEE802154), .result = 0, }, }; @@ -201,6 +201,8 @@ static bool is_tls(int family, int type, int proto) static bool is_packet(int family, int type, int proto) { + proto = ntohs(proto); + if (((type == SOCK_RAW) && (proto == ETH_P_ALL || proto == ETH_P_IEEE802154)) || ((type == SOCK_DGRAM) && (proto > 0))) { return true; diff --git a/tests/net/socket/udp/src/main.c b/tests/net/socket/udp/src/main.c index 3d27e4121a5..2f345df8b17 100644 --- a/tests/net/socket/udp/src/main.c +++ b/tests/net/socket/udp/src/main.c @@ -2155,7 +2155,7 @@ ZTEST(net_socket_udp, test_31_v4_ttl) prepare_sock_udp_v4(MY_IPV4_ADDR, CLIENT_PORT, &client_sock, &client_addr); prepare_sock_udp_v4(MY_IPV4_ADDR, SERVER_PORT, &server_sock, &server_addr); - packet_sock = zsock_socket(AF_PACKET, SOCK_RAW, ETH_P_ALL); + packet_sock = zsock_socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); zassert_true(packet_sock >= 0, "Cannot create packet socket (%d)", -errno); ret = bind_socket(packet_sock, lo0); @@ -2204,7 +2204,7 @@ ZTEST(net_socket_udp, test_32_v4_mcast_ttl) prepare_sock_udp_v4(MY_IPV4_ADDR, CLIENT_PORT, &client_sock, &client_addr); prepare_sock_udp_v4(MY_IPV4_ADDR, SERVER_PORT, &server_sock, &server_addr); - packet_sock = zsock_socket(AF_PACKET, SOCK_RAW, ETH_P_ALL); + packet_sock = zsock_socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); zassert_true(packet_sock >= 0, "Cannot create packet socket (%d)", -errno); ret = bind_socket(packet_sock, lo0); @@ -2254,7 +2254,7 @@ ZTEST(net_socket_udp, test_33_v6_mcast_hops) prepare_sock_udp_v6(MY_IPV6_ADDR, CLIENT_PORT, &client_sock, &client_addr); prepare_sock_udp_v6(MY_IPV6_ADDR, SERVER_PORT, &server_sock, &server_addr); - packet_sock = zsock_socket(AF_PACKET, SOCK_RAW, ETH_P_ALL); + packet_sock = zsock_socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); zassert_true(packet_sock >= 0, "Cannot create packet socket (%d)", -errno); ret = bind_socket(packet_sock, lo0); @@ -2320,7 +2320,7 @@ ZTEST(net_socket_udp, test_34_v6_hops) prepare_sock_udp_v6(MY_IPV6_ADDR, CLIENT_PORT, &client_sock, &client_addr); prepare_sock_udp_v6(MY_IPV6_ADDR, SERVER_PORT, &server_sock, &server_addr); - packet_sock = zsock_socket(AF_PACKET, SOCK_RAW, ETH_P_ALL); + packet_sock = zsock_socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); zassert_true(packet_sock >= 0, "Cannot create packet socket (%d)", -errno); ret = bind_socket(packet_sock, lo0);