void test_IgnoreIPv6Fields(void) { #ifdef ISC_PLATFORM_WANTIPV6 const struct in6_addr address = { 0x20, 0x01, 0x0d, 0xb8, 0x85, 0xa3, 0x08, 0xd3, 0x13, 0x19, 0x8a, 0x2e, 0x03, 0x70, 0x73, 0x34 }; sockaddr_u input1, input2; input1.sa6.sin6_family = AF_INET6; input1.sa6.sin6_addr = address; input1.sa6.sin6_flowinfo = 30L; // This value differs from input2. SET_PORT(&input1, NTP_PORT); input2.sa6.sin6_family = AF_INET6; input2.sa6.sin6_addr = address; input2.sa6.sin6_flowinfo = 10L; // This value differs from input1. SET_PORT(&input2, NTP_PORT); TEST_ASSERT_EQUAL(sock_hash(&input1), sock_hash(&input2)); #else TEST_IGNORE_MESSAGE("IPV6 disabled in build, skipping."); #endif /* ISC_PLATFORM_HAVEIPV6 */ }
void test_IPv6Address(void) { /* IPv6 addresses are assumed to have 64-bit host- and 64-bit network parts. */ const struct in6_addr input_address = { 0x20, 0x01, 0x0d, 0xb8, 0x85, 0xa3, 0x08, 0xd3, 0x13, 0x19, 0x8a, 0x2e, 0x03, 0x70, 0x73, 0x34 }; // 2001:0db8:85a3:08d3:1319:8a2e:0370:7334 const struct in6_addr expected_address = { 0x20, 0x01, 0x0d, 0xb8, 0x85, 0xa3, 0x08, 0xd3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // 2001:0db8:85a3:08d3:0000:0000:0000:0000 sockaddr_u input; input.sa6.sin6_family = AF_INET6; input.sa6.sin6_addr = input_address; SET_PORT(&input, 3000); sockaddr_u expected; expected.sa6.sin6_family = AF_INET6; expected.sa6.sin6_addr = expected_address; SET_PORT(&expected, 3000); sockaddr_u* actual = netof(&input); TEST_ASSERT_TRUE(actual != NULL); TEST_ASSERT_TRUE(IsEqual(expected, *actual)); }
main(){ printf("size: %d bytes\n", strlen(sc)); SET_PORT(sc, 33333); SET_IP(sc, "127.0.0.1"); __asm__("call sc"); }
void test_IPv6AddressWithPort(void) { #ifdef ISC_PLATFORM_WANTIPV6 const struct in6_addr address = { 0x20, 0x01, 0x0d, 0xb8, 0x85, 0xa3, 0x08, 0xd3, 0x13, 0x19, 0x8a, 0x2e, 0x03, 0x70, 0x73, 0x34 }; const char *str = "[2001:0db8:85a3:08d3:1319:8a2e:0370:7334]:3000"; sockaddr_u actual; sockaddr_u expected; expected.sa6.sin6_family = AF_INET6; expected.sa6.sin6_addr = address; SET_PORT(&expected, 3000); TEST_ASSERT_TRUE(decodenetnum(str, &actual)); TEST_ASSERT_TRUE(IsEqual(expected, actual)); #else TEST_IGNORE_MESSAGE("IPV6 disabled in build, skipping."); #endif /* ISC_PLATFORM_HAVEIPV6 */ }
void test_IPv6AddressWithPort(void) { #ifdef ISC_PLATFORM_WANTIPV6 const struct in6_addr address = { 0x20, 0x01, 0x0d, 0xb8, 0x85, 0xa3, 0x08, 0xd3, 0x13, 0x19, 0x8a, 0x2e, 0x03, 0x70, 0x73, 0x34 }; const char* expected = "2001:db8:85a3:8d3:1319:8a2e:370:7334"; const char* expected_port = "[2001:db8:85a3:8d3:1319:8a2e:370:7334]:123"; sockaddr_u input; memset(&input, 0, sizeof(input)); AF(&input) = AF_INET6; SET_ADDR6N(&input, address); SET_PORT(&input, 123); TEST_ASSERT_EQUAL_STRING(expected, socktoa(&input)); TEST_ASSERT_EQUAL_STRING(expected_port, sockporttoa(&input)); #else TEST_IGNORE_MESSAGE("IPV6 disabled in build, skipping."); #endif /* ISC_PLATFORM_HAVEIPV6 */ }
void test_ScopedIPv6AddressWithPort(void) { #ifdef ISC_PLATFORM_HAVESCOPEID const struct in6_addr address = { { { 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x12, 0x3f, 0xff, 0xfe, 0x29, 0xff, 0xfa } } }; const char* expected = "fe80::212:3fff:fe29:fffa%5"; const char* expected_port = "[fe80::212:3fff:fe29:fffa%5]:123"; sockaddr_u input; memset(&input, 0, sizeof(input)); AF(&input) = AF_INET6; SET_ADDR6N(&input, address); SET_PORT(&input, 123); SCOPE_VAR(&input) = 5; TEST_ASSERT_EQUAL_STRING(expected, socktoa(&input)); TEST_ASSERT_EQUAL_STRING(expected_port, sockporttoa(&input)); #else TEST_IGNORE_MESSAGE("Skipping because ISC_PLATFORM does not have Scope ID"); #endif }
*/ static void Accept_New_Port(REBVAL *ds, REBSER *port, REBREQ *sock) /* ** Clone a listening port as a new accept port. ** ***********************************************************************/ { REBREQ *nsock; // Get temp sock struct created by the device: nsock = sock->common.sock; if (!nsock) return; // false alarm sock->common.sock = nsock->next; nsock->common.data = 0; nsock->next = 0; // Create a new port using ACCEPT request passed by sock->common.sock: port = Copy_Block(port, 0); SET_PORT(DS_OUT, port); // Also for GC protect SET_NONE(OFV(port, STD_PORT_DATA)); // just to be sure. SET_NONE(OFV(port, STD_PORT_STATE)); // just to be sure. // Copy over the new sock data: sock = cast(REBREQ*, Use_Port_State(port, RDI_NET, sizeof(*sock))); *sock = *nsock; sock->clen = sizeof(*sock); sock->port = port; OS_FREE(nsock); // allocated by dev_net.c (MT issues?) }
sockaddr_u CreateSockaddr4(const char* address) { sockaddr_u s; s.sa4.sin_family = AF_INET; s.sa4.sin_addr.s_addr = inet_addr(address); SET_PORT(&s, 123); return s; }
sockaddr_u CreateSockaddr4(const char* address, unsigned int port) { sockaddr_u s; s.sa4.sin_family = AF_INET; s.sa4.sin_addr.s_addr = inet_addr(address); SET_PORT(&s, port); return s; }
static void parse_ports(const char *portspec) { const char *p, *q; int port, end; if (ports == NULL) if ((ports = (int *)calloc(65536 / INT_BIT, sizeof(int))) == NULL) err(1, "calloc()"); p = portspec; while (*p != '\0') { if (!isdigit(*p)) errx(1, "syntax error in port range"); for (q = p; *q != '\0' && isdigit(*q); ++q) /* nothing */ ; for (port = 0; p < q; ++p) port = port * 10 + digittoint(*p); if (port < 0 || port > 65535) errx(1, "invalid port number"); SET_PORT(port); switch (*p) { case '-': ++p; break; case ',': ++p; /* fall through */ case '\0': default: continue; } for (q = p; *q != '\0' && isdigit(*q); ++q) /* nothing */ ; for (end = 0; p < q; ++p) end = end * 10 + digittoint(*p); if (end < port || end > 65535) errx(1, "invalid port number"); while (port++ < end) SET_PORT(port); if (*p == ',') ++p; } }
/*========================================================= Name: motor_control Description: This thread outputs the PWM duty cycle through the GPIO to control the fan speed. *=========================================================*/ void * motor_control(void * arg) { while(1) { SET_PORT(18u); usleep(pwm_demand * 500u); CLR_PORT(18u); usleep((100 - pwm_demand) * 500u); } }
/*========================================================= Name: blink Description: This function flashes a LED number of times with a duty cycle (On time = off time) depending on pwm demand *=========================================================*/ void * blink(void * arg) { while(1) { SET_PORT(17); usleep((100 - pwm_demand) * 5000); /* Sleep in microseconds */ CLR_PORT(17); usleep((100 - pwm_demand) * 5000); } }
TEST(socktoa, IgnoreIPv6Fields) { const struct in6_addr address = {{{ 0x20, 0x01, 0x0d, 0xb8, 0x85, 0xa3, 0x08, 0xd3, 0x13, 0x19, 0x8a, 0x2e, 0x03, 0x70, 0x73, 0x34 }}}; sockaddr_u input1, input2; input1.sa6.sin6_family = AF_INET6; input1.sa6.sin6_addr = address; input1.sa6.sin6_flowinfo = 30L; // This value differs from input2. SET_PORT(&input1, NTP_PORT); input2.sa6.sin6_family = AF_INET6; input2.sa6.sin6_addr = address; input2.sa6.sin6_flowinfo = 10L; // This value differs from input1. SET_PORT(&input2, NTP_PORT); TEST_ASSERT_EQUAL(sock_hash(&input1), sock_hash(&input2)); }
void test_IPv4AddressWithPort(void) { const char *str = "192.0.2.2:2000"; sockaddr_u actual; sockaddr_u expected; expected.sa4.sin_family = AF_INET; expected.sa4.sin_addr.s_addr = inet_addr("192.0.2.2"); SET_PORT(&expected, 2000); TEST_ASSERT_TRUE(decodenetnum(str, &actual)); TEST_ASSERT_TRUE(IsEqual(expected, actual)); }
void test_IllegalCharInPort(void) { /* An illegal port does not make the decodenetnum fail, but instead * makes it use the standard port. */ const char *str = "192.0.2.1:a700"; sockaddr_u actual; sockaddr_u expected; expected.sa4.sin_family = AF_INET; expected.sa4.sin_addr.s_addr = inet_addr("192.0.2.1"); SET_PORT(&expected, NTP_PORT); TEST_ASSERT_TRUE(decodenetnum(str, &actual)); TEST_ASSERT_TRUE(IsEqual(expected, actual)); }
TEST(socktoa, IPv6AddressWithPort) { const struct in6_addr address = {{{ 0x20, 0x01, 0x0d, 0xb8, 0x85, 0xa3, 0x08, 0xd3, 0x13, 0x19, 0x8a, 0x2e, 0x03, 0x70, 0x73, 0x34 }}}; const char* expected = "2001:db8:85a3:8d3:1319:8a2e:370:7334"; const char* expected_port = "[2001:db8:85a3:8d3:1319:8a2e:370:7334]:123"; sockaddr_u input; memset(&input, 0, sizeof(input)); AF(&input) = AF_INET6; SET_ADDR6N(&input, address); SET_PORT(&input, 123); TEST_ASSERT_EQUAL_STRING(expected, socktoa(&input)); TEST_ASSERT_EQUAL_STRING(expected_port, sockporttoa(&input)); }
TEST(socktoa, ScopedIPv6AddressWithPort) { const struct in6_addr address = {{{ 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x12, 0x3f, 0xff, 0xfe, 0x29, 0xff, 0xfa }}}; const char* expected = "fe80::212:3fff:fe29:fffa%5"; const char* expected_port = "[fe80::212:3fff:fe29:fffa%5]:123"; sockaddr_u input; memset(&input, 0, sizeof(input)); AF(&input) = AF_INET6; SET_ADDR6N(&input, address); SET_PORT(&input, 123); SCOPE_VAR(&input) = 5; TEST_ASSERT_EQUAL_STRING(expected, socktoa(&input)); TEST_ASSERT_EQUAL_STRING(expected_port, sockporttoa(&input)); }
int __cdecl main() { WSADATA wsd; INT i = 0, nErr = 0, nStartup = 0, rc = 0; SOCKET sock = INVALID_SOCKET; SOCKADDR_STORAGE addr = {0}, mcaddr = {0}, remoteaddr = {0}; WSAOVERLAPPED over = {0}; WSABUF wsabuf = {0}; DWORD dwBytes = 0, dwFlags = 0, dwRet = 0; IPV6_MREQ mreq = {0}; WSAMSG wsamsg = {0}; LPFN_WSARECVMSG WSARecvMsg = NULL; __try { //Initialize Winsock nErr = WSAStartup(WS_VER,&wsd); if (nErr) { WSASetLastError(nErr); ERR("WSAStartup"); __leave; } else nStartup++; // bind socket and register multicast mcaddr.ss_family = AF_INET6; InitMcastAddr((SOCKADDR*)&mcaddr,sizeof mcaddr); if (INVALID_SOCKET == (sock = socket(AF_INET6,SOCK_DGRAM,0))) { ERR("socket"); __leave; } if(!RouteLookup((SOCKADDR*)&mcaddr, sizeof mcaddr, (SOCKADDR*)&addr, sizeof addr )) { ERR("RouteLookup"); __leave; } SET_PORT((SOCKADDR*)&addr,DEFAULT_PORT); if (SOCKET_ERROR == bind(sock,(SOCKADDR*)&addr,sizeof addr)) { ERR("bind"); __leave; } mreq.ipv6mr_multiaddr = ((SOCKADDR_IN6*)&mcaddr)->sin6_addr; if (SOCKET_ERROR == setsockopt(sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (char*)&mreq, sizeof mreq )) { ERR("setsockopt IPV6_ADD_MEMBRESHIP"); __leave; } // PktInfo if (!SetIpv6PktInfoOption(sock)) { ERR("SetIpv6PktInfoOption"); __leave; } if(!AllocAndInitIpv6PktInfo(&wsamsg)) { ERR("AllocAndInitIpv6PktInfo"); __leave; } // data buffer wsabuf.buf = (CHAR*)MALLOC(100); if(NULL == wsabuf.buf) { ERR("HeapAlloc"); __leave; } wsabuf.len = (ULONG)MSIZE(wsabuf.buf); wsamsg.lpBuffers = &wsabuf; wsamsg.dwBufferCount = 1; // packet source address wsamsg.name = (SOCKADDR*)&remoteaddr; wsamsg.namelen = sizeof remoteaddr; //Post overlapped WSARecvMsg InitOverlap(&over); if (NULL == (WSARecvMsg = GetWSARecvMsgFunctionPointer())) { ERR("GetWSARecvMsgFunctionPointer"); __leave; } if (SOCKET_ERROR == WSARecvMsg(sock, &wsamsg, &dwBytes, &over, NULL )) { if (WSA_IO_PENDING != WSAGetLastError()) { ERR("WSARecvMsg"); __leave; } } //set send interface if (SOCKET_ERROR == SetSendInterface(sock,(SOCKADDR*)&addr)) { ERR("SetSendInterface"); __leave; } //send msg to multicast SET_PORT((SOCKADDR*)&mcaddr,DEFAULT_PORT); //send a few packets for (i=0; i<5; i++) { if (SOCKET_ERROR == (rc = sendto(sock, TST_MSG, lstrlenA(TST_MSG), 0, (SOCKADDR*)&mcaddr, sizeof (mcaddr) ))) { ERR("sendto"); __leave; } printf("Sent %d bytes\n",rc); } dwRet = WaitForSingleObject(over.hEvent,DEFAULT_WAIT); if (dwRet) { printf("%s\n",gai_strerror(dwRet)); __leave; } if (!WSAGetOverlappedResult(sock, &over, &dwBytes, TRUE, &dwFlags )) { ERR("WSAGetOverlappedResult"); __leave; } printf("WSARecvMsg completed with %d bytes\n",dwBytes); // if multicast packet do further processing if (MSG_MCAST & wsamsg.dwFlags) { if (ProcessIpv6Msg(&wsamsg)) { //do something more interesting here printf("Recvd multicast msg.\n"); } } } __finally { CLOSESOCK(sock); FREE(wsabuf.buf); FREE(wsamsg.Control.buf); CLOSESOCKEVENT(over.hEvent); if(nStartup) WSACleanup(); } return 0; }
void SetSockaddr4(sockaddr_u* s, const char* address) { s->sa4.sin_family = AF_INET; s->sa4.sin_addr.s_addr = inet_addr(address); SET_PORT(s, 123); return; }
void *tcpSock(void *param) { PRINTD(1,"tcpSock: tcpSock started\n"); #ifdef WIN32 int first = 1; #endif HANDLE hComm = 0; paramThread *paraThread; paraThread = (paramThread *) param; int sock = 0; unsigned char payload[MAX_PAYLOAD_SIZE]; struct info *infos = (struct info *) calloc(logbuffer_size, sizeof(info)); struct addrinfo SrcAddress; in_port_t tmpPort = 0; int newSock = 0; int size = 0; unsigned char *ptrSeqNum = payload + sizeof(uint32_t); unsigned char *ptrTimeSec = ptrSeqNum + sizeof(uint32_t); unsigned char *ptrTimeUsec = ptrTimeSec + sizeof(uint32_t); struct timeval RcvTime; #ifdef WIN32 LARGE_INTEGER _tstart, _tend; unsigned long secs = 0, msecs = 0; #endif paraThread->addressInfos = infos; paraThread->count = 0; memset(payload, 0, MAX_PAYLOAD_SIZE); if (strcmp(paraThread->serial, "noSerial") != 0) { hComm = serialUp(paraThread->serial); if (hComm == INVALID_HANDLE_VALUE) printf("Error opening interface %s \n", paraThread->serial); } bool socketAlreadyOpen = false; #ifdef MULTIPORT if ((passiveMode == false) && (paraThread->indexPort > 0)) { MUTEX_THREAD_LOCK(sharedTcpSockets[paraThread->indexPort].mutexSharedSockets); sock = sharedTcpSockets[paraThread->indexPort].socket; if (sock > 0) { socketAlreadyOpen = true; } } #endif if (socketAlreadyOpen == false) { sock = socket(paraThread->destHost.ai_family, SOCK_STREAM, 0); if (paraThread->dsByte && (paraThread->destHost.ai_family == AF_INET) && setsockopt(sock, SOL_IP, IP_TOS, (char *) ¶Thread->dsByte, sizeof(BYTE)) < 0) { printf("** WARNING ** Flow %d. Could not set DS byte to: %d\n", paraThread->flowId, paraThread->dsByte); } } if (sock < 0) reportErrorAndExit("tcpSock", "socket", "Cannot create a STREAM socket on port"); if ((passiveMode == false) && (socketAlreadyOpen == false)) { if (bind(sock, paraThread->destHost.ai_addr, paraThread->destHost.ai_addrlen) < 0) { struct pipeMsg msg; msg.code = MSG_FT_ERR1; msg.flowId = paraThread->flowId; if (sendPipeMsg(paraThread->rPipe, &msg) < 0) { printf(" sending msg error"); } sleep(INFINITE); } } //#if defined UNIX && ! defined BSD if ((paraThread->iface) && (socketAlreadyOpen == false)) { printf("Binding to device %s\n", paraThread->iface); if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, paraThread->iface, strlen(paraThread->iface)) < 0) { printf("** WARNING ** Cannot bind to device %s (hint: you must be root)\n", paraThread->iface); fflush(stdout); } } //#endif if ((passiveMode == false) && (socketAlreadyOpen == false)) { if (listen(sock, SOMAXCONN) < 0) reportErrorAndExit("tcpSock", "listen", "Cannot listen on a port"); else { #ifdef WIN32 int len=paraThread->destHost.ai_addrlen; getsockname(sock,paraThread->destHost.ai_addr,&len); paraThread->destHost.ai_addrlen=len; #else getsockname(sock, paraThread->destHost.ai_addr, &(paraThread->destHost.ai_addrlen)); #endif GET_PORT((&(paraThread->destHost)), tmpPort); printf("Listening on TCP port : %d\n", ntohs(tmpPort)); fflush(stdout); #ifdef MULTIPORT if (paraThread->indexPort == 0) { paraThread->indexPort = ntohs(tmpPort); MUTEX_THREAD_LOCK(sharedTcpSockets[paraThread->indexPort].mutexSharedSockets); } #endif struct pipeMsg msg; msg.code = MSG_FT_OK; msg.flowId = paraThread->flowId; if (sendPipeMsg(paraThread->rPipe, &msg) < 0) { printf("error into sending msg to signal manager"); } } } #ifdef MULTIPORT else if ((passiveMode == false) && (socketAlreadyOpen == true)) { struct pipeMsg msg; msg.code = MSG_FT_OK; msg.flowId = paraThread->flowId; if (sendPipeMsg(paraThread->rPipe, &msg) < 0) { printf("error into sending msg to signal manager"); } } #endif SrcAddress.ai_family = paraThread->destHost.ai_family; if (SrcAddress.ai_family == PF_INET) { SrcAddress.ai_addr = (struct sockaddr *) malloc(sizeof(struct sockaddr_in)); SrcAddress.ai_addrlen = sizeof(struct sockaddr_in); } else if (SrcAddress.ai_family == PF_INET6) { SrcAddress.ai_addr = (struct sockaddr *) malloc(sizeof(struct sockaddr_in6)); SrcAddress.ai_addrlen = sizeof(struct sockaddr_in6); } pthread_cleanup_push(free, SrcAddress.ai_addr); if (passiveMode == false) { if ((newSock = accept(sock, SrcAddress.ai_addr, (socklen_t *) &SrcAddress.ai_addrlen)) < 0) reportErrorAndExit("tcpSock", "accept", "Cannot accept connection"); #ifdef MULTIPORT if ((passiveMode == false) && (socketAlreadyOpen == false)) { sharedTcpSockets[paraThread->indexPort].socket = sock; } sharedTcpSockets[paraThread->indexPort].inUse++; MUTEX_THREAD_UNLOCK(sharedTcpSockets[paraThread->indexPort].mutexSharedSockets); #else if ( closeSock(sock) == -1) reportErrorAndExit("tcpSock","closeSock","Cannot close socket sock"); #endif paraThread->socketClose = newSock; } else { struct addrinfo *SrcAddrForConnect = NULL; //#if (defined WIN32 && defined IPv6RECV) || defined UNIX || defined BSD if (paraThread->destHost.ai_family == PF_INET6) { getaddrinfo("::", NULL, &hint, &SrcAddrForConnect); } else //#endif { getaddrinfo("0.0.0.0", NULL, &hint, &SrcAddrForConnect); } SET_PORT((SrcAddrForConnect), htons((paraThread->portForPssv))); if (bind(sock, SrcAddrForConnect->ai_addr, SrcAddrForConnect->ai_addrlen) < 0) { struct pipeMsg msg; msg.code = MSG_FT_ERR1; msg.flowId = paraThread->flowId; if (sendPipeMsg(paraThread->rPipe, &msg) < 0) { printf(" sending msg error"); } sleep(INFINITE); } if (connect(sock, paraThread->destHost.ai_addr, paraThread->destHost.ai_addrlen) < 0) reportErrorAndExit("tcpSock", "connect", "Cannot connect (Passive Mode)"); PRINTD(1,"tcpSock: Connection establishes (Passive Mode)\n"); freeaddrinfo(SrcAddrForConnect); newSock = sock; paraThread->socketClose = sock; #ifdef WIN32 int len=SrcAddress.ai_addrlen; getsockname(sock,SrcAddress.ai_addr,&len); SrcAddress.ai_addrlen=len; #else getsockname(sock, SrcAddress.ai_addr, &SrcAddress.ai_addrlen); #endif } int firstpacket = 1; char HelpSrcAddress[INET6_ADDRSTRLEN]; char HelpDstAddress[INET6_ADDRSTRLEN]; int tmpPort_SrcPort = 0; int tmpPort_DstPort = 0; TSTART(_tstart, secs, msecs, first, 0, RECEIVER); PRINTD(1,"tcpSock: main loop\n"); while (1) { PRINTD(2, "tcpSock: preambleSize = %d \n",paraThread->preambleSize); size = TCPrecvPacket((unsigned char*) payload, newSock, paraThread->preambleSize, paraThread->payloadLogType); if (size <= 0) { PRINTD(1,"tcpSock: TCPrecvPacket() = %d\n",size); if (size < 0) { struct pipeMsg msg; if (passiveMode == false) { GET_PORT((&(paraThread->destHost)), tmpPort_DstPort); } else { GET_PORT((&SrcAddress), tmpPort_DstPort); } printf("Error on TCP port : %d\n", ntohs(tmpPort_DstPort)); printf("Finish on TCP port : %d\n\n", ntohs(tmpPort_DstPort)); fflush(stdout); msg.code = MSG_FT_ERR_SOCK; msg.flowId = paraThread->flowId; if (sendPipeMsg(paraThread->rPipe, &msg) < 0) { printf(" sending msg error"); } } sleep(INFINITE); } if (hComm > 0) { DTR_Disable(hComm); DTR_Enable(hComm); } GET_TIME_OF_DAY(&RcvTime, _tend, _tstart, secs, msecs, 0, RECEIVER); if ((logCheck != 0) || (logRemote != 0)) { if (firstpacket == 1) { if (passiveMode == false) { getInfo(&SrcAddress, tmpPort_SrcPort, HelpSrcAddress); getInfo(¶Thread->destHost, tmpPort_DstPort, HelpDstAddress); } else { #ifdef WIN32 int len=SrcAddress.ai_addrlen; getsockname(sock,SrcAddress.ai_addr,&len); SrcAddress.ai_addrlen=len; #else getsockname(sock, SrcAddress.ai_addr, &SrcAddress.ai_addrlen); #endif getInfo(¶Thread->destHost, tmpPort_SrcPort, HelpSrcAddress); getInfo(&SrcAddress, tmpPort_DstPort, HelpDstAddress); } firstpacket = 0; } if (paraThread->l7Proto == L7_PROTO_TELNET) size = size - 20; if (logCheck != 0) { int net_TimeSec = ntohl(*(uint32_t *) ptrTimeSec); int net_TimeUsec = ntohl(*(uint32_t *) ptrTimeUsec); if (paraThread->payloadLogType == PL_STANDARD) { writeInBufferStandard(&infos[paraThread->count], *(uint32_t *) payload, *(unsigned int *) ptrSeqNum, HelpSrcAddress, HelpDstAddress, tmpPort_SrcPort, tmpPort_DstPort, net_TimeSec, RcvTime.tv_sec % 86400L, net_TimeUsec, RcvTime.tv_usec, size); } else if (paraThread->payloadLogType == PL_SHORT) { writeInBufferShort(&infos[paraThread->count], *(uint32_t *) payload, *(unsigned int *) ptrSeqNum, HelpSrcAddress, HelpDstAddress, tmpPort_SrcPort, tmpPort_DstPort, RcvTime.tv_sec % 86400L, RcvTime.tv_usec, size); } else { writeInBufferNone(&infos[paraThread->count], paraThread->flowId, HelpSrcAddress, HelpDstAddress, tmpPort_SrcPort, tmpPort_DstPort, RcvTime.tv_sec % 86400L, RcvTime.tv_usec, size); } } if (logRemote != 0) { int net_TimeSec = ntohl(*(uint32_t *) ptrTimeSec); int net_TimeUsec = ntohl(*(uint32_t *) ptrTimeUsec); if (paraThread->payloadLogType == PL_STANDARD) { writeInBufferStandard(&infos[paraThread->count], *(uint32_t *) payload, *(uint32_t *) ptrSeqNum, HelpSrcAddress, HelpDstAddress, tmpPort_SrcPort, tmpPort_DstPort, net_TimeSec, RcvTime.tv_sec % 86400L, net_TimeUsec, RcvTime.tv_usec, size); } else if (paraThread->payloadLogType == PL_SHORT) { writeInBufferShort(&infos[paraThread->count], *(uint32_t *) payload, *(uint32_t *) ptrSeqNum, HelpSrcAddress, HelpDstAddress, tmpPort_SrcPort, tmpPort_DstPort, RcvTime.tv_sec % 86400L, RcvTime.tv_usec, size); } else { writeInBufferNone(&infos[paraThread->count], paraThread->flowId, HelpSrcAddress, HelpDstAddress, tmpPort_SrcPort, tmpPort_DstPort, RcvTime.tv_sec % 86400L, RcvTime.tv_usec, size); } infosHostToNet(&infos[paraThread->count]); } if (size != 0) paraThread->count++; if (paraThread->count == logbuffer_size) { if (logCheck != 0) flushBuffer((ofstream *) paraThread->fileLog, infos, paraThread->count); else if (logRemote != 0) { MUTEX_THREAD_LOCK(mutexLogRem); if (sendto(paraThread->logSock, (char *) infos, paraThread->count * sizeof(struct info), 0, paraThread->logHost->ai_addr, paraThread->logHost->ai_addrlen) < 0) reportErrorAndExit("tcpSock", "sendto", "Cannot send log infos to LogServer"); paraThread->count = 0; MUTEX_THREAD_UNLOCK(mutexLogRem); PRINTD(1,"tcpSock: Sent infos to LogServer\n"); } } } if (paraThread->meter == METER_RTTM) { if (sendto(newSock, (char *) payload, size, 0, SrcAddress.ai_addr, SrcAddress.ai_addrlen) < 0) reportErrorAndExit("tcpSock", "sendto", "Cannot send payload back for rttm"); PRINTD(2,"tcpSock: Sent RTTM infos\n"); } } pthread_cleanup_pop(1); return NULL; }
void *udpSock(void *param) { PRINTD(1,"udpSock: udpSock started\n"); #ifdef WIN32 int first = 1; #endif HANDLE hComm = 0; paramThread *paraThread; paraThread = (paramThread *) param; int sock = 0; unsigned char payload[MAX_PAYLOAD_SIZE]; struct info *infos = (struct info *) calloc(logbuffer_size, sizeof(info)); struct addrinfo SrcAddress; in_port_t tmpPort = 0; int size_r = 0; unsigned char *ptrSeqNum = payload + sizeof(uint32_t); unsigned char *ptrTimeSec = ptrSeqNum + sizeof(uint32_t); unsigned char *ptrTimeUsec = ptrTimeSec + sizeof(uint32_t); struct timeval RcvTime; #ifdef WIN32 LARGE_INTEGER _tstart, _tend; unsigned long secs = 0, msecs = 0; #endif paraThread->addressInfos = infos; paraThread->count = 0; if (strcmp(paraThread->serial, "noSerial") != 0) { hComm = serialUp(paraThread->serial); if (hComm == INVALID_HANDLE_VALUE) printf("Error opening interface %s \n", paraThread->serial); } bool socketAlreadyOpen = false; #ifdef MULTIPORT if ((passiveMode == false) && (paraThread->indexPort > 0)) { MUTEX_THREAD_LOCK(sharedUdpSockets[paraThread->indexPort].mutexSharedSockets); sock = sharedUdpSockets[paraThread->indexPort].socket; if (sock > 0) { socketAlreadyOpen = true; } } #endif if (socketAlreadyOpen == false) { sock = socket(paraThread->destHost.ai_family, SOCK_DGRAM, 0); if (paraThread->dsByte && (paraThread->destHost.ai_family == AF_INET) && setsockopt(sock, SOL_IP, IP_TOS, (char *) ¶Thread->dsByte, sizeof(BYTE)) < 0) { printf("** WARNING ** Flow %d. Could not set DS byte to: %d\n", paraThread->flowId, paraThread->dsByte); } } if (sock < 0) reportErrorAndExit("udpSock", "socket", "Cannot create a DATAGRAM socket on port"); if ((passiveMode == false) && (socketAlreadyOpen == false)) { if (bind(sock, paraThread->destHost.ai_addr, paraThread->destHost.ai_addrlen) < 0) { printf("Error into bind function!\n"); struct pipeMsg msg; msg.code = MSG_FT_ERR1; msg.flowId = paraThread->flowId; if (sendPipeMsg(paraThread->rPipe, &msg) < 0) { printf(" sending msg error"); } sleep(INFINITE); } else { #ifdef WIN32 int len=paraThread->destHost.ai_addrlen; getsockname(sock,paraThread->destHost.ai_addr,&len); paraThread->destHost.ai_addrlen=len; #else getsockname(sock, paraThread->destHost.ai_addr, &(paraThread->destHost.ai_addrlen)); #endif GET_PORT((&(paraThread->destHost)), tmpPort); fprintf(stderr, "Listening on UDP port : %d\n", ntohs(tmpPort)); fflush(stderr); #ifdef MULTIPORT if (paraThread->indexPort == 0) { paraThread->indexPort = ntohs(tmpPort); MUTEX_THREAD_LOCK(sharedUdpSockets[paraThread->indexPort].mutexSharedSockets); } #endif struct pipeMsg msg; msg.code = MSG_FT_OK; msg.flowId = paraThread->flowId; if (sendPipeMsg(paraThread->rPipe, &msg) < 0) { printf("error sending msg to signal manager"); } } } else if (passiveMode == true) { struct addrinfo *addrForListen = NULL; //#if (defined WIN32 && defined IPv6RECV) || defined UNIX || defined BSD if (paraThread->destHost.ai_family == PF_INET6) { getaddrinfo("::", NULL, &hint, &addrForListen); } else //#endif { getaddrinfo("0.0.0.0", NULL, &hint, &addrForListen); } SET_PORT((addrForListen), htons((paraThread->portForPssv))); if (bind(sock, addrForListen->ai_addr, addrForListen->ai_addrlen) < 0) { struct pipeMsg msg; msg.code = MSG_FT_ERR1; msg.flowId = paraThread->flowId; if (sendPipeMsg(paraThread->rPipe, &msg) < 0) { printf(" sending msg error"); } sleep(INFINITE); } else { GET_PORT(( addrForListen), tmpPort); printf("Listening on UDP port : %d\n", ntohs(tmpPort)); fflush(stdout); for (int x = 0; x < numHolePkt; x++) { if (sendto(sock, "hello", sizeof("hello"), 0, paraThread->destHost.ai_addr, paraThread->destHost.ai_addrlen) < 0) { reportErrorAndExit("udpSock", "sendto", "Cannot sendto (Passive Mode --> Hole punching)"); } } } if (connect(sock, paraThread->destHost.ai_addr, paraThread->destHost.ai_addrlen) < 0) { reportErrorAndExit("udpSock", "connect", "Cannot connect (Passive Mode)"); } freeaddrinfo(addrForListen); } #ifdef MULTIPORT else if ((passiveMode == false) && (socketAlreadyOpen == true)) { struct pipeMsg msg; msg.code = MSG_FT_OK; msg.flowId = paraThread->flowId; if (sendPipeMsg(paraThread->rPipe, &msg) < 0) { printf("error sending msg to signal manager"); } } if (passiveMode == false) { if (socketAlreadyOpen == false) { sharedUdpSockets[paraThread->indexPort].socket = sock; } sharedUdpSockets[paraThread->indexPort].inUse++; MUTEX_THREAD_UNLOCK(sharedUdpSockets[paraThread->indexPort].mutexSharedSockets); } #endif //#if defined UNIX && ! defined BSD if ((paraThread->iface) && (socketAlreadyOpen == false)) { printf("Binding to device %s\n", paraThread->iface); if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, paraThread->iface, strlen(paraThread->iface)) < 0) { printf("** WARNING ** Cannot bind to device %s (hint: you must be root)\n", paraThread->iface); fflush(stdout); } } //#endif paraThread->socketClose = sock; SrcAddress.ai_family = paraThread->destHost.ai_family; if (SrcAddress.ai_family == PF_INET) { SrcAddress.ai_addr = (struct sockaddr *) malloc(sizeof(struct sockaddr_in)); SrcAddress.ai_addrlen = sizeof(struct sockaddr_in); } else if (SrcAddress.ai_family == PF_INET6) { SrcAddress.ai_addr = (struct sockaddr *) malloc(sizeof(struct sockaddr_in6)); SrcAddress.ai_addrlen = sizeof(struct sockaddr_in6); } pthread_cleanup_push(free, SrcAddress.ai_addr); int firstpacket = 1; char HelpSrcAddress[INET6_ADDRSTRLEN]; char HelpDstAddress[INET6_ADDRSTRLEN]; int tmpPort_SrcPort = 0; int tmpPort_DstPort = 0; TSTART(_tstart, secs, msecs, first, 0, RECEIVER); PRINTD(1,"udpSock: main loop\n"); while (1) { if (passiveMode == false) { size_r = recvfrom(sock, (char *) payload, MAX_PAYLOAD_SIZE, 0, SrcAddress.ai_addr, (socklen_t *) &SrcAddress.ai_addrlen); } else { size_r = recvfrom(sock, (char *) payload, MAX_PAYLOAD_SIZE, 0, NULL, NULL); } PRINTD(2,"udpSock: Received DATAGRAM packet\n"); if (size_r < 0) { PRINTD(1,"\nudpSock: Error:%s\n",strerror(errno)); #ifndef OSX reportErrorAndExit("udpSock", "recvfrom", "Cannot receive UDP packets"); #else sleep(INFINITE); #endif } if (hComm > 0) { DTR_Disable(hComm); DTR_Enable(hComm); } GET_TIME_OF_DAY(&RcvTime, _tend, _tstart, secs, msecs, 0, RECEIVER); if ((logCheck != 0) || (logRemote != 0)) { if (firstpacket == 1) { if (passiveMode == false) { getInfo(&SrcAddress, tmpPort_SrcPort, HelpSrcAddress); getInfo(¶Thread->destHost, tmpPort_DstPort, HelpDstAddress); } else { #ifdef WIN32 int len=SrcAddress.ai_addrlen; getsockname(sock,SrcAddress.ai_addr,&len); SrcAddress.ai_addrlen=len; #else getsockname(sock, SrcAddress.ai_addr, &SrcAddress.ai_addrlen); #endif getInfo(¶Thread->destHost, tmpPort_SrcPort, HelpSrcAddress); getInfo(&SrcAddress, tmpPort_DstPort, HelpDstAddress); } firstpacket = 0; } #ifdef MULTIPORT else if (passiveMode == false) { getInfo(&SrcAddress, tmpPort_SrcPort, HelpSrcAddress); } #endif if (logCheck != 0) { int net_TimeSec = ntohl(*(uint32_t *) ptrTimeSec); int net_TimeUsec = ntohl(*(uint32_t *) ptrTimeUsec); if (paraThread->payloadLogType == PL_STANDARD) { writeInBufferStandard(&infos[paraThread->count], *(uint32_t *) payload, *(uint32_t *) ptrSeqNum, HelpSrcAddress, HelpDstAddress, tmpPort_SrcPort, tmpPort_DstPort, net_TimeSec, RcvTime.tv_sec % 86400L, net_TimeUsec, RcvTime.tv_usec, size_r); } else if (paraThread->payloadLogType == PL_SHORT) { writeInBufferShort(&infos[paraThread->count], *(uint32_t *) payload, *(uint32_t *) ptrSeqNum, HelpSrcAddress, HelpDstAddress, tmpPort_SrcPort, tmpPort_DstPort, RcvTime.tv_sec % 86400L, RcvTime.tv_usec, size_r); } else { writeInBufferNone(&infos[paraThread->count], paraThread->flowId, HelpSrcAddress, HelpDstAddress, tmpPort_SrcPort, tmpPort_DstPort, RcvTime.tv_sec % 86400L, RcvTime.tv_usec, size_r); } } if (logRemote != 0) { int net_TimeSec = ntohl(*(uint32_t *) ptrTimeSec); int net_TimeUsec = ntohl(*(uint32_t *) ptrTimeUsec); if (paraThread->payloadLogType == PL_STANDARD) { writeInBufferStandard(&infos[paraThread->count], *(uint32_t *) payload, *(uint32_t *) ptrSeqNum, HelpSrcAddress, HelpDstAddress, tmpPort_SrcPort, tmpPort_DstPort, net_TimeSec, RcvTime.tv_sec % 86400L, net_TimeUsec, RcvTime.tv_usec, size_r); } else if (paraThread->payloadLogType == PL_SHORT) { writeInBufferShort(&infos[paraThread->count], *(uint32_t *) payload, *(uint32_t *) ptrSeqNum, HelpSrcAddress, HelpDstAddress, tmpPort_SrcPort, tmpPort_DstPort, RcvTime.tv_sec % 86400L, RcvTime.tv_usec, size_r); } else { writeInBufferNone(&infos[paraThread->count], paraThread->flowId, HelpSrcAddress, HelpDstAddress, tmpPort_SrcPort, tmpPort_DstPort, RcvTime.tv_sec % 86400L, RcvTime.tv_usec, size_r); } infosHostToNet(&infos[paraThread->count]); } paraThread->count++; if (paraThread->count == logbuffer_size) { if (logCheck != 0) flushBuffer((ofstream *) paraThread->fileLog, infos, paraThread->count); else if (logRemote != 0) { MUTEX_THREAD_LOCK(mutexLogRem); if (sendto(paraThread->logSock, (char *) infos, paraThread->count * sizeof(struct info), 0, paraThread->logHost->ai_addr, paraThread->logHost->ai_addrlen) < 0) reportErrorAndExit("udpSock", "sendto", "Cannot send log infos to LogServer"); paraThread->count = 0; MUTEX_THREAD_UNLOCK(mutexLogRem); PRINTD(1,"udpSock: Sent Infos to LogServer\n"); } } } if (paraThread->meter == METER_RTTM) { if (passiveMode == false) { if (sendto(sock, (char *) payload, size_r, 0, SrcAddress.ai_addr, SrcAddress.ai_addrlen) < 0) reportErrorAndExit("udpSock", "sendto", "Cannot send back payload for rttm"); } else { if (sendto(sock, (char *) payload, size_r, 0, NULL, 0) < 0) reportErrorAndExit("udpSock", "sendto", "Cannot send back payload for rttm (Passive Mode)"); } PRINTD(2,"udpSock: Sent RTTM message\n"); } } pthread_cleanup_pop(1); return NULL; }
static int net_bindV6(struct ipv6bind* b) { SOCKET fd=INVALID_SOCKET, ofd=INVALID_SOCKET, rv; int len; /* need to defer close until new sockets created */ SOCKET close_fd=INVALID_SOCKET, close_ofd=INVALID_SOCKET; SOCKETADDRESS oaddr; /* other address to bind */ int family = b->addr->him.sa_family; int ofamily; u_short port; /* requested port parameter */ u_short bound_port; /* We only bind to only IPv4 or IPv6 if the listen address is different from the ANY IP address or * the LOOPBACK IP address. */ if (family == AF_INET && (b->addr->him4.sin_addr.s_addr != INADDR_ANY) && (b->addr->him4.sin_addr.s_addr != htonl (INADDR_LOOPBACK))) { /* bind to v4 only */ int ret; ret = net_bind (b->ipv4_fd, (struct sockaddr *)b->addr, sizeof (struct sockaddr_in)); if (ret == SOCKET_ERROR) { CLOSE_SOCKETS_AND_RETURN; } closesocket (b->ipv6_fd); b->ipv6_fd = INVALID_SOCKET; return 0; } if (family == AF_INET6 && (!NET_IN6ADDR_ISANY(&b->addr->him6)) && !NET_IN6ADDR_ISLOOPBACK(&b->addr->him6)) { /* bind to v6 only */ int ret; ret = net_bind (b->ipv6_fd, (struct sockaddr *)b->addr, sizeof (struct sockaddr_in6)); if (ret == SOCKET_ERROR) { CLOSE_SOCKETS_AND_RETURN; } closesocket (b->ipv4_fd); b->ipv4_fd = INVALID_SOCKET; return 0; } /* We need to bind on both stacks, with the same port number */ memset (&oaddr, 0, sizeof(oaddr)); if (family == AF_INET) { ofamily = AF_INET6; fd = b->ipv4_fd; ofd = b->ipv6_fd; port = ntohs (GET_PORT (b->addr)); if (b->addr->him4.sin_addr.s_addr == htonl (INADDR_LOOPBACK)) { NET_IN6ADDR_SETLOOPBACK (&oaddr.him6); } else { NET_IN6ADDR_SETANY (&oaddr.him6); } oaddr.him6.sin6_port = port; } else { ofamily = AF_INET; ofd = b->ipv4_fd; fd = b->ipv6_fd; port = ntohs (GET_PORT (b->addr)); oaddr.him4.sin_family = AF_INET; oaddr.him4.sin_port = port; if (NET_IN6ADDR_ISLOOPBACK(&b->addr->him6)) { oaddr.him4.sin_addr.s_addr = htonl (INADDR_LOOPBACK); } else { oaddr.him4.sin_addr.s_addr = INADDR_ANY; } } rv = net_bind (fd, (struct sockaddr *)b->addr, SOCKETADDRESS_LEN(b->addr)); if (rv == SOCKET_ERROR) { CLOSE_SOCKETS_AND_RETURN; } /* get the port and set it in the other address */ len = SOCKETADDRESS_LEN(b->addr); if (getsockname(fd, (struct sockaddr *)b->addr, &len) == -1) { CLOSE_SOCKETS_AND_RETURN; } bound_port = ntohs (GET_PORT (b->addr)); SET_PORT (&oaddr, htons (bound_port)); len = SOCKETADDRESS_LEN (&oaddr); if ((rv=net_bind (ofd, (struct sockaddr *) &oaddr, len)) == SOCKET_ERROR) { int retries; int sotype, arglen=sizeof(sotype); /* no retries unless, the request was for any free port */ if (port != 0) { CLOSE_SOCKETS_AND_RETURN; } getsockopt(fd, SOL_SOCKET, SO_TYPE, (void *)&sotype, &arglen); #define SOCK_RETRIES 50 /* 50 is an arbitrary limit, just to ensure that this * cannot be an endless loop. Would expect socket creation to * succeed sooner. */ for (retries = 0; retries < SOCK_RETRIES; retries ++) { int len; close_fd = fd; fd = INVALID_SOCKET; close_ofd = ofd; ofd = INVALID_SOCKET; b->ipv4_fd = INVALID_SOCKET; b->ipv6_fd = INVALID_SOCKET; /* create two new sockets */ fd = check_socket_bounds (socket (family, sotype, 0)); if (fd == INVALID_SOCKET) { CLOSE_SOCKETS_AND_RETURN; } ofd = check_socket_bounds (socket (ofamily, sotype, 0)); if (ofd == INVALID_SOCKET) { CLOSE_SOCKETS_AND_RETURN; } /* bind random port on first socket */ SET_PORT (&oaddr, 0); rv = net_bind (ofd, (struct sockaddr *)&oaddr, SOCKETADDRESS_LEN(&oaddr)); if (rv == SOCKET_ERROR) { CLOSE_SOCKETS_AND_RETURN; } /* close the original pair of sockets before continuing */ closesocket (close_fd); closesocket (close_ofd); close_fd = close_ofd = INVALID_SOCKET; /* bind new port on second socket */ len = SOCKETADDRESS_LEN(&oaddr); if (getsockname(ofd, (struct sockaddr *)&oaddr, &len) == -1) { CLOSE_SOCKETS_AND_RETURN; } bound_port = ntohs (GET_PORT (&oaddr)); SET_PORT (b->addr, htons (bound_port)); rv = net_bind (fd, (struct sockaddr *)b->addr, SOCKETADDRESS_LEN(b->addr)); if (rv != SOCKET_ERROR) { if (family == AF_INET) { b->ipv4_fd = fd; b->ipv6_fd = ofd; } else { b->ipv4_fd = ofd; b->ipv6_fd = fd; } return 0; } } CLOSE_SOCKETS_AND_RETURN; } return 0; }
/* ** open sockets and make them non-blocking */ void open_sockets( void ) { sockaddr_u name; if (-1 == sock4) { sock4 = socket(PF_INET, SOCK_DGRAM, 0); if (-1 == sock4) { /* error getting a socket */ msyslog(LOG_ERR, "open_sockets: socket(PF_INET) failed: %m"); exit(1); } /* Make it non-blocking */ make_socket_nonblocking(sock4); /* Let's try using a wildcard... */ ZERO(name); AF(&name) = AF_INET; SET_ADDR4N(&name, INADDR_ANY); SET_PORT(&name, (HAVE_OPT(USERESERVEDPORT) ? 123 : 0)); if (-1 == bind(sock4, &name.sa, SOCKLEN(&name))) { msyslog(LOG_ERR, "open_sockets: bind(sock4) failed: %m"); exit(1); } /* Register an NTP callback for recv/timeout */ ev_sock4 = event_new(base, sock4, EV_TIMEOUT | EV_READ | EV_PERSIST, &sock_cb, NULL); if (NULL == ev_sock4) { msyslog(LOG_ERR, "open_sockets: event_new(base, sock4) failed!"); } else { event_add(ev_sock4, &wakeup_tv); } } /* We may not always have IPv6... */ if (-1 == sock6 && ipv6_works) { sock6 = socket(PF_INET6, SOCK_DGRAM, 0); if (-1 == sock6 && ipv6_works) { /* error getting a socket */ msyslog(LOG_ERR, "open_sockets: socket(PF_INET6) failed: %m"); exit(1); } /* Make it non-blocking */ make_socket_nonblocking(sock6); /* Let's try using a wildcard... */ ZERO(name); AF(&name) = AF_INET6; SET_ADDR6N(&name, in6addr_any); SET_PORT(&name, (HAVE_OPT(USERESERVEDPORT) ? 123 : 0)); if (-1 == bind(sock6, &name.sa, SOCKLEN(&name))) { msyslog(LOG_ERR, "open_sockets: bind(sock6) failed: %m"); exit(1); } /* Register an NTP callback for recv/timeout */ ev_sock6 = event_new(base, sock6, EV_TIMEOUT | EV_READ | EV_PERSIST, &sock_cb, NULL); if (NULL == ev_sock6) { msyslog(LOG_ERR, "open_sockets: event_new(base, sock6) failed!"); } else { event_add(ev_sock6, &wakeup_tv); } } return; }
JNIEXPORT int JNICALL NET_BindV6(struct ipv6bind* b) { int fd=-1, ofd=-1, rv, len; /* need to defer close until new sockets created */ int close_fd=-1, close_ofd=-1; SOCKETADDRESS oaddr; /* other address to bind */ int family = b->addr->him.sa_family; int ofamily; u_short port; /* requested port parameter */ u_short bound_port; if (family == AF_INET && (b->addr->him4.sin_addr.s_addr != INADDR_ANY)) { /* bind to v4 only */ int ret; ret = NET_Bind (b->ipv4_fd, (struct sockaddr *)b->addr, sizeof (struct sockaddr_in)); if (ret == SOCKET_ERROR) { CLOSE_SOCKETS_AND_RETURN; } closesocket (b->ipv6_fd); b->ipv6_fd = -1; return 0; } if (family == AF_INET6 && (!IN6_IS_ADDR_ANY(&b->addr->him6.sin6_addr))) { /* bind to v6 only */ int ret; ret = NET_Bind (b->ipv6_fd, (struct sockaddr *)b->addr, sizeof (struct SOCKADDR_IN6)); if (ret == SOCKET_ERROR) { CLOSE_SOCKETS_AND_RETURN; } closesocket (b->ipv4_fd); b->ipv4_fd = -1; return 0; } /* We need to bind on both stacks, with the same port number */ memset (&oaddr, 0, sizeof(oaddr)); if (family == AF_INET) { ofamily = AF_INET6; fd = b->ipv4_fd; ofd = b->ipv6_fd; port = (u_short)GET_PORT (b->addr); IN6ADDR_SETANY (&oaddr.him6); oaddr.him6.sin6_port = port; } else { ofamily = AF_INET; ofd = b->ipv4_fd; fd = b->ipv6_fd; port = (u_short)GET_PORT (b->addr); oaddr.him4.sin_family = AF_INET; oaddr.him4.sin_port = port; oaddr.him4.sin_addr.s_addr = INADDR_ANY; } rv = NET_Bind (fd, (struct sockaddr *)b->addr, SOCKETADDRESS_LEN(b->addr)); if (rv == SOCKET_ERROR) { CLOSE_SOCKETS_AND_RETURN; } /* get the port and set it in the other address */ len = SOCKETADDRESS_LEN(b->addr); if (getsockname(fd, (struct sockaddr *)b->addr, &len) == -1) { CLOSE_SOCKETS_AND_RETURN; } bound_port = GET_PORT (b->addr); SET_PORT (&oaddr, bound_port); if ((rv=NET_Bind (ofd, (struct sockaddr *) &oaddr, SOCKETADDRESS_LEN (&oaddr))) == SOCKET_ERROR) { int retries; int sotype, arglen=sizeof(sotype); /* no retries unless, the request was for any free port */ if (port != 0) { CLOSE_SOCKETS_AND_RETURN; } getsockopt(fd, SOL_SOCKET, SO_TYPE, (void *)&sotype, &arglen); #define SOCK_RETRIES 50 /* 50 is an arbitrary limit, just to ensure that this * cannot be an endless loop. Would expect socket creation to * succeed sooner. */ for (retries = 0; retries < SOCK_RETRIES; retries ++) { int len; close_fd = fd; fd = -1; close_ofd = ofd; ofd = -1; b->ipv4_fd = SOCKET_ERROR; b->ipv6_fd = SOCKET_ERROR; /* create two new sockets */ fd = socket (family, sotype, 0); if (fd == SOCKET_ERROR) { CLOSE_SOCKETS_AND_RETURN; } ofd = socket (ofamily, sotype, 0); if (ofd == SOCKET_ERROR) { CLOSE_SOCKETS_AND_RETURN; } /* bind random port on first socket */ SET_PORT (&oaddr, 0); rv = NET_Bind (ofd, (struct sockaddr *)&oaddr, SOCKETADDRESS_LEN(&oaddr)); if (rv == SOCKET_ERROR) { CLOSE_SOCKETS_AND_RETURN; } /* close the original pair of sockets before continuing */ closesocket (close_fd); closesocket (close_ofd); close_fd = close_ofd = -1; /* bind new port on second socket */ len = SOCKETADDRESS_LEN(&oaddr); if (getsockname(ofd, (struct sockaddr *)&oaddr, &len) == -1) { CLOSE_SOCKETS_AND_RETURN; } bound_port = GET_PORT (&oaddr); SET_PORT (b->addr, bound_port); rv = NET_Bind (fd, (struct sockaddr *)b->addr, SOCKETADDRESS_LEN(b->addr)); if (rv != SOCKET_ERROR) { if (family == AF_INET) { b->ipv4_fd = fd; b->ipv6_fd = ofd; } else { b->ipv4_fd = ofd; b->ipv6_fd = fd; } return 0; } } CLOSE_SOCKETS_AND_RETURN; } return 0; }
/* * decodenetnum convert text IP address and port to sockaddr_u * * Returns 0 for failure, 1 for success. */ int decodenetnum( const char *num, sockaddr_u *netnum ) { struct addrinfo hints, *ai = NULL; int err; u_short port; const char *cp; const char *port_str; char *pp; char *np; char name[80]; NTP_REQUIRE(num != NULL); NTP_REQUIRE(strlen(num) < sizeof(name)); port_str = NULL; if ('[' != num[0]) { /* * to distinguish IPv6 embedded colons from a port * specification on an IPv4 address, assume all * legal IPv6 addresses have at least two colons. */ pp = strchr(num, ':'); if (NULL == pp) cp = num; /* no colons */ else if (NULL != strchr(pp + 1, ':')) cp = num; /* two or more colons */ else { /* one colon */ strlcpy(name, num, sizeof(name)); cp = name; pp = strchr(cp, ':'); *pp = '\0'; port_str = pp + 1; } } else { cp = num + 1; np = name; while (*cp && ']' != *cp) *np++ = *cp++; *np = 0; if (']' == cp[0] && ':' == cp[1] && '\0' != cp[2]) port_str = &cp[2]; cp = name; } ZERO(hints); hints.ai_flags = Z_AI_NUMERICHOST; err = getaddrinfo(cp, "ntp", &hints, &ai); if (err != 0) return 0; NTP_INSIST(ai->ai_addrlen <= sizeof(*netnum)); ZERO(*netnum); memcpy(netnum, ai->ai_addr, ai->ai_addrlen); freeaddrinfo(ai); if (NULL == port_str || 1 != sscanf(port_str, "%hu", &port)) port = NTP_PORT; SET_PORT(netnum, port); return 1; }