IpfixReceiverDtlsSctpIpV4(int port, const std::string ipAddr = "", const std::string &certificateChainFile = "", const std::string &privateKeyFile = "", const std::string &caFile = "", const std::string &caPath = "", const std::set<string> &peerFqdns = std::set<string>(), const uint32_t buffer = 0) { THROWEXCEPTION("DTLS over SCTP not supported!"); }
IDSLoadbalancerCfg::IDSLoadbalancerCfg(XMLElement* elem) : CfgHelper<IDSLoadbalancer, IDSLoadbalancerCfg>(elem, "IDSLoadbalancer"), selector(NULL), updateInterval(0) { if (!elem) return; XMLNode::XMLSet<XMLElement*> set = elem->getElementChildren(); for (XMLNode::XMLSet<XMLElement*>::iterator it = set.begin(); it != set.end(); it++) { XMLElement* e = *it; if (e->matches("updateinterval")) { updateInterval = getInt("updateinterval", 0, e); } else if (e->matches("PacketSelector")) { XMLAttribute *a = e->getAttribute("type"); if (!a) THROWEXCEPTION("no PacketSelector specified"); string _selector = a->getValue(); if (_selector == "HashPacketSelector") { if (!selector) { selector = new HashPacketSelector(); } else THROWEXCEPTION("IDSLoadBalancerCfg: multiple packet selectors specified! This is not allowed."); } else if (_selector == "IpPacketSelector") { msg(MSG_DEBUG, "IpPacketSelector"); XMLNode::XMLSet<XMLElement*> set = e->getElementChildren(); for (XMLNode::XMLSet<XMLElement*>::iterator it = set.begin(); it != set.end(); it++) { XMLElement* e = *it; if (e->matches("DestinationIp")){ XMLAttribute *a = e->getAttribute("queueno"); if (!a) THROWEXCEPTION("No queue number specified"); int queueno = 0; std::string tmp = a->getValue(); try { queueno = boost::lexical_cast<int>(tmp); }catch (boost::bad_lexical_cast &){ THROWEXCEPTION("bad value for queue number: %s", tmp.c_str()); } std::string ip = e->getFirstText(); dst[parseIp(ip)] = queueno; }else if (e->matches("SourceIp")){ XMLElement* e = *it; XMLAttribute *a = e->getAttribute("queueno"); if (!a) THROWEXCEPTION("No queue number specified"); int queueno = 0; std::string tmp = a->getValue(); try { queueno = boost::lexical_cast<int>(tmp); }catch (boost::bad_lexical_cast &){ THROWEXCEPTION("bad value for queue number: %s", tmp.c_str()); } std::string ip = e->getFirstText(); src[parseIp(ip)] = queueno; } } if (!selector) { selector = new IpPacketSelector(); if (src.empty() && dst.empty()) THROWEXCEPTION("IDSLoadBalancerCfg: packet selector IpPacketSelector was defined, but no source or destination IPs!"); } else THROWEXCEPTION("IDSLoadBalancerCfg: multiple packet selectors specified! This is not allowed."); } else if (_selector == "PriorityPacketSelector") { float startprio = getDouble("startPriority", 1.0, e); uint32_t minmontime = getInt("minimumMonitoringTime", 10000, e); uint32_t maxspeed = getInt("maxSpeed", 0, e); list<PriorityNetConfig> config; list<WeightModifierConfig> weightmods; XMLNode::XMLSet<XMLElement*> set = e->getElementChildren(); for (XMLNode::XMLSet<XMLElement*>::iterator it = set.begin(); it != set.end(); it++) { XMLElement* e = *it; if (e->matches("networks")) { XMLNode::XMLSet<XMLElement*> netset = e->getElementChildren(); for (XMLNode::XMLSet<XMLElement*>::iterator nit = netset.begin(); nit != netset.end(); nit++) { XMLElement* e = *nit; if (e->matches("network")) { XMLAttribute* a = e->getAttribute("address"); if (!a) THROWEXCEPTION("IDSLoadBalancerCfg: no attribute 'address' in configuration element 'network'!"); string cidr = a->getFirstText(); size_t pos = cidr.find("/"); string ip = cidr.substr(0, pos); string sbits = cidr.substr(pos+1); int maskbits = atoi(sbits.c_str()); if (maskbits<0 || maskbits>32) THROWEXCEPTION("IDSLoadBalancerCfg: attribute 'address' has invalid number of mask bits in configuration (%s)!", sbits.c_str()); in_addr_t ipaddr = inet_addr(ip.c_str()); if (ipaddr==(in_addr_t)-1) THROWEXCEPTION("IDSLoadBalancerCfg: attribute 'address' has invalid ip subnet in configuration (%s)!", ip.c_str()); a = e->getAttribute("weight"); if (!a) THROWEXCEPTION("IDSLoadBalancerCfg: no attribute 'weight' in configuration element 'network'!"); char* res; float weight = strtof(a->getFirstText().c_str(), &res); if (weight<=0 || res==a->getFirstText().c_str()) THROWEXCEPTION("IDSLoadBalancerCfg: attribute 'weight' in configuration element 'network' contains invalid value (%s)!", a->getFirstText().c_str()); config.push_back(PriorityNetConfig(ntohl((uint32_t)ipaddr), ((1<<(32-maskbits))-1)^0xFFFFFFFF, maskbits, weight)); } } } if (e->matches("weightModifiers")) { XMLNode::XMLSet<XMLElement*> netset = e->getElementChildren(); for (XMLNode::XMLSet<XMLElement*>::iterator nit = netset.begin(); nit != netset.end(); nit++) { XMLElement* e = *nit; if (e->matches("traffic")) { XMLAttribute* a = e->getAttribute("quantile"); if (!a) THROWEXCEPTION("IDSLoadBalancerCfg: no attribute 'quantile' in configuration element 'traffic'!"); char* res; float quantile = strtof(a->getFirstText().c_str(), &res); if (quantile<=0 || quantile>1 || res==a->getFirstText().c_str()) THROWEXCEPTION("IDSLoadBalancerCfg: attribute 'quantile' is not in expected range (0<x<=1): %s", a->getFirstText().c_str()); a = e->getAttribute("weightModifier"); if (!a) THROWEXCEPTION("IDSLoadBalancerCfg: no attribute 'weightModifier' in configuration element 'traffic'!"); float weightmod = strtof(a->getFirstText().c_str(), &res); if (weightmod<=0 || res==a->getFirstText().c_str()) THROWEXCEPTION("IDSLoadBalancerCfg: attribute 'weightModifier' is not in expected range (0<x): %s", a->getFirstText().c_str()); weightmods.push_back(WeightModifierConfig(quantile, weightmod)); } } } } if (!selector) { struct timeval tv; tv.tv_sec = minmontime/1000; tv.tv_usec = (minmontime%1000)*1000; // sort the network configuration by decreasing maskbits config.sort(compareDecrMask); selector = new PriorityPacketSelector(config, startprio, tv, maxspeed, weightmods); } else THROWEXCEPTION("IDSLoadBalancerCfg: multiple packet selectors specified! This is not allowed."); } else { THROWEXCEPTION("Invalid selector: %s", _selector.c_str()); } } } if (!selector) THROWEXCEPTION("IDSLoadBalancerCfg: No packet selector specified, this is compulsory"); }
AnonPrimitive* AnonModule::createPrimitive(AnonMethod::Method m, const std::string& parameter, std::vector<map_info> mapping) { AnonPrimitive* ret = 0; char buffer[32]; char c; bool isHex = isHexString(parameter); switch (m) { case AnonMethod::HashSha1: ret = new AnonHashSha1(); break; case AnonMethod::BytewiseHashSha1: ret = new AnonBytewiseHashSha1(); break; case AnonMethod::ContinuousChar: ret = new AnonContinuousChar(); break; case AnonMethod::Randomize: ret = new AnonRandomize(); break; case AnonMethod::Shuffle: ret = new AnonShuffle(); break; case AnonMethod::Whitenoise: ret = new AnonWhitenoise(atoi(parameter.c_str())); break; case AnonMethod::HashHmacSha1: ret = new AnonHashHmacSha1(parameter); break; case AnonMethod::BytewiseHashHmacSha1: ret = new AnonBytewiseHashHmacSha1(parameter); break; case AnonMethod::ConstOverwrite: if (parameter.size() != 1 || (isHex && parameter.size() != 4)) { THROWEXCEPTION("AnonConstOverwrite only uses one character as key"); } c = parameter.c_str()[0]; if (isHex) { if (convHexToBinary(parameter, &c, 1)!=1) { THROWEXCEPTION("Failed to convert hexadecimal key parameter '%s' to binary (one byte required)!", parameter.c_str()); } } ret = new AnonConstOverwrite(parameter.c_str()[0]); break; case AnonMethod::CryptoPan: if (parameter.length()!=32) if (isHex && parameter.length() != 66) THROWEXCEPTION("CryptoPAN key *MUST* have exactly 32 characters!"); if (isHex) { if (convHexToBinary(parameter, buffer, 32)!=32) { THROWEXCEPTION("Failed to convert hexadecimal key parameter '%s' to binary (32 bytes required)!", parameter.c_str()); } } else { memcpy(buffer, parameter.c_str(), 32); } ret = new AnonCryptoPan(buffer); break; case AnonMethod::CryptoPanPrefix: if (parameter.length()!=32) if (isHex && parameter.length() != 66) THROWEXCEPTION("CryptoPAN key *MUST* have exactly 32 characters!"); if (isHex) { if (convHexToBinary(parameter, buffer, 32)!=32) { THROWEXCEPTION("Failed to convert hexadecimal key parameter '%s' to binary (32 bytes required)!", parameter.c_str()); } } else { memcpy(buffer, parameter.c_str(), 32); } ret = new AnonCryptoPanPrefix(buffer, mapping); break; default: msg(MSG_FATAL, "AnonPrimitive number %i is unknown", m); THROWEXCEPTION("AnonPrimitive number %i is unknown", m); } return ret; }
/** * Takes an IPFIX record, and tries to create a single packet for the record (two packets if it is bidirectional) * Payload of the packet is contained in the FPA payload field of the flow * This is done by using two prepared buffers that contain a UDP and TCP header stack (tcpHeader and udpHeader) * ATTENTION: checksums are not calculated at all, as well as other TCP header fields that are connection specific */ void FpaPcapExporter::onDataRecord(IpfixDataRecord* record) { // only treat non-Options Data Records (although we cannot be sure that there is a Flow inside) if((record->templateInfo->setId != TemplateInfo::NetflowTemplate) && (record->templateInfo->setId != TemplateInfo::IpfixTemplate) && (record->templateInfo->setId != TemplateInfo::IpfixDataTemplate)) { record->removeReference(); return; } Connection c(record); pcaprec_hdr_t pcaphdr; bzero(&pcaphdr, sizeof(pcaphdr)); //pcaphdr.ts_sec = 0; // FIXME: here we should use timestamp contained in IPFIX record //pcaphdr.ts_usec = 0 // see above! if (c.protocol==6) { uint16_t totlen = sizeof(tcpHeader)+c.srcPayloadLen; if (totlen>snaplen) totlen = snaplen; if (c.srcPayloadLen>0) { // copy normal direction tcpHeader.ip.tot_len = htons(totlen-sizeof(tcpHeader.ether)); pcaphdr.incl_len = totlen; pcaphdr.orig_len = totlen; tcpHeader.ip.saddr = c.srcIP; tcpHeader.ip.daddr = c.dstIP; tcpHeader.tcp.source = c.srcPort; tcpHeader.tcp.dest = c.dstPort; if (fwrite(&pcaphdr, sizeof(pcaphdr), 1, pcapfile)!=1) { THROWEXCEPTION("FpaPcapExporter: Failed to write packet header to file %s, error: %s", fileName.c_str(), strerror(errno)); } if (fwrite(&tcpHeader, sizeof(tcpHeader), 1, pcapfile)!=1) { THROWEXCEPTION("FpaPcapExporter: Failed to write packet tcp header to file %s, error: %s", fileName.c_str(), strerror(errno)); } if (fwrite(c.srcPayload, totlen-sizeof(tcpHeader), 1, pcapfile)!=1) { THROWEXCEPTION("FpaPcapExporter: Failed to write tcp packet payload to file %s, error: %s", fileName.c_str(), strerror(errno)); } } totlen = sizeof(tcpHeader)+c.dstPayloadLen; if (totlen>snaplen) totlen = snaplen; if (c.dstPayloadLen>0) { // copy reverse direction tcpHeader.ip.tot_len = htons(totlen-sizeof(tcpHeader.ether)); pcaphdr.incl_len = totlen; pcaphdr.orig_len = totlen; tcpHeader.ip.saddr = c.dstIP; tcpHeader.ip.daddr = c.srcIP; tcpHeader.tcp.source = c.dstPort; tcpHeader.tcp.dest = c.srcPort; if (fwrite(&pcaphdr, sizeof(pcaphdr), 1, pcapfile)!=1) { THROWEXCEPTION("FpaPcapExporter: Failed to write packet header to file %s, error: %s", fileName.c_str(), strerror(errno)); } if (fwrite(&tcpHeader, sizeof(tcpHeader), 1, pcapfile)!=1) { THROWEXCEPTION("FpaPcapExporter: Failed to write packet tcp header to file %s, error: %s", fileName.c_str(), strerror(errno)); } if (fwrite(c.dstPayload, totlen-sizeof(tcpHeader), 1, pcapfile)!=1) { THROWEXCEPTION("FpaPcapExporter: Failed to write tcp packet payload to file %s, error: %s", fileName.c_str(), strerror(errno)); } } } else if (c.protocol==17) { uint16_t totlen = sizeof(udpHeader)+c.srcPayloadLen; if (totlen>snaplen) totlen = snaplen; if (c.srcPayloadLen>0) { // copy normal direction udpHeader.ip.tot_len = htons(totlen-sizeof(udpHeader.ether)); pcaphdr.incl_len = totlen; pcaphdr.orig_len = totlen; udpHeader.ip.saddr = c.srcIP; udpHeader.ip.daddr = c.dstIP; udpHeader.udp.source = c.srcPort; udpHeader.udp.dest = c.dstPort; udpHeader.udp.len = htons(totlen-sizeof(udpHeader)+sizeof(udpHeader.udp)); if (fwrite(&pcaphdr, sizeof(pcaphdr), 1, pcapfile)!=1) { THROWEXCEPTION("FpaPcapExporter: Failed to write packet header to file %s, error: %s", fileName.c_str(), strerror(errno)); } if (fwrite(&udpHeader, sizeof(udpHeader), 1, pcapfile)!=1) { THROWEXCEPTION("FpaPcapExporter: Failed to write packet udp header to file %s, error: %s", fileName.c_str(), strerror(errno)); } if (fwrite(c.srcPayload, totlen-sizeof(udpHeader), 1, pcapfile)!=1) { THROWEXCEPTION("FpaPcapExporter: Failed to write udp packet payload to file %s, error: %s", fileName.c_str(), strerror(errno)); } } totlen = sizeof(udpHeader)+c.dstPayloadLen; if (totlen>snaplen) totlen = snaplen; if (c.dstPayloadLen>0) { // copy reverse direction udpHeader.ip.tot_len = htons(totlen-sizeof(udpHeader.ether)); pcaphdr.incl_len = totlen; pcaphdr.orig_len = totlen; udpHeader.ip.saddr = c.dstIP; udpHeader.ip.daddr = c.srcIP; udpHeader.udp.source = c.dstPort; udpHeader.udp.dest = c.srcPort; udpHeader.udp.len = htons(totlen-sizeof(udpHeader)+sizeof(udpHeader.udp)); if (fwrite(&pcaphdr, sizeof(pcaphdr), 1, pcapfile)!=1) { THROWEXCEPTION("FpaPcapExporter: Failed to write packet header to file %s, error: %s", fileName.c_str(), strerror(errno)); } if (fwrite(&udpHeader, sizeof(udpHeader), 1, pcapfile)!=1) { THROWEXCEPTION("FpaPcapExporter: Failed to write packet udp header to file %s, error: %s", fileName.c_str(), strerror(errno)); } if (fwrite(c.dstPayload, totlen-sizeof(udpHeader), 1, pcapfile)!=1) { THROWEXCEPTION("FpaPcapExporter: Failed to write udp packet payload to file %s, error: %s", fileName.c_str(), strerror(errno)); } } } record->removeReference(); }
/** * Starts the command given in 'cmd' * STDOUT and STDERR of 'cmd' may be redirected into a file, see * module_configuration.txt for details * */ int PCAPExporterMem::execCmd(std::string& cmd) { int child_parent_pipe[2]; char *command[64]; int i=0; std::vector<std::string> tokens; parseCommandLine(cmd, tokens); for (std::vector<std::string>::iterator it = tokens.begin(); it!=tokens.end(); it++) { command[i++] = const_cast<char*>(it->c_str()); if(i>62) THROWEXCEPTION("Argument list too long"); } command[i] = (char*)NULL; if (pipe(child_parent_pipe)) { THROWEXCEPTION("pipe(child_parent_pipe) failed with error code %u (%s)", errno, strerror(errno)); } /* Create a pipe, which allows communication between the child and the parent. * Writing an int value (e.g. errno) into child_parent_pipe[1] * will cause an exception in the parent process. * Throwing exceptions in the child *will not* terminate Vermont! */ for (int i=0; i<2; i++) { int oldflags = fcntl (child_parent_pipe[i], F_GETFD, 0); if(-1 == oldflags) THROWEXCEPTION("fctnl: %s", strerror(errno)); oldflags |= FD_CLOEXEC; if (-1 == fcntl (child_parent_pipe[i], F_SETFD, oldflags)) THROWEXCEPTION("fctnl: %s", strerror(errno)); } int pid = fork(); if (pid == 0) { // child process close(child_parent_pipe[0]); // close read-end if (workingPath != "") { int res = chdir(workingPath.c_str()); if (res != 0) { THROWEXCEPTION("failed to change to working path '%s'", workingPath.c_str()); exit(1); } } redirectLogfile(); if (execvp(command[0], command)<0) { if (write(child_parent_pipe[1], &errno, sizeof(int)) != sizeof(int)) THROWEXCEPTION("exec failed"); //throw the exception only if we couldn't //tell the parent that sth. went wrong... exit(1); } } else if (pid > 0) { close(child_parent_pipe[1]); int buf; if (read(child_parent_pipe[0], &buf, sizeof(int)) == sizeof(int)) { //The child actually wrote errno into the pipe THROWEXCEPTION("An error occurred in the child: %s", strerror(buf)); } close(child_parent_pipe[0]); return pid; } else { THROWEXCEPTION("fork() failed"); } return -1; }
/** * DTLS over SCTP specific listener function. This function is called by @c listenerThread() */ void IpfixReceiverDtlsSctpIpV4::run() { struct sockaddr_in clientAddress; socklen_t clientAddressLen = sizeof(struct sockaddr_in); int ret; int rfd; struct timespec timeOut; /* set a 400ms time-out on the pselect */ timeOut.tv_sec = 0L; timeOut.tv_nsec = 400000000L; while(!exitFlag) { fd_set tmpreadfds = readfds; fd_set tmpwritefds = writefds; ret = pselect(maxfd + 1, &tmpreadfds, &tmpwritefds, NULL, &timeOut, NULL); if (ret == 0) { /* Timeout */ continue; } if ((ret == -1) && (errno == EINTR)) { DPRINTF("select() returned due to signal"); /* There was a signal... ignore */ continue; } if (ret < 0) { msg(MSG_ERROR ,"select() returned with an error: %s",strerror(errno)); THROWEXCEPTION("IpfixReceiverDtlsSctpIpV4: terminating listener thread"); break; } DPRINTF("select() returned %d",ret); // looking for a new client to connect at listen_socket if (FD_ISSET(listen_socket, &tmpreadfds)){ rfd = accept(listen_socket, (struct sockaddr*)&clientAddress, &clientAddressLen); if (rfd >= 0){ if ( ! isHostAuthorized(&clientAddress.sin_addr, sizeof(clientAddress.sin_addr))) { /* Do not accept connections from unauthorized hosts. */ close(rfd); } else { msg(MSG_DEBUG, "IpfixReceiverDtlsSctpIpV4: Client connected from %s:%d, FD=%d", inet_ntoa(clientAddress.sin_addr), ntohs(clientAddress.sin_port), rfd); DtlsConnectionPtr conn = DtlsConnectionPtr( new DtlsConnection(*this,&clientAddress,rfd)); connections.insert(make_pair(rfd,conn)); update_maxfd(); } }else{ msg(MSG_ERROR ,"accept() in ipfixReceiver failed"); /* TODO: Don't throw an exception here. */ THROWEXCEPTION("IpfixReceiverDtlsSctpIpV4: unable to accept new connection"); } } // check all connected sockets for new available data for (rfd = 0; rfd <= maxfd; ++rfd) { if (rfd == listen_socket) continue; if (FD_ISSET(rfd, &readfds) || FD_ISSET(rfd, &writefds)) { if (FD_ISSET(rfd, &readfds)) DPRINTF("descriptor %d is ready for reading",rfd); if (FD_ISSET(rfd, &writefds)) DPRINTF("descriptor %d is ready for writing",rfd); connections_map::iterator it = connections.find(rfd); if (it == connections.end()) { /* This should not happend. */ msg(MSG_ERROR,"Can't find connection for file descriptor."); FD_CLR(rfd,&readfds); FD_CLR(rfd,&writefds); continue; } ret = it->second->fdready(); if (ret == 0) { DPRINTF("fdready() returned 0. Deleting connection."); remove_connection(rfd); update_maxfd(); } } } } msg(MSG_DEBUG, "IpfixReceiverDtlsSctpIpV4: Exiting"); }
/** * Does DTLS over SCTP/IPv4 specific initialization. * @param port Port to listen on */ IpfixReceiverDtlsSctpIpV4::IpfixReceiverDtlsSctpIpV4(int port, const std::string ipAddr, const std::string &certificateChainFile, const std::string &privateKeyFile, const std::string &caFile, const std::string &caPath, const std::set<string> &peerFqdnsParam) : IpfixReceiver(port),ssl_ctx(certificateChainFile,privateKeyFile,caFile,caPath, ! peerFqdnsParam.empty()),listen_socket(-1),maxfd(0), peerFqdns(peerFqdnsParam), statReceivedPackets(0) { struct sockaddr_in serverAddress; struct sctp_event_subscribe ses; int flags; /* FIXME: make error messages consistent with IpfixReceiverDtlsUdpIpV4 */ try { listen_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP); if(listen_socket < 0) { /* FIXME: should we use strerror_r? */ msg(MSG_FATAL, "socket creation failed: %s", strerror(errno)); THROWEXCEPTION("Cannot create IpfixReceiverDtlsSctpIpV4, socket creation failed: %s", strerror(errno)); } /* set socket to non-blocking i/o */ flags = fcntl(listen_socket,F_GETFL,0); flags |= O_NONBLOCK; if (fcntl(listen_socket,F_SETFL,flags)<0) { THROWEXCEPTION("IPFIX: Failed to set socket to non-blocking i/o"); } // if ipAddr set: Bind a specific IP address to our socket. // else: use wildcard address if(ipAddr.empty()) serverAddress.sin_addr.s_addr = htonl(INADDR_ANY); else if ( ! inet_pton(AF_INET,ipAddr.c_str(),&serverAddress.sin_addr) ) { THROWEXCEPTION("IP address invalid."); } serverAddress.sin_family = AF_INET; serverAddress.sin_port = htons(port); if(bind(listen_socket, (struct sockaddr*)&serverAddress, sizeof(struct sockaddr_in)) < 0) { msg(MSG_FATAL, "Cannot bind socket: %s", strerror(errno)); THROWEXCEPTION("Cannot create IpfixReceiverDtlsSctpIpV4 %s:%d",ipAddr.c_str(), port ); } if(listen(listen_socket, SCTP_MAX_BACKLOG) < 0 ) { msg(MSG_FATAL, "Can not listen socket: %s", strerror(errno)); THROWEXCEPTION("Cannot create IpfixReceiverDtlsSctpIpV4 %s:%d",ipAddr.c_str(), port ); } msg(MSG_INFO, "SCTP Receiver listening on %s:%d, FD=%d", (ipAddr == "")?std::string("ALL").c_str() : ipAddr.c_str(), port, listen_socket); memset(&ses, 0, sizeof(ses)); ses.sctp_data_io_event = 1; if ( setsockopt(listen_socket, IPPROTO_SCTP, SCTP_EVENTS, &ses, sizeof(ses))) { msg(MSG_FATAL, "setsockopt() failed: %s", strerror(errno)); THROWEXCEPTION("Cannot create IpfixReceiverDtlsSctpIpV4 %s:%d",ipAddr.c_str(), port ); } /* BIO_new_dgram_sctp sets the necessary socket options on listen_socket. * This includes activating SCTP-AUTH and subscribing to all necessary events. * We can delete this BIO right after because we're only calling it for the * side effects on listen_socket. */ BIO_free(BIO_new_dgram_sctp(listen_socket, BIO_NOCLOSE)); FD_ZERO(&readfds); FD_ZERO(&writefds); FD_SET(listen_socket,&readfds); update_maxfd(); /* TODO: Find out what this is? */ SensorManager::getInstance().addSensor(this, "IpfixReceiverDtlsSctpIpV4", 0); msg(MSG_INFO, "DTLS over SCTP Receiver listening on %s:%d, FD=%d", (ipAddr == "")?std::string("ALL").c_str() : ipAddr.c_str(), port, listen_socket); } catch(...) { if (listen_socket>=0) { close(listen_socket); listen_socket = -1; } throw; // rethrow } }
/** * SCTP specific listener function. This function is called by @c listenerThread() */ void IpfixReceiverSctpIpV4::run() { struct sockaddr_in clientAddress; socklen_t clientAddressLen; clientAddressLen = sizeof(struct sockaddr_in); fd_set fd_array; //all active filedescriptors int maxfd; FD_ZERO(&fd_array); FD_SET(listen_socket, &fd_array); // add listensocket maxfd = listen_socket; fd_set readfds; int ret; int rfd; while(!exit) { readfds = fd_array; // because select() changes readfds ret = select(maxfd + 1, &readfds, NULL, NULL, NULL); // check only for something to read if ((ret == -1) && (errno == EINTR)) { /* There was a signal... ignore */ continue; } if (ret < 0) { msg(MSG_ERROR ,"select() returned with an error"); THROWEXCEPTION("IpfixReceiverSctpIpV4: terminating listener thread"); break; } // looking for a new client to connect at listen_socket if (FD_ISSET(listen_socket, &readfds)){ rfd = accept(listen_socket, (struct sockaddr*)&clientAddress, &clientAddressLen); if (rfd >= 0){ FD_SET(rfd, &fd_array); // add new client to fd_array msg(MSG_DEBUG, "IpfixReceiverSctpIpV4: Client connected from %s:%d, FD=%d", inet_ntoa(clientAddress.sin_addr), ntohs(clientAddress.sin_port), rfd); if (rfd > maxfd){ maxfd = rfd; } }else{ msg(MSG_ERROR ,"accept() in ipfixReceiver failed"); THROWEXCEPTION("IpfixReceiverSctpIpV4: unable to accept new connection"); } } // check all connected sockets for new available data for (rfd = listen_socket + 1; rfd <= maxfd; ++rfd) { if (FD_ISSET(rfd, &readfds)) { boost::shared_array<uint8_t> data(new uint8_t[MAX_MSG_LEN]); ret = recvfrom(rfd, data.get(), MAX_MSG_LEN, 0, (struct sockaddr*)&clientAddress, &clientAddressLen); if (ret == 0) { // shut down initiated FD_CLR(rfd, &fd_array); // delete dead client msg(MSG_DEBUG, "IpfixReceiverSctpIpV4: Client disconnected"); }else{ if (isHostAuthorized(&clientAddress.sin_addr, sizeof(clientAddress.sin_addr))) { boost::shared_ptr<IpfixRecord::SourceID> sourceID(new IpfixRecord::SourceID); memcpy(sourceID->exporterAddress.ip, &clientAddress.sin_addr.s_addr, 4); sourceID->exporterAddress.len = 4; sourceID->exporterPort = ntohs(clientAddress.sin_port); sourceID->protocol = IPFIX_protocolIdentifier_SCTP; sourceID->receiverPort = receiverPort; sourceID->fileDescriptor = rfd; pthread_mutex_lock(&mutex); for (std::list<IpfixPacketProcessor*>::iterator i = packetProcessors.begin(); i != packetProcessors.end(); ++i) { (*i)->processPacket(data, ret, sourceID); } pthread_mutex_unlock(&mutex); } else{ msg(MSG_DEBUG, "packet from unauthorized host %s discarded", inet_ntoa(clientAddress.sin_addr)); } } } } } }
void IpfixPayloadWriter::dumpEntry(Connection* conn) { char filename[2][100]; char idxpath[2][100]; snprintf(filename[0], 100, "%s-%04llu-%s.%d-%s.%d", filenamePrefix.c_str(), (long long unsigned)connectionID, IPToString(conn->srcIP).c_str(), ntohs(conn->srcPort), IPToString(conn->dstIP).c_str(), ntohs(conn->dstPort)); snprintf(filename[1], 100, "%s-%04llu-%s.%d-%s.%d", filenamePrefix.c_str(), (long long unsigned)connectionID, IPToString(conn->dstIP).c_str(), ntohs(conn->dstPort), IPToString(conn->srcIP).c_str(), ntohs(conn->srcPort)); snprintf(idxpath[0], ARRAY_SIZE(idxpath[0]), "/%04llX", (long long unsigned)(connectionID>>16)); snprintf(idxpath[1], ARRAY_SIZE(idxpath[1]), "/%02llX/", (long long unsigned)(connectionID>>8)); connectionID++; // create paths, if needed struct stat s; string mkpath = path+string(idxpath[0]); if (stat(mkpath.c_str(), &s) != 0) { if (mkdir(mkpath.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)!=0) THROWEXCEPTION("error while creating directory '%s': %s", mkpath.c_str(), strerror(errno)); } mkpath += string(idxpath[1]); if (stat(mkpath.c_str(), &s) != 0) { if (mkdir(mkpath.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)!=0) THROWEXCEPTION("error while creating directory '%s': %s", mkpath.c_str(), strerror(errno)); } string filepayload[2] = { mkpath + string(filename[0]) + ".payload", mkpath + string(filename[1]) + ".payload" }; string fileinfo = mkpath + string(filename[0]) + ".info"; msg(MSG_VDEBUG, "writing files for connection %s", filename[0]); if (stat(filepayload[0].c_str(), &s) == 0 && !filewarningIssued) { msg(MSG_DIALOG, "files in IpfixPayloadWriter destination directory already present, overwriting ..."); filewarningIssued = true; } // save payload in two files FILE* f; char buf[500]; if (conn->srcPayload) { f = fopen(filepayload[0].c_str(), "w+"); if (f == NULL) THROWEXCEPTION("failed to open file '%s', error: %s", filepayload[0].c_str(), strerror(errno)); if (conn->srcPayloadLen && fwrite(conn->srcPayload, conn->srcPayloadLen, 1, f) != 1) THROWEXCEPTION("failed to write to file '%s', error: %s, 1", filepayload[0].c_str(), strerror(errno)); if (fclose(f) != 0) THROWEXCEPTION("failed to close file '%s', error: %s, 2", filepayload[0].c_str(), strerror(errno)); } if (conn->dstPayload) { f = fopen(filepayload[1].c_str(), "w+"); if (f == NULL) THROWEXCEPTION("failed to open file '%s', error: %s", filepayload[1].c_str(), strerror(errno)); if (conn->dstPayloadLen && fwrite(conn->dstPayload, conn->dstPayloadLen, 1, f) != 1) THROWEXCEPTION("failed to write to file '%s', error: %s, 3", filepayload[1].c_str(), strerror(errno)); if (fclose(f) != 0) THROWEXCEPTION("failed to close file '%s', error: %s, 4", filepayload[1].c_str(), strerror(errno)); } // save additional data f = fopen(fileinfo.c_str(), "w+"); if (f == NULL) THROWEXCEPTION("failed to open file '%s', error: %s", fileinfo.c_str(), strerror(errno)); snprintf(buf, 100, "srcIP: %s\n", IPToString(conn->srcIP).c_str()); if (fwrite(buf, strnlen(buf, 100), 1, f) != 1) THROWEXCEPTION("failed to write to file '%s', error: %s", fileinfo.c_str(), strerror(errno)); snprintf(buf, 100, "dstIP: %s\n", IPToString(conn->dstIP).c_str()); if (fwrite(buf, strnlen(buf, 100), 1, f) != 1) THROWEXCEPTION("failed to write to file '%s', error: %s", fileinfo.c_str(), strerror(errno)); snprintf(buf, 100, "srcPort: %u\n", ntohs(conn->srcPort)); if (fwrite(buf, strnlen(buf, 100), 1, f) != 1) THROWEXCEPTION("failed to write to file '%s', error: %s", fileinfo.c_str(), strerror(errno)); snprintf(buf, 100, "dstPort: %u\n", htons(conn->dstPort)); if (fwrite(buf, strnlen(buf, 100), 1, f) != 1) THROWEXCEPTION("failed to write to file '%s', error: %s", fileinfo.c_str(), strerror(errno)); snprintf(buf, 100, "srcFlowTimes: %llu / %llu\n", (long long unsigned)conn->srcTimeStart, (long long unsigned)conn->srcTimeEnd); if (fwrite(buf, strnlen(buf, 100), 1, f) != 1) THROWEXCEPTION("failed to write to file '%s', error: %s", fileinfo.c_str(), strerror(errno)); snprintf(buf, 100, "revFlowTimes: %llu / %llu\n", (long long unsigned)conn->dstTimeStart, (long long unsigned)conn->dstTimeEnd); if (fwrite(buf, strnlen(buf, 100), 1, f) != 1) THROWEXCEPTION("failed to write to file '%s', error: %s", fileinfo.c_str(), strerror(errno)); snprintf(buf, 100, "srcOctets: %llu\n", (long long unsigned)htonll(conn->srcOctets)); if (fwrite(buf, strnlen(buf, 100), 1, f) != 1) THROWEXCEPTION("failed to write to file '%s', error: %s", fileinfo.c_str(), strerror(errno)); snprintf(buf, 100, "revOctets: %llu\n", (long long unsigned)htonll(conn->dstOctets)); if (fwrite(buf, strnlen(buf, 100), 1, f) != 1) THROWEXCEPTION("failed to write to file '%s', error: %s", fileinfo.c_str(), strerror(errno)); snprintf(buf, 100, "srcPackets: %llu\n", (long long unsigned)htonll(conn->srcPackets)); if (fwrite(buf, strnlen(buf, 100), 1, f) != 1) THROWEXCEPTION("failed to write to file '%s', error: %s", fileinfo.c_str(), strerror(errno)); snprintf(buf, 100, "revPackets: %llu\n", (long long unsigned)htonll(conn->dstPackets)); if (fwrite(buf, strnlen(buf, 100), 1, f) != 1) THROWEXCEPTION("failed to write to file '%s', error: %s", fileinfo.c_str(), strerror(errno)); snprintf(buf, 100, "protocol: %d\n", conn->protocol); if (fwrite(buf, strnlen(buf, 100), 1, f) != 1) THROWEXCEPTION("failed to write to file '%s', error: %s", fileinfo.c_str(), strerror(errno)); snprintf(buf, 100, "srcPayloadLen: %d\n", conn->srcPayloadLen); if (fwrite(buf, strnlen(buf, 100), 1, f) != 1) THROWEXCEPTION("failed to write to file '%s', error: %s", fileinfo.c_str(), strerror(errno)); snprintf(buf, 100, "dstPayloadLen: %d\n", conn->dstPayloadLen); if (fwrite(buf, strnlen(buf, 100), 1, f) != 1) THROWEXCEPTION("failed to write to file '%s', error: %s", fileinfo.c_str(), strerror(errno)); if (conn->srcPayload != 0) { snprintf(buf, 100, "nicePayload: "); if (fwrite(buf, strnlen(buf, 100), 1, f) != 1) THROWEXCEPTION("failed to write to file '%s', error: %s", fileinfo.c_str(), strerror(errno)); if (conn->srcPayloadLen>0) { uint32_t buflen = (conn->srcPayloadLen > ARRAY_SIZE(buf) ? ARRAY_SIZE(buf) : conn->srcPayloadLen); memcpy(buf, conn->srcPayload, buflen); for (uint32_t i=0; i<buflen && i<conn->srcPayloadLen; i++) { if (!isprint(buf[i])) buf[i] = '.'; } if (fwrite(buf, buflen, 1, f) != 1) THROWEXCEPTION("failed to write to file '%s', error: %s", fileinfo.c_str(), strerror(errno)); } if (fwrite("\n", 1, 1, f) != 1) THROWEXCEPTION("failed to write to file '%s', error: %s", fileinfo.c_str(), strerror(errno)); } if (conn->dstPayload != 0) { snprintf(buf, 100, "revNicePayload: "); if (fwrite(buf, strnlen(buf, 100), 1, f) != 1) THROWEXCEPTION("failed to write to file '%s', error: %s", fileinfo.c_str(), strerror(errno)); if (conn->dstPayloadLen>0) { uint32_t buflen = (conn->dstPayloadLen > ARRAY_SIZE(buf) ? ARRAY_SIZE(buf) : conn->dstPayloadLen); memcpy(buf, conn->dstPayload, buflen); for (uint32_t i=0; i<buflen && i<conn->dstPayloadLen; i++) { if (!isprint(buf[i])) buf[i] = '.'; } if (fwrite(buf, buflen, 1, f) != 1) THROWEXCEPTION("failed to write to file '%s', error: %s", fileinfo.c_str(), strerror(errno)); } if (fwrite("\n", 1, 1, f) != 1) THROWEXCEPTION("failed to write to file '%s', error: %s", fileinfo.c_str(), strerror(errno)); } if (fclose(f) != 0) THROWEXCEPTION("failed to close file '%s', error: %s", fileinfo.c_str(), strerror(errno)); }
void SensorManager::retrieveStatistics(bool ignoreshutdown) { const char* xmlpre = "<vermont>\n\t<sensorData time=\"%s\" epochtime=\"%d.%03d\" host=\"%s\">\n"; const char* xmlpost = "\t</sensorData>\n</vermont>\n"; const char* xmlglobals = "\t\t<%s>%s</%s>\n"; string lockfile = outputFilename + ".lock"; bool haveGraphLock; // we must not wait for the graph lock, else there may be a race condition with // the ConfigManager while (! (haveGraphLock = graphIS->tryLockGraph())) { if (smExitFlag) break; timespec timeout = { 0, 200000 }; nanosleep(&timeout, NULL); } if (!ignoreshutdown && smExitFlag) return; const char* openflags = (append ? "a" : "w"); FILE* file = fopen(outputFilename.c_str(), openflags); if (!file) { THROWEXCEPTION("failed to reopen file %s", outputFilename.c_str()); perror("error:"); } timeval tvcurtime = unixtime(); time_t curtime = tvcurtime.tv_sec; char curtimestr[100]; ctime_r(&curtime, curtimestr); curtimestr[strlen(curtimestr)-1] = 0; fprintf(file, xmlpre, curtimestr, curtime, tvcurtime.tv_usec/1000, hostname); char text[100]; snprintf(text, 100, "%u", static_cast<uint32_t>(getpid())); fprintf(file, xmlglobals, "pid", text, "pid"); char lasttimestr[100]; ctime_r(&lasttime, lasttimestr); lasttimestr[strlen(lasttimestr)-1] = 0; fprintf(file, xmlglobals, "lastTime", lasttimestr, "lastTime"); #if defined(__linux__) const char* xmlglobalsuint = "\t\t<%s>%u</%s>\n"; ThreadCPUInterface::SystemInfo si = ThreadCPUInterface::getSystemInfo(); fprintf(file, "\t\t<jiffyFrequency>%llu</jiffyFrequency>\n", (long long unsigned)hertzValue); fprintf(file, xmlglobalsuint, "processorAmount", si.noCPUs, "processorAmount"); for (uint16_t i=0; i<si.sysJiffies.size(); i++) { double sysutil = (si.sysJiffies[i]-lastSystemInfo.sysJiffies[i])/(static_cast<double>(curtime)-lasttime)/hertzValue*100; double userutil = (si.userJiffies[i]-lastSystemInfo.userJiffies[i])/(static_cast<double>(curtime)-lasttime)/hertzValue*100; fprintf(file, "\t\t<processor id=\"%u\"><util type=\"system\">%.2f</util><util type=\"user\">%.2f</util></processor>\n", i, sysutil, userutil); } fprintf(file, "\t\t<memory><free type=\"bytes\">%llu</free><total type=\"bytes\">%llu</total></memory>\n", (long long unsigned)si.freeMemory, (long long unsigned)si.totalMemory); lastSystemInfo = si; #endif //DPRINTF("*** sensor data at %s", ctime(&curtime)); Graph* g = graphIS->getGraph(); vector<CfgNode*> nodes = g->getNodes(); vector<CfgNode*>::iterator iter = nodes.begin(); while (iter != nodes.end()) { Cfg* cfg = (*iter)->getCfg(); Sensor* s = cfg->getInstance(); vector<uint32_t> nextids = cfg->getNext(); writeSensorXML(file, s, cfg->getName().c_str(), cfg->getID(), true, curtime, lasttime, &nextids); iter++; } // iterate through all non-module sensors mutex.lock(); list<SensorEntry>::const_iterator siter = sensors.begin(); while (siter != sensors.end()) { //DPRINTFL(MSG_ERROR, "non-module cfg->getName()=%s, s=%u", siter->name.c_str(), siter->sensor); writeSensorXML(file, siter->sensor, siter->name.c_str(), siter->id, false, curtime, lasttime, NULL); siter++; } mutex.unlock(); fprintf(file, "%s", xmlpost); fclose(file); if (haveGraphLock) graphIS->unlockGraph(); }
bool Config::Init() { // Default values, if they are not set under config.xml those will be used. // Section GFX m_vParserInfo.push_back( ParserData( "GFX", IS_SECTION, NULL ) ); m_vParserInfo.push_back( ParserData( "WIDTH", IS_INTEGER, &m_iWidth ) ); m_vParserInfo.push_back( ParserData( "HEIGHT", IS_INTEGER, &m_iHeight ) ); m_vParserInfo.push_back( ParserData( "BPP", IS_INTEGER, &m_iBPP ) ); m_vParserInfo.push_back( ParserData( "CURSOR", IS_INTEGER, &m_iCursor ) ); m_vParserInfo.push_back( ParserData( "PERSPECTIVE", IS_INTEGER, &m_iPerspective ) ); m_vParserInfo.push_back( ParserData( "FULLSCREEN", IS_INTEGER, &m_iStartFullScreen ) ); m_vParserInfo.push_back( ParserData( "ROOF_FADE_TIME", IS_INTEGER, &m_iRoofFadeTime ) ); m_vParserInfo.push_back( ParserData( "ROOF_FADE_ALPHA", IS_INTEGER, &m_iRoofFadeAlpha ) ); m_vParserInfo.push_back( ParserData( "ZBUFFER_SIZE", IS_INTEGER, &m_iDepthBuffer ) ); m_vParserInfo.push_back( ParserData( "MAXZOOM", IS_INTEGER, &m_iMaxZoom ) ); m_vParserInfo.push_back( ParserData( "MAXANGLE", IS_INTEGER, &m_iMaxAngle ) ); m_vParserInfo.push_back( ParserData( "VIEWDISTANCE", IS_INTEGER, &m_iViewDistance ) ); m_vParserInfo.push_back( ParserData( "BRIGHTNESS", IS_INTEGER, &m_iBrightness ) ); // Section UO m_vParserInfo.push_back( ParserData( "UO", IS_SECTION, NULL ) ); m_vParserInfo.push_back( ParserData( "STARTX", IS_INTEGER, &m_iStartX ) ); m_vParserInfo.push_back( ParserData( "STARTY", IS_INTEGER, &m_iStartY ) ); m_vParserInfo.push_back( ParserData( "STARTZ", IS_INTEGER, &m_iStartZ ) ); m_vParserInfo.push_back( ParserData( "MULPATH", IS_STRING, &m_sMulPath ) ); // m_vParserInfo.push_back( ParserData( "COMPRESSED_MAP", IS_STRING, &m_sCompressedMap ) ); m_vParserInfo.push_back( ParserData( "POPUP_MENU", IS_INTEGER, &m_iPopup ) ); m_vParserInfo.push_back( ParserData( "AOS", IS_INTEGER, &m_iAOSToolTips ) ); m_vParserInfo.push_back( ParserData( "CLIENT_IDENTIFICATION", IS_STRING, &m_sClientVersion ) ); m_vParserInfo.push_back( ParserData( "USE_CLILOCS", IS_INTEGER, &m_iClilocs ) ); m_vParserInfo.push_back( ParserData( "CLILOC_LANGUAGE", IS_STRING, &m_sClilocLang ) ); m_vParserInfo.push_back( ParserData( "SPEECH_HUE", IS_INTEGER, &m_iSpeechHue ) ); m_vParserInfo.push_back( ParserData( "AOSTOOLTIPS", IS_INTEGER, &m_iAOSToolTips ) ); //Artix added speech.mul config option m_vParserInfo.push_back( ParserData( "USE_SPEECH", IS_INTEGER, &m_iSpeech ) ); // Section NET m_vParserInfo.push_back( ParserData( "NET", IS_SECTION, NULL ) ); m_vParserInfo.push_back( ParserData( "PORT", IS_INTEGER, &m_iServerPort ) ); m_vParserInfo.push_back( ParserData( "SERVER", IS_STRING, &m_sServer ) ); m_vParserInfo.push_back( ParserData( "LOGIN", IS_STRING, &m_sLogin ) ); m_vParserInfo.push_back( ParserData( "PASSWORD", IS_STRING, &m_sPassword ) ); m_vParserInfo.push_back( ParserData( "IS_SPHERE", IS_INTEGER, &m_iIsSphere ) ); m_vParserInfo.push_back( ParserData( "IS_SPHERE55R", IS_INTEGER, &m_iIsSphere55R ) ); m_vParserInfo.push_back( ParserData( "IS_POL", IS_INTEGER, &m_iIsPol ) ); m_vParserInfo.push_back( ParserData( "IS_RUNUO", IS_INTEGER, &m_iIsRunUO ) ); m_vParserInfo.push_back( ParserData( "IS_UOX3", IS_INTEGER, &m_iIsUox3 ) ); m_vParserInfo.push_back( ParserData( "CLIENT_KEY", IS_INTEGER, &m_iClientKey ) ); // Section Sound m_vParserInfo.push_back( ParserData( "SOUND", IS_SECTION, NULL ) ); m_vParserInfo.push_back( ParserData( "MUSIC", IS_INTEGER, &m_iMusic ) ); m_vParserInfo.push_back( ParserData( "SOUND", IS_INTEGER, &m_iSound ) ); m_vParserInfo.push_back( ParserData( "FREQUENCY", IS_INTEGER, &m_iFrequency ) ); m_vParserInfo.push_back( ParserData( "STEREO", IS_INTEGER, &m_iStereo ) ); m_vParserInfo.push_back( ParserData( "CHUNKSIZE", IS_INTEGER, &m_iChunkSize ) ); m_vParserInfo.push_back( ParserData( "MUSICVOLUME", IS_INTEGER, &m_iMusicVolume ) ); m_vParserInfo.push_back( ParserData( "SOUNDVOLUME", IS_INTEGER, &m_iSoundVolume ) ); m_vParserInfo.push_back( ParserData( "MP3", IS_INTEGER, &m_iMP3 ) ); m_vParserInfo.push_back( ParserData( "FOOTSTEPS", IS_INTEGER, &m_iFootSteps ) ); // Section Iris Client m_vParserInfo.push_back( ParserData( "IRIS", IS_SECTION, NULL ) ); m_vParserInfo.push_back( ParserData( "SCRIPTS_PATH", IS_STRING, &m_sScriptPath ) ); m_vParserInfo.push_back( ParserData( "MOUSEOVER_TIMER", IS_INTEGER, &m_iMouseMotionTimer ) ); m_vParserInfo.push_back( ParserData( "", IS_END, NULL ) ); // After adding to the vector our struct start filling it with actual values XML::Parser kParser; kParser.loadData( "./xml/config.xml" ); XML::Node *kDocument = kParser.parseDocument(); XML::Node *kConfig = kDocument->findNode( "CONFIG" ); if ( !kConfig ) { THROWEXCEPTION( "Could not find configuration node." ); return false; } XML::Node *kValue = NULL, *kSection = NULL; // Read all values from config.xml for ( int i = 0; m_vParserInfo[i].iType != IS_END; i++ ) { const ParserData &Data = m_vParserInfo[i]; if ( Data.iType == IS_SECTION ) { kSection = kConfig->findNode( Data.sName ); } else { // If no section is loaded get from <config> kValue = kSection != NULL ? kSection->findNode( Data.sName ) : kConfig->findNode( Data.sName ); if ( kValue != NULL ) { if ( Data.iType == IS_BOOL ) { *reinterpret_cast<bool *>( Data.pData ) = kValue->asBool(); } else if ( Data.iType == IS_INTEGER ) { *reinterpret_cast<int *>( Data.pData ) = kValue->asInteger(); } else if ( Data.iType == IS_STRING ) { *reinterpret_cast<std::string *>( Data.pData ) = kValue->asString(); } } } } // Read Fonts bit of the file XML::Node *kFontSet = kConfig->findNode( "FONTSET" ); if ( kFontSet ) { int idx = 0; XML::Node *kFontNode = NULL; FontInfo kFontInfo; while ( ( kFontNode = kFontSet->findNode( "FONT", idx++ ) ) ) { if ( !kFontNode->lookupAttribute( "ID", kFontInfo.iId ) ) { continue; } if ( !kFontNode->lookupAttribute( "FILE", kFontInfo.sFileName ) ) { continue; } if ( !kFontNode->lookupAttribute( "NAME", kFontInfo.sFontName ) ) { continue; } if ( !kFontNode->lookupAttribute( "SIZE", kFontInfo.iSize ) ) { continue; } if ( !kFontNode->lookupAttribute( "HUE", kFontInfo.iHue ) ) { continue; } FontManager::GetInstance()->AddTTFFont( kFontInfo.iId, kFontInfo.sFileName, kFontInfo.sFontName, kFontInfo.iSize, kFontInfo.iHue ); } } // Depth Buffer if ( m_iDepthBuffer <= 0 ) { m_iDepthBuffer = 16; } // View Distance if ( m_iViewDistance < 3 ) { m_iViewDistance = 3; } // Max Zoom if ( m_iMaxZoom <= 0 ) { m_iMaxZoom = 0; } // Max Angle if ( m_iMaxAngle < 10 ) { m_iMaxAngle = 10; } // Max Angle if ( m_iMaxAngle > 90 ) { m_iMaxAngle = 90; } // Fix Mul path if no / at the end if ( m_sMulPath.size() ) { char cLastChar = m_sMulPath[m_sMulPath.length() - 1]; if ( ( cLastChar != '/' ) && ( cLastChar != '\\' ) ) { m_sMulPath += "/"; } } return true; }
/** * parses configuration and adjusts/creates module graph accordingly * afterwards all modules are started */ void ConfigManager::parseConfig(std::string fileName) { lockGraph(); Graph* oldGraph = graph; graph = new Graph(); old_document = document; document = XMLDocument::parse_file(fileName); XMLElement* root = document->getRootNode(); // consistency checks if (!root) { unlockGraph(); THROWEXCEPTION("%s is an empty XML-Document!", fileName.c_str()); } if (!root->matches("ipfixConfig")) { unlockGraph(); THROWEXCEPTION("Root element does not match \"ipfixConfig\"." " This is not a valid configuration file!"); } /* process each root element node and add a new node (with its config * attached to the node) to the graph */ XMLNode::XMLSet<XMLElement*> rootElements = root->getElementChildren(); for (XMLNode::XMLSet<XMLElement*>::const_iterator it = rootElements.begin(); it != rootElements.end(); it++) { bool found = false; for (unsigned int i = 0; i < ARRAY_SIZE(configModules); i++) { if ((*it)->getName() == configModules[i]->getName()) { Cfg* cfg = configModules[i]->create(*it); // handle special modules SensorManagerCfg* smcfg = dynamic_cast<SensorManagerCfg*>(cfg); if (smcfg) { // SensorManager will not be connected to any modules, so its instance // needs to be started manually smcfg->setGraphIS(this); sensorManager = smcfg->getInstance(); } graph->addNode(cfg); found = true; } } if (!found) { unlockGraph(); msg(MSG_INFO, "Unknown cfg entry %s found", (*it)->getName().c_str()); } } if (!oldGraph) { // this is the first config we have read Connector connector; graph->accept(&connector); } else { // first, connect the nodes on the new graph (but NOT the modules Connector connector(true, false); graph->accept(&connector); // now connect the modules reusing those from the old graph ReConnector reconnector(oldGraph); graph->accept(&reconnector); } // start the instances if not already running std::vector<CfgNode*> topoNodes = graph->topoSort(); for (size_t i = 0; i < topoNodes.size(); i++) { Cfg* cfg = topoNodes[topoNodes.size() -1 -i]->getCfg(); msg(MSG_INFO, "Starting module %s", cfg->getName().c_str()); cfg->start(false); } if (old_document) delete old_document; // if there is an old graph, we did a reconfiguration. So now we have to delete the // old graph, but we can't delete the instances immediatly, because there is a small // chance that instances which got reused could still hold a reference to a instance we // want to delete right now. // => we use the deleter to delete the instances after a specific time has passed so we // are safe that no-one holds a reference on the deleted modules anymore if (oldGraph) deleter.addGraph(oldGraph); unlockGraph(); }