static int bfddMain(int argc, char *argv[]) { int argIndex; SockAddr connectAddr; const char *valueString; //gLog.LogToFile("/tmp/bfd.log"); UtilsInit(); gLog.LogToSyslog("bfdd-control", false); gLog.Optional(Log::App, "Startup %x", getpid()); //Parse command line options for (argIndex = 1; argIndex < argc; argIndex++) { if (0 == strcmp("--altport", argv[argIndex])) { if (connectAddr.IsValid()) { fprintf(stderr, "Only a single --altport or --control option is allowed.\n"); exit(1); } // Backwards compatability only ... use --control connectAddr.FromString("127.0.0.1", ALT_PORTNUM); } else if (CheckArg("--control", argv[argIndex], &valueString)) { if (!valueString || *valueString == '\0') { fprintf(stderr, "--control must be followed by an '=' and a ip address with a port.\n"); exit(1); } if (!connectAddr.FromString(valueString)) { fprintf(stderr, "--control address <%s> is not an IPv4 or IPv6 address.\n", valueString); exit(1); } if (!connectAddr.HasPort()) { fprintf(stderr, "--control address must have a port specified. The address <%s> does not conatin a port.\n", valueString); exit(1); } } else if (0 == strncmp("--", argv[argIndex], 2)) { fprintf(stderr, "Unrecognized %s command line option %s.\n", ControlAppName, argv[argIndex]); exit(1); } else break; } if (argIndex >= argc) { fprintf(stderr, "No command. Try \"man %s\" for a list of commands.\n", ControlAppName); exit(1); } // "version" is special because we tell first. Than lest the beacon handle it. if (0 == strcmp(argv[argIndex], "version")) { fprintf(stdout, "%s v%s\n", ControlAppName, SofwareVesrion); } if (!connectAddr.IsValid()) connectAddr.FromString("127.0.0.1", PORTNUM); // "load" is special because we send a series of commands.. if (0 == strcmp(argv[argIndex], "load")) { argIndex++; if (argIndex >= argc) { fprintf(stderr, "Must supply a script file after 'load'\n"); exit(1); } fprintf(stdout, "Running script from file <%s>\n", argv[argIndex]); if (!doLoadScript(argv[argIndex], connectAddr)) { fprintf(stderr, "Script load failed.\n"); exit(1); } fprintf(stdout, "Completed script from file <%s>\n", argv[argIndex]); exit(0); } // To allow for quotes, we concatenate all the arguments, separating them with // "NULL". vector<char> buffer; buffer.reserve(MaxCommandSize); for (; argIndex < argc; argIndex++) { AddParamToBuffer(buffer, argv[argIndex]); } if (buffer.size() == 0) { fprintf(stderr, "No command. Try \"man %s\" for a list of commands.\n", ControlAppName); exit(1); } // argIndex is double null terminated. buffer.push_back('\0'); if (!SendData(&buffer.front(), buffer.size(), connectAddr)) exit(1); exit(0); }
void Beacon::handleListenSocket(Socket &socket) { SockAddr sourceAddr; IpAddr destIpAddr, sourceIpAddr; uint8_t ttl; BfdPacket packet; bool found; Session *session = NULL; if (!m_packet.DoRecvMsg(socket)) { gLog.ErrnoError(m_packet.GetLastError(), "Error receiving on BFD listen socket"); return; } sourceAddr = m_packet.GetSrcAddress(); if (!LogVerify(sourceAddr.IsValid())) return; sourceIpAddr = IpAddr(sourceAddr); destIpAddr = m_packet.GetDestAddress(); if (!destIpAddr.IsValid()) { gLog.LogError("Could not get destination address for packet from %s.", sourceAddr.ToString()); return; } ttl = m_packet.GetTTLorHops(&found); if (!found) { gLog.LogError("Could not get ttl for packet from %s.", sourceAddr.ToString()); return; } LogOptional(Log::Packet, "Received bfd packet %zu bytes from %s to %s", m_packet.GetDataSize(), sourceAddr.ToString(), destIpAddr.ToString()); // // Check ip specific stuff. See draft-ietf-bfd-v4v6-1hop-11.txt // // Port if (m_strictPorts) { if (sourceAddr.Port() < bfd::MinSourcePort) // max port is max value, so no need to check { LogOptional(Log::Discard, "Discard packet: bad source port %s to %s", sourceAddr.ToString(), destIpAddr.ToString()); return; } } // TTL assumes that all control packets are from neighbors. if (ttl != 255) { gLog.Optional(Log::Discard, "Discard packet: bad ttl/hops %hhu", ttl); return; } if (!Session::InitialProcessControlPacket(m_packet.GetData(), m_packet.GetDataSize(), packet)) { gLog.Optional(Log::Discard, "Discard packet"); return; } // We have a (partially) valid packet ... now find the correct session. if (packet.header.yourDisc != 0) { DiscMapIt found = m_discMap.find(packet.header.yourDisc); if (found == m_discMap.end()) { if (gLog.LogTypeEnabled(Log::DiscardDetail)) Session::LogPacketContents(packet, false, true, sourceAddr, destIpAddr); gLog.Optional(Log::Discard, "Discard packet: no session found for yourDisc <%u>.", packet.header.yourDisc); return; } session = found->second; if (session->GetRemoteAddress() != sourceIpAddr) { if (gLog.LogTypeEnabled(Log::DiscardDetail)) Session::LogPacketContents(packet, false, true, sourceAddr, destIpAddr); LogOptional(Log::Discard, "Discard packet: mismatched yourDisc <%u> and ip <from %s to %s>.", packet.header.yourDisc, sourceAddr.ToString(), destIpAddr.ToString()); return; } } else { // No discriminator session = findInSourceMap(sourceIpAddr, destIpAddr); if (NULL == session) { // No session yet .. create one !? if (!m_allowAnyPassiveIP && m_allowedPassiveIP.find(sourceIpAddr) == m_allowedPassiveIP.end()) { if (gLog.LogTypeEnabled(Log::DiscardDetail)) Session::LogPacketContents(packet, false, true, sourceAddr, destIpAddr); LogOptional(Log::Discard, "Ignoring unauthorized bfd packets from %s", sourceAddr.ToString()); return; } session = addSession(sourceIpAddr, destIpAddr); if (!session) return; if (!session->StartPassiveSession(sourceAddr, destIpAddr)) { gLog.LogError("Failed to add new session for local %s to remote %s id=%d.", destIpAddr.ToString(), sourceAddr.ToString(), session->GetId()); KillSession(session); } LogOptional(Log::Session, "Added new session for local %s to remote %s id=%d.", destIpAddr.ToString(), sourceAddr.ToString(), session->GetId()); } } // // We have a session that can handle the rest. // session->ProcessControlPacket(packet, sourceAddr.Port()); }