Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Validating a Subnet Mask
Forum Update on Monday, May 27th 2025

Validating a Subnet Mask

Scheduled Pinned Locked Moved Unsolved General and Desktop
7 Posts 4 Posters 3.3k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • webzoidW Offline
    webzoidW Offline
    webzoid
    wrote on last edited by webzoid
    #1

    Does anyone know of any existing algorithms within Qt which could validate a network subnet mask including checking that contiguous bits are set?

    For example, the following are valid subnets:

    255.255.255.0
    11111111.11111111.11111111.00000000
    
    255.255.224.0
    11111111.11111111.11110000.00000000
    
    255.224.0.0
    11111111.11110000.00000000.00000000
    

    Whereas these are not valid subnet masks

    255.15.0.0
    11111111.00001111.00000000.00000000
    
    255.255.88.0
    11111111.11111111.01011000.00000000
    
    224.15.0.0
    11110000.00001111.00000000.00000000
    

    I could go through each bit in turn starting with MSB, then set a flag when the bit is clear. If I see another set bit after the flag has been set then I can determine that the netmask is invalid.

    Seems a little clunky though and I'd perhaps expect that this is already covered somewhere in the QtNetwork library?

    uint32_t netmask = 0xFFF00000;
    bool flag = false;
    QString str;
    
    for (int i = 31; i >= 0; i--) {
    	bool set = (((netmask & (1 << i)) >> i) == 1);
    
    	if (set) {
    		str += "1";
    	}
    	else {
    		str += "0";
    	}
    
    	if (!set)
    		flag = true;
    
    	if (set && flag)
    		error = true;
    }
    
    qDebug() << str;
    
    jsulmJ 1 Reply Last reply
    0
    • webzoidW webzoid

      Does anyone know of any existing algorithms within Qt which could validate a network subnet mask including checking that contiguous bits are set?

      For example, the following are valid subnets:

      255.255.255.0
      11111111.11111111.11111111.00000000
      
      255.255.224.0
      11111111.11111111.11110000.00000000
      
      255.224.0.0
      11111111.11110000.00000000.00000000
      

      Whereas these are not valid subnet masks

      255.15.0.0
      11111111.00001111.00000000.00000000
      
      255.255.88.0
      11111111.11111111.01011000.00000000
      
      224.15.0.0
      11110000.00001111.00000000.00000000
      

      I could go through each bit in turn starting with MSB, then set a flag when the bit is clear. If I see another set bit after the flag has been set then I can determine that the netmask is invalid.

      Seems a little clunky though and I'd perhaps expect that this is already covered somewhere in the QtNetwork library?

      uint32_t netmask = 0xFFF00000;
      bool flag = false;
      QString str;
      
      for (int i = 31; i >= 0; i--) {
      	bool set = (((netmask & (1 << i)) >> i) == 1);
      
      	if (set) {
      		str += "1";
      	}
      	else {
      		str += "0";
      	}
      
      	if (!set)
      		flag = true;
      
      	if (set && flag)
      		error = true;
      }
      
      qDebug() << str;
      
      jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @webzoid There are not that many numbers to check against:

      00000000
      10000000
      11000000
      11100000
      11110000
      11111000
      11111100
      11111110
      11111111
      

      Simply check each byte of the mask whether it is one of this numbers. You don't even need to convert to binary representation.

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      2
      • webzoidW Offline
        webzoidW Offline
        webzoid
        wrote on last edited by
        #3

        @jsulm Sorry, I wasn't very explicit - the subnet mask is ultimately stored as a 32-bit number hence why I'm looping through all 32 bit positions.

        jsulmJ Paul ColbyP 2 Replies Last reply
        0
        • webzoidW webzoid

          @jsulm Sorry, I wasn't very explicit - the subnet mask is ultimately stored as a 32-bit number hence why I'm looping through all 32 bit positions.

          jsulmJ Offline
          jsulmJ Offline
          jsulm
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @webzoid But then you can iterate over each byte instead of iterating over each bit.

          https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          2
          • webzoidW webzoid

            @jsulm Sorry, I wasn't very explicit - the subnet mask is ultimately stored as a 32-bit number hence why I'm looping through all 32 bit positions.

            Paul ColbyP Offline
            Paul ColbyP Offline
            Paul Colby
            wrote on last edited by
            #5

            @webzoid said in Validating a Subnet Mask:

            the subnet mask is ultimately stored as a 32-bit number

            There may be better ways, but you can do it like:

            bool isContiguous(quint32 mask)
            {
                for (;mask != 0; mask <<=1) {
                    if ((mask & (1<<31)) == 0)
                        return false; // Highest bit is now zero, but mask is non-zero.
                }
                return true; // Mask was, or became 0.
            }
            

            And calling it with your sample masks:

                qDebug() << isContiguous(QHostAddress(QStringLiteral("255.255.255.0")).toIPv4Address());
                qDebug() << isContiguous(QHostAddress(QStringLiteral("255.255.224.0")).toIPv4Address());
                qDebug() << isContiguous(QHostAddress(QStringLiteral("255.224.0.0")).toIPv4Address());
                qDebug() << isContiguous(QHostAddress(QStringLiteral("255.15.0.0")).toIPv4Address());
                qDebug() << isContiguous(QHostAddress(QStringLiteral("255.255.88.0")).toIPv4Address());
                qDebug() << isContiguous(QHostAddress(QStringLiteral("224.15.0.0")).toIPv4Address());
            

            Gives:

            true
            true
            true
            false
            false
            false
            

            Cheers.

            webzoidW 1 Reply Last reply
            5
            • Paul ColbyP Paul Colby

              @webzoid said in Validating a Subnet Mask:

              the subnet mask is ultimately stored as a 32-bit number

              There may be better ways, but you can do it like:

              bool isContiguous(quint32 mask)
              {
                  for (;mask != 0; mask <<=1) {
                      if ((mask & (1<<31)) == 0)
                          return false; // Highest bit is now zero, but mask is non-zero.
                  }
                  return true; // Mask was, or became 0.
              }
              

              And calling it with your sample masks:

                  qDebug() << isContiguous(QHostAddress(QStringLiteral("255.255.255.0")).toIPv4Address());
                  qDebug() << isContiguous(QHostAddress(QStringLiteral("255.255.224.0")).toIPv4Address());
                  qDebug() << isContiguous(QHostAddress(QStringLiteral("255.224.0.0")).toIPv4Address());
                  qDebug() << isContiguous(QHostAddress(QStringLiteral("255.15.0.0")).toIPv4Address());
                  qDebug() << isContiguous(QHostAddress(QStringLiteral("255.255.88.0")).toIPv4Address());
                  qDebug() << isContiguous(QHostAddress(QStringLiteral("224.15.0.0")).toIPv4Address());
              

              Gives:

              true
              true
              true
              false
              false
              false
              

              Cheers.

              webzoidW Offline
              webzoidW Offline
              webzoid
              wrote on last edited by
              #6

              @Paul-Colby Thanks Paul, that looks like a neat little way to do it.

              kshegunovK 1 Reply Last reply
              0
              • webzoidW webzoid

                @Paul-Colby Thanks Paul, that looks like a neat little way to do it.

                kshegunovK Offline
                kshegunovK Offline
                kshegunov
                Moderators
                wrote on last edited by kshegunov
                #7

                As @jsulm pointed out, it should be rather trivial. Here's an example, but you need to modify and/or fix it, as I don't test my snippets:

                bool isContiguous(const QString & maskString)
                {
                    static const quint8 bits[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
                
                    quint32 mask = QHostAddress(maskString).toIPv4Address();
                
                    quint32 validity = ~(mask ^ ~(mask << 1));
                    char * data = reinterpret_cast<char *>(&validity);
                
                    quint8 raised = 0;
                    for (qint8 i = 0; i < sizeof(quint32); i++)
                        raised += bits[data[i] & 0x0f] + (bits[data[i] >> 4]);
                
                    return raised == 1;
                }
                

                PS.
                The idea of the above snippet is to count the "discontinuities" in the bit stream (hence the shift and xor in the beginning). Basically you should have only one single bit set in the validity integer to have a valid mask. More than one raised bit means the mask is not valid (i.e. more than one switch from 0 to 1 or 1 to 0). The loop on the bytes is just for more efficient bit counting. If your compiler supports it you can use the popcnt instruction instead of the whole for loop.
                gcc: __builtin_popcount
                msvc: __popcnt

                Read and abide by the Qt Code of Conduct

                1 Reply Last reply
                2

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved