drivers: nsos: support for AF_PACKET

Handle AF_PACKET family.

Signed-off-by: Noemie Gillet <ngillet@sequans.com>
This commit is contained in:
Noemie Gillet 2024-10-29 13:35:10 +01:00 committed by Anas Nashif
parent 10bb61ee7d
commit 2253a26c10
4 changed files with 98 additions and 0 deletions

View file

@ -15,18 +15,21 @@
#define NSOS_MID_PF_INET 1 /**< IP protocol family version 4. */
#define NSOS_MID_PF_INET6 2 /**< IP protocol family version 6. */
#define NSOS_MID_PF_UNIX 6 /**< Unix protocol. */
#define NSOS_MID_PF_PACKET 3 /**< Packet family. */
/* Address families. */
#define NSOS_MID_AF_UNSPEC NSOS_MID_PF_UNSPEC /**< Unspecified address family. */
#define NSOS_MID_AF_INET NSOS_MID_PF_INET /**< IP protocol family version 4. */
#define NSOS_MID_AF_INET6 NSOS_MID_PF_INET6 /**< IP protocol family version 6. */
#define NSOS_MID_AF_UNIX NSOS_MID_PF_UNIX /**< Unix protocol. */
#define NSOS_MID_AF_PACKET NSOS_MID_PF_PACKET /**< Packet family. */
/** Protocol numbers from IANA/BSD */
enum nsos_mid_net_ip_protocol {
NSOS_MID_IPPROTO_IP = 0, /**< IP protocol (pseudo-val for setsockopt() */
NSOS_MID_IPPROTO_ICMP = 1, /**< ICMP protocol */
NSOS_MID_IPPROTO_IGMP = 2, /**< IGMP protocol */
NSOS_MID_IPPROTO_ETH_P_ALL = 3, /**< Every packet. from linux if_ether.h */
NSOS_MID_IPPROTO_IPIP = 4, /**< IPIP tunnels */
NSOS_MID_IPPROTO_TCP = 6, /**< TCP protocol */
NSOS_MID_IPPROTO_UDP = 17, /**< UDP protocol */
@ -71,12 +74,22 @@ struct nsos_mid_sockaddr_un {
char sun_path[UNIX_PATH_MAX]; /* pathname */
};
struct nsos_mid_sockaddr_ll {
sa_family_t sll_family; /**< Always AF_PACKET */
uint16_t sll_protocol; /**< Physical-layer protocol */
int sll_ifindex; /**< Interface number */
uint16_t sll_hatype; /**< ARP hardware type */
uint8_t sll_pkttype; /**< Packet type */
uint8_t sll_halen; /**< Length of address */
uint8_t sll_addr[8]; /**< Physical-layer address, big endian */
};
struct nsos_mid_sockaddr_storage {
union {
struct nsos_mid_sockaddr_in sockaddr_in;
struct nsos_mid_sockaddr_in6 sockaddr_in6;
struct nsos_mid_sockaddr_un sockaddr_un;
struct nsos_mid_sockaddr_ll sockaddr_ll;
};
};

View file

@ -17,6 +17,8 @@
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <netinet/if_ether.h>
#include <netpacket/packet.h>
#include <poll.h>
#include <stdlib.h>
#include <string.h>
@ -72,6 +74,9 @@ static int socket_family_from_nsos_mid(int family_mid, int *family)
case NSOS_MID_AF_UNIX:
*family = AF_UNIX;
break;
case NSOS_MID_AF_PACKET:
*family = AF_PACKET;
break;
default:
nsi_print_warning("%s: socket family %d not supported\n", __func__, family_mid);
return -NSOS_MID_EAFNOSUPPORT;
@ -95,6 +100,9 @@ static int socket_family_to_nsos_mid(int family, int *family_mid)
case AF_UNIX:
*family_mid = NSOS_MID_AF_UNIX;
break;
case AF_PACKET:
*family_mid = NSOS_MID_AF_PACKET;
break;
default:
nsi_print_warning("%s: socket family %d not supported\n", __func__, family);
return -NSOS_MID_EAFNOSUPPORT;
@ -130,6 +138,9 @@ static int socket_proto_from_nsos_mid(int proto_mid, int *proto)
case NSOS_MID_IPPROTO_RAW:
*proto = IPPROTO_RAW;
break;
case NSOS_MID_IPPROTO_ETH_P_ALL:
*proto = htons(ETH_P_ALL);
break;
default:
nsi_print_warning("%s: socket protocol %d not supported\n", __func__, proto_mid);
return -NSOS_MID_EPROTONOSUPPORT;
@ -165,6 +176,9 @@ static int socket_proto_to_nsos_mid(int proto, int *proto_mid)
case IPPROTO_RAW:
*proto_mid = NSOS_MID_IPPROTO_RAW;
break;
case ETH_P_ALL:
*proto_mid = htons(NSOS_MID_IPPROTO_ETH_P_ALL);
break;
default:
nsi_print_warning("%s: socket protocol %d not supported\n", __func__, proto);
return -NSOS_MID_EPROTONOSUPPORT;
@ -316,6 +330,24 @@ static int sockaddr_from_nsos_mid(struct sockaddr **addr, socklen_t *addrlen,
return 0;
}
case NSOS_MID_AF_PACKET: {
const struct nsos_mid_sockaddr_ll *addr_ll_mid =
(const struct nsos_mid_sockaddr_ll *)addr_mid;
struct sockaddr_ll *addr_ll = (struct sockaddr_ll *)*addr;
addr_ll->sll_family = NSOS_MID_AF_PACKET;
addr_ll->sll_protocol = addr_ll_mid->sll_protocol;
addr_ll->sll_ifindex = addr_ll_mid->sll_ifindex;
addr_ll->sll_hatype = addr_ll_mid->sll_hatype;
addr_ll->sll_pkttype = addr_ll_mid->sll_pkttype;
addr_ll->sll_halen = addr_ll_mid->sll_halen;
memcpy(addr_ll->sll_addr, addr_ll_mid->sll_addr,
sizeof(addr_ll->sll_addr));
*addrlen = sizeof(*addr_ll);
return 0;
}
}
return -NSOS_MID_EINVAL;
@ -384,6 +416,23 @@ static int sockaddr_to_nsos_mid(const struct sockaddr *addr, socklen_t addrlen,
return 0;
}
case AF_PACKET: {
struct nsos_mid_sockaddr_ll *addr_ll_mid =
(struct nsos_mid_sockaddr_ll *)addr_mid;
const struct sockaddr_ll *addr_ll = (const struct sockaddr_ll *)addr;
if (addr_ll_mid) {
addr_ll_mid->sll_family = NSOS_MID_AF_PACKET;
addr_ll_mid->sll_protocol = addr_ll->sll_protocol;
addr_ll_mid->sll_ifindex = addr_ll->sll_ifindex;
}
if (addrlen_mid) {
*addrlen_mid = sizeof(*addr_ll);
}
return 0;
}
}
nsi_print_warning("%s: socket family %d not supported\n", __func__, addr->sa_family);

View file

@ -75,6 +75,9 @@ static int socket_family_to_nsos_mid(int family, int *family_mid)
case AF_UNIX:
*family_mid = NSOS_MID_AF_UNIX;
break;
case AF_PACKET:
*family_mid = NSOS_MID_AF_PACKET;
break;
default:
return -NSOS_MID_EAFNOSUPPORT;
}
@ -109,6 +112,9 @@ static int socket_proto_to_nsos_mid(int proto, int *proto_mid)
case IPPROTO_RAW:
*proto_mid = NSOS_MID_IPPROTO_RAW;
break;
case htons(IPPROTO_ETH_P_ALL):
*proto_mid = NSOS_MID_IPPROTO_ETH_P_ALL;
break;
default:
return -NSOS_MID_EPROTONOSUPPORT;
}
@ -469,6 +475,29 @@ static int sockaddr_to_nsos_mid(const struct sockaddr *addr, socklen_t addrlen,
return 0;
}
case AF_PACKET: {
const struct sockaddr_ll *addr_ll =
(const struct sockaddr_ll *)addr;
struct nsos_mid_sockaddr_ll *addr_ll_mid =
(struct nsos_mid_sockaddr_ll *)*addr_mid;
if (addrlen < sizeof(*addr_ll)) {
return -NSOS_MID_EINVAL;
}
addr_ll_mid->sll_family = NSOS_MID_AF_UNIX;
addr_ll_mid->sll_protocol = addr_ll->sll_protocol;
addr_ll_mid->sll_ifindex = addr_ll->sll_ifindex;
addr_ll_mid->sll_hatype = addr_ll->sll_hatype;
addr_ll_mid->sll_pkttype = addr_ll->sll_pkttype;
addr_ll_mid->sll_halen = addr_ll->sll_halen;
memcpy(addr_ll_mid->sll_addr, addr_ll->sll_addr,
sizeof(addr_ll->sll_addr));
*addrlen_mid = sizeof(*addr_ll_mid);
return 0;
}
}
return -NSOS_MID_EINVAL;
@ -948,6 +977,9 @@ static int socket_proto_from_nsos_mid(int proto_mid, int *proto)
case NSOS_MID_IPPROTO_RAW:
*proto = IPPROTO_RAW;
break;
case NSOS_MID_IPPROTO_ETH_P_ALL:
*proto = htons(IPPROTO_ETH_P_ALL);
break;
default:
return -NSOS_MID_EPROTONOSUPPORT;
}
@ -970,6 +1002,9 @@ static int socket_family_from_nsos_mid(int family_mid, int *family)
case NSOS_MID_AF_UNIX:
*family = AF_UNIX;
break;
case NSOS_MID_AF_PACKET:
*family = AF_PACKET;
break;
default:
return -NSOS_MID_EAFNOSUPPORT;
}

View file

@ -65,6 +65,7 @@ enum net_ip_protocol {
IPPROTO_IP = 0, /**< IP protocol (pseudo-val for setsockopt() */
IPPROTO_ICMP = 1, /**< ICMP protocol */
IPPROTO_IGMP = 2, /**< IGMP protocol */
IPPROTO_ETH_P_ALL = 3, /**< Every packet. from linux if_ether.h */
IPPROTO_IPIP = 4, /**< IPIP tunnels */
IPPROTO_TCP = 6, /**< TCP protocol */
IPPROTO_UDP = 17, /**< UDP protocol */