EIBNetIPTunnel::EIBNetIPTunnel (const char *dest, int port, int sport, const char *srcip, int Dataport, int flags, Trace * tr) { t = tr; TRACEPRINTF (t, 2, this, "Open"); pth_sem_init (&insignal); pth_sem_init (&outsignal); getwait = pth_event (PTH_EVENT_SEM, &outsignal); noqueue = flags & FLAG_B_TUNNEL_NOQUEUE; sock = 0; if (!GetHostIP (&caddr, dest)) return; caddr.sin_port = htons (port); if (!GetSourceAddress (&caddr, &raddr)) return; raddr.sin_port = htons (sport); NAT = false; dataport = Dataport; sock = new EIBNetIPSocket (raddr, 0, t); if (!sock->init ()) { delete sock; sock = 0; return; } if (srcip) { if (!GetHostIP (&saddr, srcip)) { delete sock; sock = 0; return; } saddr.sin_port = htons (sport); NAT = true; } else saddr = raddr; sock->sendaddr = caddr; sock->recvaddr = caddr; sock->recvall = 0; mode = 0; vmode = 0; support_busmonitor = 1; connect_busmonitor = 0; Start (); TRACEPRINTF (t, 2, this, "Opened"); }
TEST(Env, SourceAddress) { string s = GetSourceAddress(); size_t const beg = s.find_last_of('/'); EXPECT_NE(beg, string::npos); s = s.substr(beg + 1); size_t const end = s.find_last_of(','); EXPECT_NE(end, string::npos); string const test = s.substr(0, end); EXPECT_EQ(test, "env_tests.cpp, GetSourceAddress"); ostringstream ss; ss << test << ", " << (__LINE__ - 17) << ": "; // magic constant EXPECT_EQ(s, ss.str()); }
void EIBNetIPRouter::start() { struct sockaddr_in baddr; struct ip_mreq mcfg; TRACEPRINTF (t, 2, "Open"); memset (&baddr, 0, sizeof (baddr)); #ifdef HAVE_SOCKADDR_IN_LEN baddr.sin_len = sizeof (baddr); #endif baddr.sin_family = AF_INET; baddr.sin_port = htons (port); baddr.sin_addr.s_addr = htonl (INADDR_ANY); sock = new EIBNetIPSocket (baddr, 1, t); if (!sock->init ()) goto err_out; sock->on_recv.set<EIBNetIPRouter,&EIBNetIPRouter::read_cb>(this); if (! sock->SetInterface(interface)) { ERRORPRINTF (t, E_ERROR | 58, "interface %s not recognized", interface); goto err_out; } sock->recvall = 2; if (GetHostIP (t, &sock->sendaddr, multicastaddr) == 0) goto err_out; sock->sendaddr.sin_port = htons (port); if (!GetSourceAddress (t, &sock->sendaddr, &sock->localaddr)) goto err_out; sock->localaddr.sin_port = sock->sendaddr.sin_port; mcfg.imr_multiaddr = sock->sendaddr.sin_addr; mcfg.imr_interface.s_addr = htonl (INADDR_ANY); if (!sock->SetMulticast (mcfg)) goto err_out; TRACEPRINTF (t, 2, "Opened"); BusDriver::start(); return; err_out: delete sock; sock = 0; stopped(); }
void KnxTelegram::InfoVerbose(String& str) const { byte payloadLength = GetPayloadLength(); str+= "Repeat="; str+= IsRepeated() ? "YES" : "NO"; str+="\nPrio="; switch(GetPriority()) { case KNX_PRIORITY_SYSTEM_VALUE : str+="SYSTEM"; break; case KNX_PRIORITY_ALARM_VALUE : str+="ALARM"; break; case KNX_PRIORITY_HIGH_VALUE : str+="HIGH"; break; case KNX_PRIORITY_NORMAL_VALUE : str+="NORMAL"; break; default : str+="ERR_VAL!"; break; } str+="\nSrcAddr=" + String(GetSourceAddress(),HEX); str+="\nTargetAddr=" + String(GetTargetAddress(),HEX); str+="\nGroupAddr="; if (IsMulticast()) str+= "YES"; else str+="NO"; str+="\nRout.Counter=" + String(GetRoutingCounter(),DEC); str+="\nPayloadLgth=" + String(payloadLength,DEC); str+="\nTelegramLength=" + String(GetTelegramLength(),DEC); str+="\nCommand="; switch(GetCommand()) { case KNX_COMMAND_VALUE_READ : str+="VAL_READ"; break; case KNX_COMMAND_VALUE_RESPONSE : str+="VAL_RESP"; break; case KNX_COMMAND_VALUE_WRITE : str+="VAL_WRITE"; break; case KNX_COMMAND_MEMORY_WRITE : str+="MEM_WRITE"; break; default : str+="ERR_VAL!"; break; } str+="\nPayload=" + String(GetFirstPayloadByte(),HEX)+' '; for (byte i = 0; i < payloadLength-1; i++) str+=String(_payloadChecksum[i], HEX)+' '; str+="\nValidity="; switch(GetValidity()) { case KNX_TELEGRAM_VALID : str+="VALID"; break; case KNX_TELEGRAM_INVALID_CONTROL_FIELD : str+="INVALID_CTRL_FIELD"; break; case KNX_TELEGRAM_UNSUPPORTED_FRAME_FORMAT : str+="UNSUPPORTED_FRAME_FORMAT"; break; case KNX_TELEGRAM_INCORRECT_PAYLOAD_LENGTH : str+="INCORRECT_PAYLOAD_LGTH"; break; case KNX_TELEGRAM_INVALID_COMMAND_FIELD : str+="INVALID_CMD_FIELD"; break; case KNX_TELEGRAM_UNKNOWN_COMMAND : str+="UNKNOWN_CMD"; break; case KNX_TELEGRAM_INCORRECT_CHECKSUM : str+="INCORRECT_CHKSUM"; break; default : str+="ERR_VAL!"; break; } str+='\n'; }
EIBNetIPRouter::EIBNetIPRouter (const char *multicastaddr, int port, eibaddr_t a UNUSED, Layer3 * l3, L2options *opt) : Layer2 (l3, opt) { struct sockaddr_in baddr; struct ip_mreq mcfg; TRACEPRINTF (t, 2, this, "Open"); memset (&baddr, 0, sizeof (baddr)); #ifdef HAVE_SOCKADDR_IN_LEN baddr.sin_len = sizeof (baddr); #endif baddr.sin_family = AF_INET; baddr.sin_port = htons (port); baddr.sin_addr.s_addr = htonl (INADDR_ANY); sock = new EIBNetIPSocket (baddr, 1, t); if (!sock->init ()) { delete sock; sock = 0; return; } sock->recvall = 2; if (GetHostIP (&sock->sendaddr, multicastaddr) == 0) { delete sock; sock = 0; return; } sock->sendaddr.sin_port = htons (port); if (!GetSourceAddress (&sock->sendaddr, &sock->localaddr)) return; sock->localaddr.sin_port = sock->sendaddr.sin_port; mcfg.imr_multiaddr = sock->sendaddr.sin_addr; mcfg.imr_interface.s_addr = htonl (INADDR_ANY); if (!sock->SetMulticast (mcfg)) { delete sock; sock = 0; return; } Start (); TRACEPRINTF (t, 2, this, "Opened"); }
void KnxTelegram::Info(String& str) const { byte payloadLength = GetPayloadLength(); str+="SrcAddr=" + String(GetSourceAddress(),HEX); str+="\nTargetAddr=" + String(GetTargetAddress(),HEX); str+="\nPayloadLgth=" + String(payloadLength,DEC); str+="\nCommand="; switch(GetCommand()) { case KNX_COMMAND_VALUE_READ : str+="VAL_READ"; break; case KNX_COMMAND_VALUE_RESPONSE : str+="VAL_RESP"; break; case KNX_COMMAND_VALUE_WRITE : str+="VAL_WRITE"; break; case KNX_COMMAND_MEMORY_WRITE : str+="MEM_WRITE"; break; default : str+="ERR_VAL!"; break; } str+="\nPayload=" + String(GetFirstPayloadByte(),HEX)+' '; for (byte i = 0; i < payloadLength-1; i++) str+=String(_payloadChecksum[i], HEX)+' '; str+='\n'; }
EIBnetDriver::EIBnetDriver (LinkConnectClientPtr c, std::string& multicastaddr, int port, std::string& intf) : SubDriver(c) { struct sockaddr_in baddr; struct ip_mreq mcfg; sock = 0; t->setAuxName("driver"); TRACEPRINTF (t, 8, "OpenD"); if (GetHostIP (t, &maddr, multicastaddr) == 0) { ERRORPRINTF (t, E_ERROR | 11, "Addr '%s' not resolvable", multicastaddr); goto err_out; } if (port) { maddr.sin_port = htons (port); memset (&baddr, 0, sizeof (baddr)); #ifdef HAVE_SOCKADDR_IN_LEN baddr.sin_len = sizeof (baddr); #endif baddr.sin_family = AF_INET; baddr.sin_addr.s_addr = htonl (INADDR_ANY); baddr.sin_port = htons (port); sock = new EIBNetIPSocket (baddr, 1, t); if (!sock->SetInterface(intf)) goto err_out; if (!sock->init ()) goto err_out; sock->on_recv.set<EIBnetDriver,&EIBnetDriver::recv_cb>(this); sock->on_error.set<EIBnetDriver,&EIBnetDriver::error_cb>(this); } else { EIBnetServer &parent = *std::static_pointer_cast<EIBnetServer>(server); maddr.sin_port = parent.Port; sock = parent.sock; } mcfg.imr_multiaddr = maddr.sin_addr; mcfg.imr_interface.s_addr = htonl (INADDR_ANY); if (!sock->SetMulticast (mcfg)) goto err_out; /** This causes us to ignore multicast packets sent by ourselves */ if (!GetSourceAddress (t, &maddr, &sock->localaddr)) goto err_out; sock->localaddr.sin_port = std::static_pointer_cast<EIBnetServer>(server)->Port; sock->recvall = 2; TRACEPRINTF (t, 8, "OpenedD"); return; err_out: if (sock && port) delete (sock); sock = 0; return; }
void EIBNetIPTunnel::start() { TRACEPRINTF (t, 2, "Open"); timeout.set <EIBNetIPTunnel,&EIBNetIPTunnel::timeout_cb> (this); conntimeout.set <EIBNetIPTunnel,&EIBNetIPTunnel::conntimeout_cb> (this); trigger.set <EIBNetIPTunnel,&EIBNetIPTunnel::trigger_cb> (this); trigger.start(); sock = nullptr; if (!GetHostIP (t, &caddr, dest)) goto ex; caddr.sin_port = htons (port); if (!GetSourceAddress (t, &caddr, &raddr)) goto ex; raddr.sin_port = htons (sport); NAT = false; sock = new EIBNetIPSocket (raddr, (sport != 0), t); if (!sock->init ()) goto ex; raddr.sin_port = sock->port(); sock->on_recv.set<EIBNetIPTunnel,&EIBNetIPTunnel::read_cb>(this); sock->on_error.set<EIBNetIPTunnel,&EIBNetIPTunnel::error_cb>(this); if (srcip.size()) { if (!GetHostIP (t, &saddr, srcip)) goto ex; saddr.sin_port = htons (sport); NAT = true; } else saddr = raddr; sock->sendaddr = caddr; sock->recvaddr = caddr; sock->recvall = 0; support_busmonitor = true; connect_busmonitor = false; { EIBnet_ConnectRequest creq = get_creq(); EIBNetIPPacket p = creq.ToPacket (); sock->sendaddr = caddr; sock->Send (p); } conntimeout.start(CONNECT_REQUEST_TIMEOUT,0); TRACEPRINTF (t, 2, "Opened"); out.clear(); return; ex: if (sock) { delete sock; sock = nullptr; } is_stopped(); stopped(); }
int main (int ac, char *ag[]) { int tracelevel; int sport; int dport; char *a, *b, *c; if (ac != 2 && ac != 3) die ("Usage: %s ip[:dst-port[:src-port]] [tracelevel]", ag[0]); struct sockaddr_in saddr; struct sockaddr_in caddr; EIBNetIPSocket *sock; ev_timer timeout; ev_timer_init(&timeout, &end_me, 10.,0.); ev_timer_start(EV_DEFAULT_ &timeout); tracelevel = 0; if (ac == 3) tracelevel = atoi (ag[2]); a = strdup (ag[1]); if (!a) die ("out of memory"); for (b = a; *b; b++) if (*b == ':') break; sport = 3672; if (*b == ':') { *b = 0; for (c = b + 1; *c; c++) if (*c == ':') break; if (*c == ':') { *c = 0; sport = atoi (c + 1); } dport = atoi (b + 1); } else dport = 3671; std::string edesc = "eibnetdescribe"; Trace t = Trace(edesc, "main"); t.SetTraceLevel (tracelevel); printf ("Asking %s at port %d from port %d\n", a, dport, sport); if (!GetHostIP (NULL, &caddr, a)) die ("Host not found"); caddr.sin_port = htons (dport); if (!GetSourceAddress (TracePtr(new Trace(t,a)), &caddr, &saddr)) die ("No route found"); saddr.sin_port = htons (sport); sock = new EIBNetIPSocket (saddr, 0, TracePtr(new Trace(t,a))); sock->sendaddr = caddr; sock->recvaddr = caddr; if (!sock->init ()) die ("IP initialisation failed"); EIBnet_DescriptionRequest req; EIBNetIPPacket *p1; req.caddr = saddr; sock->on_read.set<recv_me>(); sock->Send (req.ToPacket ()); ev_run (EV_DEFAULT_ 0); return 0; }