static int Norm_ICMP6 (NormalizerContext* c, Packet * p, uint8_t layer, int changes) { ICMPHdr* h = (ICMPHdr*)(p->layers[layer].start); NormMode mode = getNormMode(c); if ( (h->type == ICMP6_ECHO || h->type == ICMP6_REPLY) && (h->code != 0) ) { if ( mode == NORM_MODE_ON ) { h->code = 0; changes++; } normStats[PC_ICMP6_ECHO][mode]++; sfBase.iPegs[PERF_COUNT_ICMP6_ECHO][mode]++; } return changes; }
static int Norm_IP6_Opts (NormalizerContext* c, Packet * p, uint8_t layer, int changes) { NormMode mode = getNormMode(c); if ( mode == NORM_MODE_ON ) { uint8_t* b = p->layers[layer].start; ExtOpt* x = (ExtOpt*)b; // whatever was here, turn it into one PADN option x->type = IP6_OPT_PAD_N; x->olen = (x->xlen * 8) + 8 - sizeof(*x); memset(b+sizeof(*x), 0, x->olen); changes++; } normStats[PC_IP6_OPTS][mode]++; sfBase.iPegs[PERF_COUNT_IP6_OPTS][mode]++; return changes; }
static int Norm_IP6 (NormalizerContext* c, Packet * p, uint8_t layer, int changes) { IP6RawHdr* h = (IP6RawHdr*)(p->layers[layer].start); NormMode mode = getNormMode(c); if ( Norm_IsEnabled(c, NORM_IP6_TTL) ) { if ( h->ip6hops < ScMinTTL() ) { if ( mode == NORM_MODE_ON ) { h->ip6hops = ScNewTTL(); p->error_flags &= ~PKT_ERR_BAD_TTL; changes++; } normStats[PC_IP6_TTL][mode]++; sfBase.iPegs[PERF_COUNT_IP6_TTL][mode]++; } } return changes; }
static inline int Norm_TCPPadding (NormalizerContext* context, uint8_t* opts, size_t len, uint8_t numOpts, int changes) { size_t i = 0; uint8_t c = 0; NormMode mode = getNormMode(context); while ( (i < len) && (opts[i] != TCPOPT_EOL) && (c++ < numOpts) ) { i += ( opts[i] <= 1 ) ? 1 : opts[i+1]; } if ( ++i < len && memcmp(opts+i, MAX_EOL_PAD, len-i) ) { if ( mode == NORM_MODE_ON ) { memset(opts+i, 0, len-i); changes++; } normStats[PC_TCP_PAD][mode]++; sfBase.iPegs[PERF_COUNT_TCP_PAD][mode]++; } return changes; }
static int Norm_TCP (NormalizerContext* c, Packet * p, uint8_t layer, int changes) { NormMode mode = getNormMode(c); TCPHdr* h = (TCPHdr*)(p->layers[layer].start); if ( Norm_IsEnabled(c, NORM_TCP_RSV) ) { if ( h->th_offx2 & TH_RSV ) { if ( mode == NORM_MODE_ON ) { h->th_offx2 &= ~TH_RSV; changes++; } normStats[PC_TCP_RSV][mode]++; sfBase.iPegs[PERF_COUNT_TCP_RSV][mode]++; } } if ( Norm_IsEnabled(c, NORM_TCP_ECN_PKT) ) { if ( h->th_flags & (TH_CWR|TH_ECE) ) { if ( mode == NORM_MODE_ON ) { h->th_flags &= ~(TH_CWR|TH_ECE); changes++; } normStats[PC_TCP_ECN_PKT][mode]++; sfBase.iPegs[PERF_COUNT_TCP_ECN_PKT][mode]++; } if ( h->th_offx2 & TH_NS ) { if ( mode == NORM_MODE_ON ) { h->th_offx2 &= ~TH_NS; changes++; } normStats[PC_TCP_NS][mode]++; sfBase.iPegs[PERF_COUNT_TCP_NS][mode]++; } } if ( h->th_urp ) { if ( !(h->th_flags & TH_URG) ) { if ( Norm_IsEnabled(c, NORM_TCP_REQ_URG) ) { if ( mode == NORM_MODE_ON ) { h->th_urp = 0; changes++; } normStats[PC_TCP_REQ_URG][mode]++; sfBase.iPegs[PERF_COUNT_TCP_REQ_URG][mode]++; } } else if ( !p->dsize ) { if ( Norm_IsEnabled(c, NORM_TCP_REQ_PAY) ) { if ( mode == NORM_MODE_ON ) { h->th_flags &= ~TH_URG; h->th_urp = 0; changes++; } normStats[PC_TCP_REQ_PAY][mode]++; sfBase.iPegs[PERF_COUNT_TCP_REQ_PAY][mode]++; } } else if ( (ntohs(h->th_urp) > p->dsize) ) { if ( Norm_IsEnabled(c, NORM_TCP_URP) ) { if ( mode == NORM_MODE_ON ) { h->th_urp = ntohs(p->dsize); changes++; } normStats[PC_TCP_URP][mode]++; sfBase.iPegs[PERF_COUNT_TCP_URP][mode]++; } } } else if ( Norm_IsEnabled(c, NORM_TCP_REQ_URP) && h->th_flags & TH_URG ) { if ( mode == NORM_MODE_ON ) { h->th_flags &= ~TH_URG; changes++; } normStats[PC_TCP_REQ_URP][mode]++; sfBase.iPegs[PERF_COUNT_TCP_REQ_URP][mode]++; } if ( p->tcp_options_len > 0 ) { uint8_t* opts = p->layers[layer].start + TCP_HEADER_LEN; if ( Norm_IsEnabled(c, NORM_TCP_OPT) ) { changes = Norm_TCPOptions(c, opts, p->tcp_options_len, h, p->tcp_option_count, changes); } else if ( Norm_IsEnabled(c, NORM_TCP_PAD) ) { changes = Norm_TCPPadding(c, opts, p->tcp_options_len, p->tcp_option_count, changes); } } return changes; }
static inline int Norm_TCPOptions (NormalizerContext* context, uint8_t* opts, size_t len, const TCPHdr* h, uint8_t numOpts, int changes) { size_t i = 0; uint8_t c = 0; NormMode mode = getNormMode(context); while ( (i < len) && (opts[i] != TCPOPT_EOL) && (c++ < numOpts) ) { uint8_t olen = ( opts[i] <= 1 ) ? 1 : opts[i+1]; // we know that the first numOpts options have valid lengths // so we should not need to check individual or total option lengths. // however, we keep this as a sanity check. if ( i + olen > len) break; switch ( opts[i] ) { case TCPOPT_NOP: break; case TCPOPT_MAXSEG: case TCPOPT_WSCALE: if ( !(h->th_flags & TH_SYN) ) { if ( mode == NORM_MODE_ON ) { NopDaOpt(opts+i, olen); changes++; } normStats[PC_TCP_SYN_OPT][mode]++; sfBase.iPegs[PERF_COUNT_TCP_SYN_OPT][mode]++; } break; case TCPOPT_TIMESTAMP: if ( !(h->th_flags & TH_ACK) && // use memcmp because opts have arbitrary alignment memcmp(opts+i+TS_ECR_OFFSET, MAX_EOL_PAD, TS_ECR_LENGTH) ) { if ( mode == NORM_MODE_ON ) { // TSecr should be zero unless ACK is set memset(opts+i+TS_ECR_OFFSET, 0, TS_ECR_LENGTH); changes++; } normStats[PC_TCP_TS_ECR][mode]++; sfBase.iPegs[PERF_COUNT_TCP_TS_ECR][mode]++; } break; default: if ( !Norm_TcpIsOptional(context, opts[i]) ) { if ( mode == NORM_MODE_ON ) { NopDaOpt(opts+i, olen); changes++; } normStats[PC_TCP_OPT][mode]++; sfBase.iPegs[PERF_COUNT_TCP_OPT][mode]++; } } i += olen; } if ( ++i < len && memcmp(opts+i, MAX_EOL_PAD, len-i) ) { if ( mode == NORM_MODE_ON ) { memset(opts+i, 0, len-i); changes++; } normStats[PC_TCP_PAD][mode]++; sfBase.iPegs[PERF_COUNT_TCP_PAD][mode]++; } return changes; }
static int Norm_IP4 (NormalizerContext* c, Packet * p, uint8_t layer, int changes) { IPHdr* h = (IPHdr*)(p->layers[layer].start); uint16_t fragbits = ntohs(h->ip_off); uint16_t origbits = fragbits; NormMode mode = getNormMode(c); if ( Norm_IsEnabled(c, NORM_IP4_TRIM) && (layer == 1) ) { uint32_t len = p->layers[0].length + ntohs(h->ip_len); if ( (len < p->pkth->pktlen) && ( (len >= ETH_MIN_LEN) || (p->pkth->pktlen > ETH_MIN_LEN) ) ) { if ( mode == NORM_MODE_ON ) { ((DAQ_PktHdr_t*)p->pkth)->pktlen = (len < ETH_MIN_LEN) ? ETH_MIN_LEN : len; p->packet_flags |= PKT_RESIZED; changes++; } normStats[PC_IP4_TRIM][mode]++; sfBase.iPegs[PERF_COUNT_IP4_TRIM][mode]++; } } if ( Norm_IsEnabled(c, NORM_IP4_TOS) ) { if ( h->ip_tos ) { if ( mode == NORM_MODE_ON ) { h->ip_tos = 0; changes++; } normStats[PC_IP4_TOS][mode]++; sfBase.iPegs[PERF_COUNT_IP4_TOS][mode]++; } } #if 0 if ( Norm_IsEnabled(c, NORM_IP4_ID) ) { // TBD implement IP ID normalization / randomization } #endif if ( Norm_IsEnabled(c, NORM_IP4_DF) ) { if ( fragbits & IP4_FLAG_DF ) { if ( mode == NORM_MODE_ON ) { fragbits &= ~IP4_FLAG_DF; changes++; } normStats[PC_IP4_DF][mode]++; sfBase.iPegs[PERF_COUNT_IP4_DF][mode]++; } } if ( Norm_IsEnabled(c, NORM_IP4_RF) ) { if ( fragbits & IP4_FLAG_RF ) { if ( mode == NORM_MODE_ON ) { fragbits &= ~IP4_FLAG_RF; changes++; } normStats[PC_IP4_RF][mode]++; sfBase.iPegs[PERF_COUNT_IP4_RF][mode]++; } } if ( fragbits != origbits ) { h->ip_off = htons(fragbits); } if ( Norm_IsEnabled(c, NORM_IP4_TTL) ) { if ( h->ip_ttl < ScMinTTL() ) { if ( mode == NORM_MODE_ON ) { h->ip_ttl = ScNewTTL(); p->error_flags &= ~PKT_ERR_BAD_TTL; changes++; } normStats[PC_IP4_TTL][mode]++; sfBase.iPegs[PERF_COUNT_IP4_TTL][mode]++; } } if ( p->layers[layer].length > IP_HEADER_LEN ) { if ( mode == NORM_MODE_ON ) { uint8_t* opts = p->layers[layer].start + IP_HEADER_LEN; uint8_t len = p->layers[layer].length - IP_HEADER_LEN; // expect len > 0 because IHL yields a multiple of 4 memset(opts, IPOPT_NOP, len); changes++; } normStats[PC_IP4_OPTS][mode]++; sfBase.iPegs[PERF_COUNT_IP4_OPTS][mode]++; } return changes; }
//------------------------------ bool MolState::Read() { int i,j,k,l; char tmpCh; std::string tmp_str, tmp_atomName; std::istringstream tmp_iStr; Atom tmp_atom; //------------ Read IP (if provided) ---------------------------------- if ( xmlF.CheckSubNode("ip") ) { xmlF.node("ip"); energy = xmlF.getDoubleValue(); xmlF.stepBack(); } //------------ Read the Geometry -------------------------------------- xmlF.node("geometry"); int tmp_nAtoms, tmp_nNormMds; tmp_nAtoms=xmlF.getIntValue("number_of_atoms"); std::string units; units=xmlF.value("units"); ifLinear= xmlF.getBoolValue("linear"); if (ifLinear) tmp_nNormMds = (3*tmp_nAtoms - 5); else tmp_nNormMds = (3*tmp_nAtoms - 6); tmp_iStr.str(xmlF.value("text")); tmp_iStr.clear(); atoms.clear(); for (i=0; i<tmp_nAtoms; i++) { tmp_atomName=""; tmpCh=' '; while ( !ifLetterOrNumber(tmpCh) and !(tmp_iStr.fail()) ) tmp_iStr.get(tmpCh); if (tmp_iStr.fail()) { std::cout << "\nError: less then "<< tmp_nAtoms <<" atoms found or the format error, \"text\"-s line nuumber "<<i+1<<"\n"; xmlF.exitOnFormatError(true); } do { tmp_atomName+=tmpCh; tmp_iStr.get( tmpCh ); } while( ifLetterOrNumber(tmpCh) ); tmp_atom.Name() = tmp_atomName; for (k=0; k<CARTDIM; k++) { tmp_iStr >> tmp_atom.Coord(k); if (units=="au") tmp_atom.Coord(k)*=AU2ANGSTROM; } if (tmp_iStr.fail()) { std::cout << "\nError: less then "<< tmp_nAtoms <<" atoms found or the format error in the atomic coordinates,\n" << " \"text\"-s line number "<<i+1<<"\n"; xmlF.exitOnFormatError(true); } atoms.push_back(tmp_atom); } //------------ Convert atomic names to masses -------------------------- for (i=0; i<NAtoms(); i++) { tmp_iStr.str( amuF.reset().node("masses").node( getAtom(i).Name().c_str() ).value() ); tmp_iStr.clear(); tmp_iStr >> getAtom(i).Mass(); amuF.exitOnFormatError(tmp_iStr.fail()); } //------------ Read Normal Modes --------------------------------------- NormalMode tmp_normMode(NAtoms(),0); // one temp. norm mode normModes.clear(); xmlF.stepBack(); xmlF.node("normal_modes"); tmp_iStr.str(xmlF.value("text")); tmp_iStr.clear(); for (i=0; i < tmp_nNormMds; i++) normModes.push_back( tmp_normMode ); int nModesPerLine=3; // three number of vib. modes per Line int nLines; nLines = tmp_nNormMds / nModesPerLine; if ( tmp_nNormMds % nModesPerLine != 0) nLines++; for (k = 0; k < nLines; k++) // number of blocks with 3 norm.modes. ("lines") { int current_nModesPerLine = nModesPerLine; // for the last entree, nModesPerString may differ from 3 if (nLines - 1 == k) if ( tmp_nNormMds % nModesPerLine != 0 ) current_nModesPerLine = tmp_nNormMds % nModesPerLine; for (i=0; i < NAtoms(); i++) for (j=0; j < current_nModesPerLine; j++) for (l=0; l < CARTDIM; l++) { tmp_iStr >> normModes[k*nModesPerLine+j].getDisplacement()[i*CARTDIM+l]; if (tmp_iStr.fail()) { std::cout << "\nError: less normal modes found than expected or the format error\n"; xmlF.exitOnFormatError(true); } } } //------------ Read Frequencies ---------------------------------------- xmlF.stepBack(); xmlF.node("frequencies"); tmp_iStr.str(xmlF.value("text")); tmp_iStr.clear(); for (i=0; i < tmp_nNormMds; i++) { tmp_iStr >> getNormMode(i).getFreq(); if (tmp_iStr.fail()) { std::cout << "\nError: format error at frequency #"<<i<< " or less than " << tmp_nNormMds <<" frequencies found\n"; xmlF.exitOnFormatError(true); } if (getNormMode(i).getFreq()<=0) { std::cout <<"\nError. The frequency ["<<getNormMode(i).getFreq() <<"] is negative\n"; xmlF.exitOnFormatError(true); } } // Now MolState is in a good shape, and some transformations can be performed //------------ 1. Un-mass-weight normal modes---------------------------- xmlF.stepBack(); xmlF.node("normal_modes"); bool if_massweighted; if_massweighted=xmlF.getBoolValue("if_mass_weighted"); //------------ 1. mass un-weight normal modes, if needed (QChem-->ACES format; )---------------- // qchem if_massweighted="true"; aces if_massweighted="false"; reduced_masses.Adjust(NNormModes(),1); reduced_masses.Set(1); if (if_massweighted) { // Read atomic names from "...->normal_modes->atoms" std::vector<Atom> normalModeAtoms; tmp_iStr.str(xmlF.value("atoms")); tmp_iStr.clear(); normalModeAtoms.clear(); for (i=0; i<NAtoms(); i++) { tmp_atomName=""; tmpCh=' '; while ( !ifLetterOrNumber(tmpCh) and !(tmp_iStr.fail()) ) tmp_iStr.get(tmpCh); xmlF.exitOnFormatError(tmp_iStr.fail()); do { tmp_atomName+=tmpCh; tmp_iStr.get( tmpCh ); } while( ifLetterOrNumber(tmpCh) ); tmp_atom.Name() = tmp_atomName; normalModeAtoms.push_back(tmp_atom); } // Get masses for each atomic name: for (i=0; i<NAtoms(); i++) { tmp_iStr.str( amuF.reset().node("masses").node( normalModeAtoms[i].Name().c_str() ).value() ); tmp_iStr.clear(); tmp_iStr >> normalModeAtoms[i].Mass(); amuF.exitOnFormatError(tmp_iStr.fail()); } // Mass-un-weight normal modes: for (int nm=0; nm<NNormModes(); nm++) for (int a=0; a<NAtoms(); a++) for (int i=0; i<CARTDIM; i++ ) getNormMode(nm).getDisplacement().Elem1(a*CARTDIM+i) *= sqrt(normalModeAtoms[a].Mass()); // normolize each normal mode (/sqrt(norm) which is also /sqrt(reduced mass)): // KMatrix reduced_masses(NNormModes(),1); for (int nm=0; nm<NNormModes(); nm++) { reduced_masses[nm] = 0; for (int a=0; a<NAtoms(); a++) for (int i=0; i<CARTDIM; i++ ) reduced_masses[nm]+= getNormMode(nm).getDisplacement().Elem1(a*CARTDIM+i) * getNormMode(nm).getDisplacement().Elem1(a*CARTDIM+i); } // reduced_masses.Print("Reduced masses:"); // Normalize: for (int nm=0; nm<NNormModes(); nm++) for (int a=0; a<NAtoms(); a++) for (int i=0; i<CARTDIM; i++ ) getNormMode(nm).getDisplacement().Elem1(a*CARTDIM+i)/=sqrt(reduced_masses[nm]); } xmlF.stepBack(); //------------ 2. Align geometry if requested ---------------------------- if_aligned_manually=false; double man_rot_x, man_rot_y, man_rot_z; Vector3D man_shift; if ( xmlF.CheckSubNode("manual_coordinates_transformation") ) { xmlF.node("manual_coordinates_transformation"); man_rot_x=xmlF.getDoubleValue("rotate_around_x"); man_rot_y=xmlF.getDoubleValue("rotate_around_y"); man_rot_z=xmlF.getDoubleValue("rotate_around_z"); man_shift.getCoord(0)=-xmlF.getDoubleValue("shift_along_x"); man_shift.getCoord(1)=-xmlF.getDoubleValue("shift_along_y"); man_shift.getCoord(2)=-xmlF.getDoubleValue("shift_along_z"); std::cout << "Molecular structure and normal modes of this electronic state\nwill be transformed as requested in the input.\n"; shiftCoordinates(man_shift); rotate(man_rot_x*PI,man_rot_y*PI,man_rot_z*PI); applyCoordinateThreshold(COORDINATE_THRESHOLD); if_aligned_manually=true; xmlF.stepBack(); } //------------ 3. Reorder normal modes if requested -------------------- if ( xmlF.CheckSubNode("manual_normal_modes_reordering") ) { xmlF.node("manual_normal_modes_reordering"); if_nm_reordered_manually=false; normModesOrder.clear(); std::cout << "New normal modes order was requested:\n" << xmlF.value("new_order") <<"\n"; tmp_iStr.str(xmlF.value("new_order")); int tmpInt; for (int nm=0; nm < NNormModes(); nm++) { tmp_iStr >> tmpInt; //input error check: if (tmp_iStr.fail()) { std::cout << "\nFormat error: non numeric symbol or less entries then the number of normal modes\n\n"; xmlF.exitOnFormatError(true); } if ( (tmpInt<0) or (tmpInt>=NNormModes()) ) { std::cout << "\nError: normal mode number ["<< tmpInt<<"] is out of range [0.."<<NNormModes()-1<<"].\n\n"; xmlF.exitOnFormatError(true); } normModesOrder.push_back(tmpInt); } // check if there are duplicates in the list: std::vector<int> tmpIntVector, tmpIntVector2; tmpIntVector = normModesOrder; std::sort( tmpIntVector.begin(), tmpIntVector.end() ); tmpIntVector2 = tmpIntVector; std::vector<int>::const_iterator intVec_iter; intVec_iter= unique( tmpIntVector.begin(), tmpIntVector.end() ); if (intVec_iter != tmpIntVector.end()) { std::cout << "\nFormat error: there are non unique entries. Check the sorted list:\n"; for (std::vector<int>::const_iterator tmp_iter=tmpIntVector2.begin(); tmp_iter!=tmpIntVector2.end(); tmp_iter++) std::cout << ' ' << *tmp_iter; std::cout<<'\n'; xmlF.exitOnFormatError(true); } // backup normal modes std::vector<NormalMode> oldNormModes; oldNormModes.clear(); for (int nm=0; nm < NNormModes(); nm++) { tmp_normMode = getNormMode(nm); oldNormModes.push_back( tmp_normMode ); } // copy normal modes using new order for (int nm=0; nm < NNormModes(); nm++) getNormMode(nm) = oldNormModes[ normModesOrder[nm] ]; std::cout << "Normal modes were reordered accordingly.\n"; if_nm_reordered_manually=true; xmlF.stepBack(); }