extern int sock_add(char * ifacename,int ifaceid, char * addr, int port, int thisifaceonly, int reuse) { SOCKET s; struct sockaddr_in6 bindme; struct ipv6_mreq ipmreq; int hops=1; char packedAddr[16]; char multiAddr[16] = { 0xff,2, 0,0, 0,0, 0,0, 0,0, 0,0, 0,1, 0,2}; inet_pton6(addr,packedAddr); if ((s=socket(AF_INET6,SOCK_DGRAM, 0)) == INVALID_SOCKET) return -2; memset(&bindme, 0, sizeof(bindme)); bindme.sin6_family = AF_INET6; bindme.sin6_port = htons(port); if (IN6_IS_ADDR_LINKLOCAL((IN6_ADDR*)packedAddr)) bindme.sin6_scope_id = ifaceid; if (!IN6_IS_ADDR_MULTICAST((IN6_ADDR*)packedAddr)) { inet_pton6(addr, (char*)&bindme.sin6_addr); } // REUSEADDR must be before bind() in order to take effect if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char*)&hops, sizeof(hops))) { error_message_set(WSAGetLastError()); return LOWLEVEL_ERROR_REUSE_FAILED; } if (bind(s, (struct sockaddr*)&bindme, sizeof(bindme))) { error_message_set(WSAGetLastError()); return LOWLEVEL_ERROR_BIND_FAILED; } if (IN6_IS_ADDR_MULTICAST((IN6_ADDR*)packedAddr)) { /* multicast */ ipmreq.ipv6mr_interface=ifaceid; memcpy(&ipmreq.ipv6mr_multiaddr,packedAddr,16); if(setsockopt(s,IPPROTO_IPV6,IPV6_ADD_MEMBERSHIP,(char*)&ipmreq,sizeof(ipmreq))) { error_message_set(WSAGetLastError()); return LOWLEVEL_ERROR_MCAST_MEMBERSHIP; } if(setsockopt(s,IPPROTO_IPV6,IPV6_MULTICAST_HOPS,(char*)&hops,sizeof(hops))) { error_message_set(WSAGetLastError()); return LOWLEVEL_ERROR_MCAST_HOPS; } } return s; }
int sock_send(int fd, char * addr, char * buf, int buflen, int port,int iface) { ADDRINFO inforemote,*remote; char addrStr[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")+5]; char portStr[10]; int i; char packaddr[16]; char ifaceStr[10]; memset(addrStr, 0, sizeof(addrStr)); memset(portStr, 0, sizeof(portStr)); memset(packaddr, 0, sizeof(packaddr)); memset(ifaceStr, 0, sizeof(ifaceStr)); strcpy(addrStr,addr); itoa(port,portStr,10); itoa(iface,ifaceStr,10); inet_pton6(addrStr,packaddr); if(IN6_IS_ADDR_LINKLOCAL((struct in6_addr*)packaddr) ||IN6_IS_ADDR_SITELOCAL((struct in6_addr*)packaddr)) strcat(strcat(addrStr,"%"),ifaceStr); memset(&inforemote, 0, sizeof(inforemote)); inforemote.ai_flags=AI_NUMERICHOST; inforemote.ai_family=PF_INET6; inforemote.ai_socktype=SOCK_DGRAM; inforemote.ai_protocol=IPPROTO_IPV6; //inet_ntop6(addr,addrStr); if(getaddrinfo(addrStr,portStr,&inforemote,&remote)) return 0; i=sendto(fd,buf,buflen,0,remote->ai_addr,remote->ai_addrlen); freeaddrinfo(remote); if (i==SOCKET_ERROR) { error_message_set(WSAGetLastError()); return LOWLEVEL_ERROR_UNSPEC; } return LOWLEVEL_NO_ERROR; }