FreeBSD Bugzilla – Attachment 253704 Details for
Bug 281391
IPv6 multicast sent to wrong MAC address
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
test case program
hive.cc (text/plain), 4.88 KB, created by
antonfb
on 2024-09-20 21:42:02 UTC
(
hide
)
Description:
test case program
Filename:
MIME Type:
Creator:
antonfb
Created:
2024-09-20 21:42:02 UTC
Size:
4.88 KB
patch
obsolete
>#include <iostream> >#include <cstring> > >#include <sys/types.h> >#include <sys/time.h> >#include <sys/socket.h> >#include <sys/select.h> >#include <netinet/in.h> >#include <arpa/inet.h> >#include <netdb.h> > >#if defined(SOCKLEN_T_DECLARED) || defined(_SOCKLEN_T_DECLARED) >#define HAVE_SOCKLEN >#endif > >using namespace std; > >/* > * Hive test FreeBSD multicast > * Copyright 2024 Jeffrey Anton > * > * MIT 2 part license > * > * Usage: > * hive (ipv4 usage) > * hive foo (ipv6 usage) > * > * recommend running via truss for debugging > * > * NOTE: ipv6 address must be changed in the code for your ipv6 /64 network > * > * announcement rules > * On Startup > * At least every five minutes (i.e. five minutes - random seconds) > * when a startup annoucement is seen (i.e. random seconds after seen) > * > * announcement format > * > * format version 1 > * timestamp > * sequence > * digest version > * digest > * message > */ >class Hive { >public: > Hive(bool = false); > ~Hive(); > void Run(); > void SetStatus(const char *); >private: > int sock; > union { > struct sockaddr sa; > struct sockaddr_in sin; > struct sockaddr_in6 sin6; > }; > struct timeval tv; > unsigned long seq; > bool ipv6; > char *status; > > void Init(); > void SendUp(); > void RecvUp(); > void Loop(); >}; > >Hive::Hive(bool i) > : status(NULL), seq(0), ipv6(i) >{ > Init(); >} > >Hive::~Hive() >{ > delete [] status; >} > >void >Hive::SetStatus(const char *s) >{ > delete [] status; > int l = strlen(s); > status = new char[l+1]; > strcpy(status, s); >} > >void >Hive::Run() >{ > SendUp(); > Loop(); >} > >void >Hive::Init() >{ > if (ipv6) { > // make socket > sock = socket(PF_INET6, SOCK_DGRAM, 0); > >#ifdef HAVE_SOCKLEN > sin6.sin6_len = sizeof sin6; >#endif > sin6.sin6_family = AF_INET6; > memset(sin6.sin6_addr.s6_addr, '\0', sizeof sin6.sin6_addr); > sin6.sin6_port = htons(3412); > sin6.sin6_flowinfo = 0; > sin6.sin6_scope_id = 0; > > ::bind(sock, &sa, sizeof sin6); > > int one = 1; > setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &one, sizeof one); > one = 0; > setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &one, sizeof one); > > // NOTE: CHANGE THIS FOR YOUR IPV6 MULTICAST ADDRESS > > struct ipv6_mreq mreq; > mreq.ipv6mr_interface = 0; > uint8_t *a = mreq.ipv6mr_multiaddr.s6_addr; > *a++ = 0xff; > *a++ = 0x34; > *a++ = 0; > *a++ = 64; > // /64 address starts here > *a++ = 0x20; > *a++ = 0x01; > *a++ = 0x05; > *a++ = 0xa8; > *a++ = 0x60; > *a++ = 0xc8; > *a++ = 0x1e; > *a++ = 0x00; > // /64 address ends above > // multicast qualification starts here is :0201 > *a++ = 0; > *a++ = 2; > *a++ = 0; > *a++ = 1; > > sin6.sin6_addr = mreq.ipv6mr_multiaddr; > if (setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, > &mreq, sizeof mreq)) { > perror("ipv6 join group fail"); > } > } else { > // make socket > sock = socket(PF_INET, SOCK_DGRAM, 0); > >#ifdef HAVE_SOCKLEN > sin.sin_len = sizeof sin; >#endif > sin.sin_family = AF_INET; > sin.sin_addr.s_addr = htonl(INADDR_ANY); > sin.sin_port = htons(3412); > > ::bind(sock, &sa, sizeof sin); > > int one = 1; > setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, &one, sizeof one); > one = 0; > setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, &one, sizeof one); > > struct ip_mreq mreq; > mreq.imr_interface.s_addr = htonl(INADDR_ANY); > inet_aton("239.1.0.1", &mreq.imr_multiaddr); > > sin.sin_addr = mreq.imr_multiaddr; > setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof mreq); > } >} > >void >Hive::SendUp() >{ > struct msghdr msg; > struct iovec iov; > > iov.iov_base = status; > iov.iov_len = strlen(status); > msg.msg_name = &sa; > msg.msg_namelen = ipv6 ? sizeof(sockaddr_in6) : sizeof(sockaddr_in); > msg.msg_iov = &iov; > msg.msg_iovlen = 1; > msg.msg_control = NULL; > msg.msg_controllen = 0; > msg.msg_flags = 0; > > sendmsg(sock, &msg, 0); > > gettimeofday(&tv, NULL); > tv.tv_sec += 5; >} > >void >Hive::RecvUp() >{ > char buf[200]; > char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; > int r; > socklen_t rs; > > if (ipv6) { > struct sockaddr_in6 rsin; > > rs = sizeof rsin; > r = recvfrom(sock, buf, sizeof buf, 0, (struct sockaddr *)&rsin, &rs); > getnameinfo((struct sockaddr *)&rsin, sizeof rsin, hbuf, sizeof hbuf, > sbuf, sizeof sbuf, NI_NUMERICHOST|NI_NUMERICSERV); > } else { > struct sockaddr_in rsin; > > rs = sizeof rsin; > r = recvfrom(sock, buf, sizeof buf, 0, (struct sockaddr *)&rsin, &rs); > getnameinfo((struct sockaddr *)&rsin, sizeof rsin, hbuf, sizeof hbuf, > sbuf, sizeof sbuf, NI_NUMERICHOST|NI_NUMERICSERV); > } > if (r) > buf[r] = '\0'; > cout << hbuf << ' ' << sbuf << ' ' << buf << endl; >} > >void >Hive::Loop() >{ > int s = 0; > fd_set rdset; > struct timeval ntv; > > while (s >= 0) { > gettimeofday(&ntv, NULL); > if (timercmp(&tv, &ntv, <=)) > SendUp(); > timersub(&tv, &ntv, &ntv); > FD_ZERO(&rdset); > FD_SET(sock, &rdset); > s = select(sock+1, &rdset, NULL, NULL, &ntv); > if (s == 1) > RecvUp(); > if (s == 0) > SendUp(); > } >} > >int >main(int ac, char **) >{ > Hive h(ac > 1); > > h.SetStatus("This is a test"); > h.Run(); > > return 0; >}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 281391
: 253704