Commit dff20072 authored by Danilo Sabato's avatar Danilo Sabato Committed by Alessandro Rubini

arch-bare-x86-64: fix multicast for raw-ethernet (copy from gnu-linux)

parent 73c06b94
......@@ -74,6 +74,98 @@ struct bare_sockaddr_ll {
#define SIOCGIFINDEX 0x8933
#define SIOCGIFHWADDR 0x8927
#define SO_TIMESTAMP 29
#define SOL_SOCKET 1
/* from uapi/linux/if_ether.h */
#define ETH_ALEN 6 /* Octets in one ethernet addr */
/* start copy from linux/socket.h */
/* Setsockoptions(2) level. Thanks to BSD these must match IPPROTO_xxx */
#define SOL_IP 0
/* #define SOL_ICMP 1 No-no-no! Due to Linux :-) we cannot use
SOL_ICMP=1 */
#define SOL_TCP 6
#define SOL_UDP 17
#define SOL_IPV6 41
#define SOL_ICMPV6 58
#define SOL_SCTP 132
#define SOL_UDPLITE 136 /* UDP-Lite (RFC 3828) */
#define SOL_RAW 255
#define SOL_IPX 256
#define SOL_AX25 257
#define SOL_ATALK 258
#define SOL_NETROM 259
#define SOL_ROSE 260
#define SOL_DECNET 261
#define SOL_X25 262
#define SOL_PACKET 263
#define SOL_ATM 264 /* ATM layer (cell level) */
#define SOL_AAL 265 /* ATM Adaption Layer (packet level) */
#define SOL_IRDA 266
#define SOL_NETBEUI 267
#define SOL_LLC 268
#define SOL_DCCP 269
#define SOL_NETLINK 270
#define SOL_TIPC 271
#define SOL_RXRPC 272
#define SOL_PPPOL2TP 273
#define SOL_BLUETOOTH 274
#define SOL_PNPIPE 275
#define SOL_RDS 276
#define SOL_IUCV 277
#define SOL_CAIF 278
#define SOL_ALG 279
/* end copy from linux/socket.h */
/* start copy from uapi/linux/if_packet.h */
struct bare_packet_mreq {
int mr_ifindex;
unsigned short mr_type;
unsigned short mr_alen;
unsigned char mr_address[8];
};
#define PACKET_MR_MULTICAST 0
#define PACKET_MR_PROMISC 1
#define PACKET_MR_ALLMULTI 2
#define PACKET_MR_UNICAST 3
/* Packet types */
#define PACKET_HOST 0 /* To us */
#define PACKET_BROADCAST 1 /* To all */
#define PACKET_MULTICAST 2 /* To group */
#define PACKET_OTHERHOST 3 /* To someone else */
#define PACKET_OUTGOING 4 /* Outgoing of any type */
/* These ones are invisible by user level */
#define PACKET_LOOPBACK 5 /* MC/BRD frame looped back */
#define PACKET_FASTROUTE 6 /* Fastrouted frame */
/* Packet socket options */
#define PACKET_ADD_MEMBERSHIP 1
#define PACKET_DROP_MEMBERSHIP 2
#define PACKET_RECV_OUTPUT 3
/* Value 4 is still used by obsolete turbo-packet. */
#define PACKET_RX_RING 5
#define PACKET_STATISTICS 6
#define PACKET_COPY_THRESH 7
#define PACKET_AUXDATA 8
#define PACKET_ORIGDEV 9
#define PACKET_VERSION 10
#define PACKET_HDRLEN 11
#define PACKET_RESERVE 12
#define PACKET_TX_RING 13
#define PACKET_LOSS 14
#define PACKET_VNET_HDR 15
#define PACKET_TX_TIMESTAMP 16
#define PACKET_TIMESTAMP 17
#define PACKET_FANOUT 18
/* end copy from linux/if_packet.h */
/* other network stuff, bah.... */
struct bare_ethhdr {
unsigned char h_dest[6];
......
......@@ -60,48 +60,82 @@ int pp_send_packet(struct pp_instance *ppi, void *pkt, int len,
/* To open a channel we must bind to an interface and so on */
int bare_open_ch(struct pp_instance *ppi, char *ifname)
{
int sock, iindex;
int sock = -1;
int temp, iindex;
struct bare_ifreq ifr;
struct bare_sockaddr_ll addr;
struct bare_sockaddr_ll addr_ll;
struct bare_packet_mreq pmr;
/* open socket */
sock = sys_socket(PF_PACKET, SOCK_RAW, PP_ETHERTYPE);
if (sock < 0) {
pp_diag_error(ppi, bare_errno);
pp_diag_fatal(ppi, "socket()", "");
}
/* hw interface information */
memset(&ifr, 0, sizeof(ifr));
strcpy(ifr.ifr_ifrn.ifrn_name, ifname);
if (sys_ioctl(sock, SIOCGIFINDEX, &ifr) < 0) {
pp_diag_error(ppi, bare_errno);
pp_diag_fatal(ppi, "ioctl(GIFINDEX)", "");
}
iindex = ifr.ifr_ifru.index;
if (sys_ioctl(sock, SIOCGIFHWADDR, &ifr) < 0) {
pp_diag_error(ppi, bare_errno);
pp_diag_fatal(ppi, "ioctl(GIFHWADDR)", "");
}
memcpy(NP(ppi)->ch[PP_NP_GEN].addr,
ifr.ifr_ifru.ifru_hwaddr.sa_data, 6);
memcpy(NP(ppi)->ch[PP_NP_EVT].addr,
ifr.ifr_ifru.ifru_hwaddr.sa_data, 6);
/* bind and setsockopt */
memset(&addr, 0, sizeof(addr));
addr.sll_family = PF_PACKET;
addr.sll_protocol = htons(PP_ETHERTYPE);
addr.sll_ifindex = iindex;
if (sys_bind(sock, (struct bare_sockaddr *)&addr, sizeof(addr)) < 0) {
pp_diag_error(ppi, bare_errno);
pp_diag_fatal(ppi, "bind", "");
if (OPTS(ppi)->ethernet_mode) {
/* open socket */
sock = sys_socket(PF_PACKET, SOCK_RAW, ETH_P_1588);
if (sock < 0) {
pp_diag_error(ppi, bare_errno);
pp_diag_fatal(ppi, "socket()", "");
sys_close(sock);
return -1;
}
/* hw interface information */
memset(&ifr, 0, sizeof(ifr));
strcpy(ifr.ifr_ifrn.ifrn_name, ifname);
if (sys_ioctl(sock, SIOCGIFINDEX, &ifr) < 0) {
pp_diag_error(ppi, bare_errno);
pp_diag_fatal(ppi, "ioctl(GIFINDEX)", "");
sys_close(sock);
return -1;
}
iindex = ifr.ifr_ifru.index;
if (sys_ioctl(sock, SIOCGIFHWADDR, &ifr) < 0) {
pp_diag_error(ppi, bare_errno);
pp_diag_fatal(ppi, "ioctl(GIFHWADDR)", "");
sys_close(sock);
return -1;
}
memcpy(NP(ppi)->ch[PP_NP_GEN].addr,
ifr.ifr_ifru.ifru_hwaddr.sa_data, 6);
memcpy(NP(ppi)->ch[PP_NP_EVT].addr,
ifr.ifr_ifru.ifru_hwaddr.sa_data, 6);
/* bind */
memset(&addr_ll, 0, sizeof(addr_ll));
addr_ll.sll_family = PF_PACKET;
addr_ll.sll_protocol = htons(ETH_P_1588);
addr_ll.sll_ifindex = iindex;
if (sys_bind(sock, (struct bare_sockaddr *)&addr_ll,
sizeof(addr_ll)) < 0) {
pp_diag_error(ppi, bare_errno);
pp_diag_fatal(ppi, "bind", "");
sys_close(sock);
return -1;
}
/* accept the multicast address for raw-ethernet ptp */
memset(&pmr, 0, sizeof(pmr));
pmr.mr_ifindex = iindex;
pmr.mr_type = PACKET_MR_MULTICAST;
pmr.mr_alen = ETH_ALEN;
memcpy(pmr.mr_address, PP_MCAST_MACADDRESS, ETH_ALEN);
sys_setsockopt(sock, SOL_PACKET, PACKET_ADD_MEMBERSHIP,
&pmr, sizeof(pmr)); /* lazily ignore errors */
/* also the PEER multicast address */
memcpy(pmr.mr_address, PP_PEER_MACADDRESS, ETH_ALEN);
sys_setsockopt(sock, SOL_PACKET, PACKET_ADD_MEMBERSHIP,
&pmr, sizeof(pmr)); /* lazily ignore errors */
NP(ppi)->ch[PP_NP_GEN].fd = sock;
NP(ppi)->ch[PP_NP_EVT].fd = sock;
/* make timestamps available through recvmsg() -- FIXME: hw? */
sys_setsockopt(sock, SOL_SOCKET, SO_TIMESTAMP,
&temp, sizeof(int));
return 0;
}
NP(ppi)->ch[PP_NP_GEN].fd = sock;
NP(ppi)->ch[PP_NP_EVT].fd = sock;
return 0;
return -1;
}
int bare_net_init(struct pp_instance *ppi)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment