예제 #1
0
파일: normalize.c 프로젝트: jasonish/snort
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;
}
예제 #2
0
파일: normalize.c 프로젝트: jasonish/snort
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;
}
예제 #3
0
파일: normalize.c 프로젝트: jasonish/snort
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;
}
예제 #4
0
파일: normalize.c 프로젝트: jasonish/snort
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;
}
예제 #5
0
파일: normalize.c 프로젝트: jasonish/snort
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;
}
예제 #6
0
파일: normalize.c 프로젝트: jasonish/snort
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;
}
예제 #7
0
파일: normalize.c 프로젝트: jasonish/snort
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;
}
예제 #8
0
//------------------------------
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();
    }