Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. ip iterator code challenge

ip iterator code challenge

Scheduled Pinned Locked Moved C#
algorithmsdata-structurestools
14 Posts 3 Posters 1 Views 1 Watching
  • 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.
  • A Offline
    A Offline
    acecase
    wrote on last edited by
    #1

    I started on a project that I expected this to be a small part of, and I now realize that it is a huge undertaking. I thought it may be a fun exercise for those of you who are better than I, and it would be helpful to a lot of us to have. The idea is a class that can be used to iterate nmap style ip range input (eg. 192.168.45,47-50.0/24 or 172.16.*.10-25) and return a list of ip addresses in the given ranges. I started writing it as a TargetGroup class with the intention of being able to do something like... TargetGroup group = new TargetGroup("192.168.45,47-50.0/24"); string[] ips = group.IPAddresses(); ...And have an array, or list or whatever, containing all ip addresses. This has proven to be a pretty big deal to build reliably and efficiently. Also, after searching around a lot, I see that nothing like this exists. With such a great utility, and no availability, this would be a great contribution to the community. I can't spend any more time on it, and don't know that I could ever get it where it needs to be. However, if noone else jumps on it, I will revisit it as a project when I can concentrate souly on this class. For now I am going to finish the original project using a static target list with much simpler target definitions. If anyone chooses to tackle it, good luck. I'm sure I'm not the only person who would greatly appreciate it. I will not be responsible for any hair pulled out or sleep lost trying.

    2 U.S. coins equal 30 cents and one is NOT a nickle. Hmm..

    I B 2 Replies Last reply
    0
    • A acecase

      I started on a project that I expected this to be a small part of, and I now realize that it is a huge undertaking. I thought it may be a fun exercise for those of you who are better than I, and it would be helpful to a lot of us to have. The idea is a class that can be used to iterate nmap style ip range input (eg. 192.168.45,47-50.0/24 or 172.16.*.10-25) and return a list of ip addresses in the given ranges. I started writing it as a TargetGroup class with the intention of being able to do something like... TargetGroup group = new TargetGroup("192.168.45,47-50.0/24"); string[] ips = group.IPAddresses(); ...And have an array, or list or whatever, containing all ip addresses. This has proven to be a pretty big deal to build reliably and efficiently. Also, after searching around a lot, I see that nothing like this exists. With such a great utility, and no availability, this would be a great contribution to the community. I can't spend any more time on it, and don't know that I could ever get it where it needs to be. However, if noone else jumps on it, I will revisit it as a project when I can concentrate souly on this class. For now I am going to finish the original project using a static target list with much simpler target definitions. If anyone chooses to tackle it, good luck. I'm sure I'm not the only person who would greatly appreciate it. I will not be responsible for any hair pulled out or sleep lost trying.

      2 U.S. coins equal 30 cents and one is NOT a nickle. Hmm..

      I Offline
      I Offline
      Ian Shlasko
      wrote on last edited by
      #2

      Seems pretty straightforward, unless I'm missing something...

      public static IEnumerable<IPAddress> ParseIPAddressRange(string inputString)
      {
      string[] tokens = inputString.Split('.');
      foreach (IPAddress addr in ParseIPAddressRange(tokens, 0, string.Empty))
      yield return addr;
      }
      private static IEnumerable<IPAddress> ParseIPAddressRange(string[] tokens, int index, string partial)
      {
      if (index > 3)
      yield return IPAddress.Parse(partial);
      else if (index >= tokens.Length || tokens[index] == "*")
      {
      for (int x = 0; x < 256; x++)
      foreach (IPAddress addr in ParseIPAddressRange(tokens, index + 1, partial + "." + x.ToString()))
      yield return addr;
      }
      else
      {
      // Parse out tokens[index], append it to partial and recurse like above
      // This is just an exercise in string parsing... Easy.
      }
      }

      Proud to have finally moved to the A-Ark. Which one are you in?
      Author of the Guardians Saga (Sci-Fi/Fantasy novels)

      A 1 Reply Last reply
      0
      • A acecase

        I started on a project that I expected this to be a small part of, and I now realize that it is a huge undertaking. I thought it may be a fun exercise for those of you who are better than I, and it would be helpful to a lot of us to have. The idea is a class that can be used to iterate nmap style ip range input (eg. 192.168.45,47-50.0/24 or 172.16.*.10-25) and return a list of ip addresses in the given ranges. I started writing it as a TargetGroup class with the intention of being able to do something like... TargetGroup group = new TargetGroup("192.168.45,47-50.0/24"); string[] ips = group.IPAddresses(); ...And have an array, or list or whatever, containing all ip addresses. This has proven to be a pretty big deal to build reliably and efficiently. Also, after searching around a lot, I see that nothing like this exists. With such a great utility, and no availability, this would be a great contribution to the community. I can't spend any more time on it, and don't know that I could ever get it where it needs to be. However, if noone else jumps on it, I will revisit it as a project when I can concentrate souly on this class. For now I am going to finish the original project using a static target list with much simpler target definitions. If anyone chooses to tackle it, good luck. I'm sure I'm not the only person who would greatly appreciate it. I will not be responsible for any hair pulled out or sleep lost trying.

        2 U.S. coins equal 30 cents and one is NOT a nickle. Hmm..

        B Offline
        B Offline
        BillWoodruff
        wrote on last edited by
        #3

        While I can grasp what are your goal is, your use of delimiters is not clearly explained. How are "/" and "*" and "," being used, exactly in your expressions. My first reaction to this problem would be to "decompose" it into four calls to one procedure ... that take your range-building parameters as input ... that returns a List<int> for each of the four IP numbers, and then work on the combinatorial algorithm that generates the final list, from these four lists; which I would guess could be done using Linq. best, Bill

        "Anyone who shows me my 'blind spots' gives me the gift of sight." ... a thought from the shallows of the deeply shallow mind of ... Bill

        A 1 Reply Last reply
        0
        • I Ian Shlasko

          Seems pretty straightforward, unless I'm missing something...

          public static IEnumerable<IPAddress> ParseIPAddressRange(string inputString)
          {
          string[] tokens = inputString.Split('.');
          foreach (IPAddress addr in ParseIPAddressRange(tokens, 0, string.Empty))
          yield return addr;
          }
          private static IEnumerable<IPAddress> ParseIPAddressRange(string[] tokens, int index, string partial)
          {
          if (index > 3)
          yield return IPAddress.Parse(partial);
          else if (index >= tokens.Length || tokens[index] == "*")
          {
          for (int x = 0; x < 256; x++)
          foreach (IPAddress addr in ParseIPAddressRange(tokens, index + 1, partial + "." + x.ToString()))
          yield return addr;
          }
          else
          {
          // Parse out tokens[index], append it to partial and recurse like above
          // This is just an exercise in string parsing... Easy.
          }
          }

          Proud to have finally moved to the A-Ark. Which one are you in?
          Author of the Guardians Saga (Sci-Fi/Fantasy novels)

          A Offline
          A Offline
          acecase
          wrote on last edited by
          #4

          This is nice code. Good C# standard. It's a good start, but doesn't do what I was suggesting. It handles breaking the octets and *, but doesn't handle - ranges , ranges or /xx CIDR notation. I would like to see something that handles input as well as nmap Again, nice looking code though.

          2 U.S. coins equal 30 cents and one is NOT a nickle. Hmm..

          I 1 Reply Last reply
          0
          • B BillWoodruff

            While I can grasp what are your goal is, your use of delimiters is not clearly explained. How are "/" and "*" and "," being used, exactly in your expressions. My first reaction to this problem would be to "decompose" it into four calls to one procedure ... that take your range-building parameters as input ... that returns a List<int> for each of the four IP numbers, and then work on the combinatorial algorithm that generates the final list, from these four lists; which I would guess could be done using Linq. best, Bill

            "Anyone who shows me my 'blind spots' gives me the gift of sight." ... a thought from the shallows of the deeply shallow mind of ... Bill

            A Offline
            A Offline
            acecase
            wrote on last edited by
            #5

            I'm sorry. I didn't explain well. The , would be to say this,that (this AND that) The - would be to say this-that (this TO that) (1-3 = 1,2,3) The * would be to say all (1-254) The /xx would be CIDR notation eg. 192.168.0.0/24 would be 192.168.0.1 with a mask of 255.255.255.0, so it would be 192.168.0.1 - 192.168.0.254 eg2 10.96.248.0/22 would be 10.96.248.1 with a mask of 255.255.252.0, so it would be 10.96.248.1 - 10.96.249.254 Personally I don't know if I would include the option to use something like ; to include multiple ranges, or build with the intention of the user having multiple instances of the class; one for each range. If you want to see how useful it would be to handle ip ranges this way use nmap, or lookup some nmap examples. It would be a great class for network applications, or even a standalone application that would output text that could be piped to do things like ping sweeps. Windows is greatly lacking in this area. Thanks for the interest.

            2 U.S. coins equal 30 cents and one is NOT a nickle. Hmm..

            A 1 Reply Last reply
            0
            • A acecase

              I'm sorry. I didn't explain well. The , would be to say this,that (this AND that) The - would be to say this-that (this TO that) (1-3 = 1,2,3) The * would be to say all (1-254) The /xx would be CIDR notation eg. 192.168.0.0/24 would be 192.168.0.1 with a mask of 255.255.255.0, so it would be 192.168.0.1 - 192.168.0.254 eg2 10.96.248.0/22 would be 10.96.248.1 with a mask of 255.255.252.0, so it would be 10.96.248.1 - 10.96.249.254 Personally I don't know if I would include the option to use something like ; to include multiple ranges, or build with the intention of the user having multiple instances of the class; one for each range. If you want to see how useful it would be to handle ip ranges this way use nmap, or lookup some nmap examples. It would be a great class for network applications, or even a standalone application that would output text that could be piped to do things like ping sweeps. Windows is greatly lacking in this area. Thanks for the interest.

              2 U.S. coins equal 30 cents and one is NOT a nickle. Hmm..

              A Offline
              A Offline
              acecase
              wrote on last edited by
              #6

              One more note, in case I didn't explain well enough. The part that really added difficulty for me was the ability to add multiple delimiters to each octet so that I could say 192.168.0.1 194.168.0.1 195.168.0.1 196.168.0.1 by entering 192,194-196.168.0.1 This is valid input for nmap, but I don't know of any other application that will parse it correctly. Nmap uses about 600 lines of C code to accomplish it. I'm curious if C# would be more or less. My bet is less.

              2 U.S. coins equal 30 cents and one is NOT a nickle. Hmm..

              1 Reply Last reply
              0
              • A acecase

                This is nice code. Good C# standard. It's a good start, but doesn't do what I was suggesting. It handles breaking the octets and *, but doesn't handle - ranges , ranges or /xx CIDR notation. I would like to see something that handles input as well as nmap Again, nice looking code though.

                2 U.S. coins equal 30 cents and one is NOT a nickle. Hmm..

                I Offline
                I Offline
                Ian Shlasko
                wrote on last edited by
                #7

                That's the easy part. Either use some regular expressions, or just split the strings manually: 1) Split on commas, and parse each component individually 2) Split each component by dashes, and count from one number to the other, just like I counted from 0 to 255 3) Split by slashes, and do whatever calculation is needed for CIDR notation (Too lazy to look that up right now) Split() and int.Parse() can handle all of that.

                Proud to have finally moved to the A-Ark. Which one are you in?
                Author of the Guardians Saga (Sci-Fi/Fantasy novels)

                A 1 Reply Last reply
                0
                • I Ian Shlasko

                  That's the easy part. Either use some regular expressions, or just split the strings manually: 1) Split on commas, and parse each component individually 2) Split each component by dashes, and count from one number to the other, just like I counted from 0 to 255 3) Split by slashes, and do whatever calculation is needed for CIDR notation (Too lazy to look that up right now) Split() and int.Parse() can handle all of that.

                  Proud to have finally moved to the A-Ark. Which one are you in?
                  Author of the Guardians Saga (Sci-Fi/Fantasy novels)

                  A Offline
                  A Offline
                  acecase
                  wrote on last edited by
                  #8

                  Yeah. It's definitely just a lot of string manipulation, but to optimize it and make it reliable it's a much larger project than you would think until you start. I started this project thinking that this would be a small part of it. I see now that the IPAM application will be easier to complete than this part alone. At least at my skill level. I plan to make it a project of its own if noone beats me to it. At the moment the need is IPAM and I can get that done using a static list of simpler ip ranges. I can actually get the majority of my network with about 5 ranges as simple as xxx.xxx.xx-yy.0/24 xx.xx.xxx.0/22 and 172.16.0.0/16 That's easy. If you don't think it'll be tough to build "well", as the nmap folks have, you should give it a shot. :) Definitely doable, but it's a deceptive project.

                  2 U.S. coins equal 30 cents and one is NOT a nickle. Hmm..

                  I 1 Reply Last reply
                  0
                  • A acecase

                    Yeah. It's definitely just a lot of string manipulation, but to optimize it and make it reliable it's a much larger project than you would think until you start. I started this project thinking that this would be a small part of it. I see now that the IPAM application will be easier to complete than this part alone. At least at my skill level. I plan to make it a project of its own if noone beats me to it. At the moment the need is IPAM and I can get that done using a static list of simpler ip ranges. I can actually get the majority of my network with about 5 ranges as simple as xxx.xxx.xx-yy.0/24 xx.xx.xxx.0/22 and 172.16.0.0/16 That's easy. If you don't think it'll be tough to build "well", as the nmap folks have, you should give it a shot. :) Definitely doable, but it's a deceptive project.

                    2 U.S. coins equal 30 cents and one is NOT a nickle. Hmm..

                    I Offline
                    I Offline
                    Ian Shlasko
                    wrote on last edited by
                    #9

                    Deceptive? Hardly...

                    foreach (string component in tokens[index].Split(','))
                    {
                    if (component.Contains('-'))
                    {
                    string[] range = component.Split('-');
                    if (range.Length != 2) throw new ArgumentException();
                    int startRange, endRange;
                    if (int.TryParse(range[0], out startRange) && int.TryParse(range[1], out endRange) && startRange <= endRange)
                    for (int x = startRange; x <= endRange; x++)
                    foreach (IPAddress addr in ParseIPAddressRange(tokens, index + 1, partial + "." + x.ToString()))
                    yield return addr;
                    else
                    throw new ArgumentException();
                    }
                    else if (component.Contains('/')
                    {
                    // You should really be able to figure out the /xx notation on your own, given the above block.
                    }
                    }

                    Proud to have finally moved to the A-Ark. Which one are you in?
                    Author of the Guardians Saga (Sci-Fi/Fantasy novels)

                    A 2 Replies Last reply
                    0
                    • I Ian Shlasko

                      Deceptive? Hardly...

                      foreach (string component in tokens[index].Split(','))
                      {
                      if (component.Contains('-'))
                      {
                      string[] range = component.Split('-');
                      if (range.Length != 2) throw new ArgumentException();
                      int startRange, endRange;
                      if (int.TryParse(range[0], out startRange) && int.TryParse(range[1], out endRange) && startRange <= endRange)
                      for (int x = startRange; x <= endRange; x++)
                      foreach (IPAddress addr in ParseIPAddressRange(tokens, index + 1, partial + "." + x.ToString()))
                      yield return addr;
                      else
                      throw new ArgumentException();
                      }
                      else if (component.Contains('/')
                      {
                      // You should really be able to figure out the /xx notation on your own, given the above block.
                      }
                      }

                      Proud to have finally moved to the A-Ark. Which one are you in?
                      Author of the Guardians Saga (Sci-Fi/Fantasy novels)

                      A Offline
                      A Offline
                      acecase
                      wrote on last edited by
                      #10

                      I hope this doesn't read the wrong way because this truly is nicer code than what I have, and I appreciate you trying to help. However, I'm not asking for help as much as I am presenting a challenge that I hope to get time for and thought someone may like to play with. This would do what most people would need I'm sure, but what if you throw 172,10,159-162.0.0.1 at it? I don't have a windows box at home, so I can only guess by looking at it, but I don't think it would work. Should get 172.0.0.1 10.0.0.1 159.0.0.1 160.0.0.1 161.0.0.1 162.0.0.1 This looks like a crazy target range, but it is actually simpler than one that I use regularly to check gateway interfaces; with different numbers of course. The one that I actually use has a second and third octet that is about like this' first. If anyone is able to get something near as reliable, flexible, and optimized as what nmap has in under... say... 400 lines of code, I would say that would be amazing.

                      2 U.S. coins equal 30 cents and one is NOT a nickle. Hmm..

                      I 1 Reply Last reply
                      0
                      • A acecase

                        I hope this doesn't read the wrong way because this truly is nicer code than what I have, and I appreciate you trying to help. However, I'm not asking for help as much as I am presenting a challenge that I hope to get time for and thought someone may like to play with. This would do what most people would need I'm sure, but what if you throw 172,10,159-162.0.0.1 at it? I don't have a windows box at home, so I can only guess by looking at it, but I don't think it would work. Should get 172.0.0.1 10.0.0.1 159.0.0.1 160.0.0.1 161.0.0.1 162.0.0.1 This looks like a crazy target range, but it is actually simpler than one that I use regularly to check gateway interfaces; with different numbers of course. The one that I actually use has a second and third octet that is about like this' first. If anyone is able to get something near as reliable, flexible, and optimized as what nmap has in under... say... 400 lines of code, I would say that would be amazing.

                        2 U.S. coins equal 30 cents and one is NOT a nickle. Hmm..

                        I Offline
                        I Offline
                        Ian Shlasko
                        wrote on last edited by
                        #11

                        Yep, that would work with the code I posted... Notice it splits by commas first, then checks each term for hyphens... And since it works recursively, it can parse out those terms in any part of the address. Granted, I typed it directly into the reply and haven't tested it, so there might be typos, but the design should work. All it needs is the /xx section.

                        Proud to have finally moved to the A-Ark. Which one are you in?
                        Author of the Guardians Saga (Sci-Fi/Fantasy novels)

                        A 1 Reply Last reply
                        0
                        • I Ian Shlasko

                          Yep, that would work with the code I posted... Notice it splits by commas first, then checks each term for hyphens... And since it works recursively, it can parse out those terms in any part of the address. Granted, I typed it directly into the reply and haven't tested it, so there might be typos, but the design should work. All it needs is the /xx section.

                          Proud to have finally moved to the A-Ark. Which one are you in?
                          Author of the Guardians Saga (Sci-Fi/Fantasy novels)

                          A Offline
                          A Offline
                          acecase
                          wrote on last edited by
                          #12

                          I'm gonna have to check it out tomorrow. If that works, I'm very impressed and slightly ashamed. Thanks

                          2 U.S. coins equal 30 cents and one is NOT a nickle. Hmm..

                          1 Reply Last reply
                          0
                          • I Ian Shlasko

                            Deceptive? Hardly...

                            foreach (string component in tokens[index].Split(','))
                            {
                            if (component.Contains('-'))
                            {
                            string[] range = component.Split('-');
                            if (range.Length != 2) throw new ArgumentException();
                            int startRange, endRange;
                            if (int.TryParse(range[0], out startRange) && int.TryParse(range[1], out endRange) && startRange <= endRange)
                            for (int x = startRange; x <= endRange; x++)
                            foreach (IPAddress addr in ParseIPAddressRange(tokens, index + 1, partial + "." + x.ToString()))
                            yield return addr;
                            else
                            throw new ArgumentException();
                            }
                            else if (component.Contains('/')
                            {
                            // You should really be able to figure out the /xx notation on your own, given the above block.
                            }
                            }

                            Proud to have finally moved to the A-Ark. Which one are you in?
                            Author of the Guardians Saga (Sci-Fi/Fantasy novels)

                            A Offline
                            A Offline
                            acecase
                            wrote on last edited by
                            #13

                            I finally got a chance to look at it, and I think this could be expanded to work in well under the 400 lines that I mentioned before. I like it. As it is, as you know, it doesn't parse even the simplest x.x.x.x address, but it is cleaner and more efficient than my approach.

                            2 U.S. coins equal 30 cents and one is NOT a nickle. Hmm..

                            I 1 Reply Last reply
                            0
                            • A acecase

                              I finally got a chance to look at it, and I think this could be expanded to work in well under the 400 lines that I mentioned before. I like it. As it is, as you know, it doesn't parse even the simplest x.x.x.x address, but it is cleaner and more efficient than my approach.

                              2 U.S. coins equal 30 cents and one is NOT a nickle. Hmm..

                              I Offline
                              I Offline
                              Ian Shlasko
                              wrote on last edited by
                              #14

                              Yeah, I never got around to the simple case... That's just another else inside the comma split.

                              Proud to have finally moved to the A-Ark. Which one are you in?
                              Author of the Guardians Saga (Sci-Fi/Fantasy novels)

                              1 Reply Last reply
                              0
                              Reply
                              • Reply as topic
                              Log in to reply
                              • Oldest to Newest
                              • Newest to Oldest
                              • Most Votes


                              • Login

                              • Don't have an account? Register

                              • Login or register to search.
                              • First post
                                Last post
                              0
                              • Categories
                              • Recent
                              • Tags
                              • Popular
                              • World
                              • Users
                              • Groups