-1

So I've run into a quandary on sorting IPv4 addresses, and didn't know if there was a set rule in some obscure networking document. Do I do a straight sort on the raw address only (such as converting the IP address to a 32bit number and then sorting), do I factor in the CIDR via some mathematical formula, do I sort via the CIDR only (as if I'm comparing the network size and not the addresses directly)?

I.e., normal math, we'd do something like -1 < 0 < 1 to denote the order of precedence. Given say, 10.1.0.0/16, 172.16.0.0/12, 192.168.1.0/24, and 192.168.1.42, what would be the order of precedence?

Kumba
  • 620
  • 1
  • 5
  • 13
  • Can you clarify what you mean by "precedence"? IP addresses aren't members of the peerage; 13.5.4.64/32 isn't in any way that I know "better" than 194.168.4.100/32. More insight into what you're trying to do would be most helpful. – MadHatter Jan 12 '11 at 10:52
  • @MadHatter: I'm working on a VB.NET project in which I have a class that represents an IPv4 address. I'm trying to implement the IComparer(Of T) interface, in which I have to define a function that would sort my custom objects that the .NET Framework would invoke if needed. I have a question open on StackOverflow specifically pertaining to this. Here, on ServerFault, I figure more people familiar with the art/need of sorting network addresses might exist, so I'm posting this question in the hopes I get some guidance that will allow me to write the function that I need to sort IP addresses. – Kumba Jan 12 '11 at 11:05
  • FYI, the related SO question is [here](http://stackoverflow.com/questions/4665420/overriding-compareto-when-there-are-multiple-ways-to-compare-two-objects-of-the-s). – Kumba Jan 12 '11 at 11:05
  • 2
    IP addresses are not sortable any more than street addresses are. Would you sort "101 Johnson Avenue" before or after "28 Ocean Drive"? – ThatGraemeGuy Jan 12 '11 at 11:39
  • @Graeme: But there's still a method to the madness, even in postal addresses. I.e., in DC for example, numbered streets go north and south, lettered streets go east and west, and state avenues run diagonally. DC is subdivided into 4 quadrants, SE, NE, SW, NW. Blocks repeat in each quadrant, so a numerical address of the same number can exist on 16th St, both in SE and NE quadrants. This is a sane system that essentially "sorts" DC's layout in such a way that a person can, without a map, locate exactly where they are in the city using these rules. – Kumba Jan 12 '11 at 11:55
  • That still doesn't change the fact that IP addresses are not sortable in any meaningful, generalised manner. – ThatGraemeGuy Jan 12 '11 at 12:03
  • @Graeme: Then I'll invent one :) – Kumba Jan 12 '11 at 12:17

3 Answers3

6

You could sort IP adresses with the following command:

sort -n -t . -k 1,1 -k 2,2 -k 3,3 -k 4,4 ips.txt

What does this?

It uses sort with the -n parameter which tells sort we will be doing numerical sorting.

But our number is represented by 4 subnumbers (the actual octets of the ip adress) which are separated by the dot . (-t .). So let's go and sort, first by the first field, and only the first field (-k 1,1), then by the second and only the second (-k 2,2), and so on (-k 3,3 -k 4,4).

pacey
  • 3,833
  • 1
  • 16
  • 31
  • @pacey: What about the CIDR value? Is it a factor at all in the sorting? – Kumba Jan 12 '11 at 11:02
  • 5
    As I keep trying to say, *it depends*. If you want to sort by address, then no, it doesn't. If you want to sort by size of network, then yes, it's the only thing that matters. If you want to sort by some other criterion, then that criterion will matter. Your question seems to assume that there's one way of sorting addresses, handed down from the ancients; but there isn't. It all depends on what you're trying to do. PLEASE tell us what you're trying to achieve with this list; otherwise it's very hard to answer the question. – MadHatter Jan 12 '11 at 11:07
  • @MadHatter: Whoa, chill dude. I'm trying my best for someone whose been up for 16 hours and it being nearly 7am in the morning, k? I commented on Pacey's comment _before_ I responded to your comment above, so it's not like I'm ignoring you. You are right -- I made assumptions. We all do. Fact of life. Some are right, many are wrong. – Kumba Jan 12 '11 at 11:37
  • What I am trying to do is sort IPv4 addresses. Plain and simple. The question is, what's the accepted practice to do so when you're given different sets of data? Assume Data set #1 is a series of randomized IPv4 addresses, but they're all /32. That kind of a sort is straight forward. But assume data set #2 is not only a randomized set of IPv4 addresses, some of these addresses are also subnet identifiers, like 172.16.0.0/12. When facing a mix of /32 and non-/32 IP addresses, what's the preferred way to sort? – Kumba Jan 12 '11 at 11:39
  • Ignore the VB bit. The only thing you need to understand about that is I'm aiming to take whatever knowledge I glean from here and write a function in VB.NET that actually _implements_ the sort. Then, should my program ever encounter one of these data sets of randomized IPv4 addresses, it will actually know _how_ to sort them, based on the criterion I will design in the sorting function. – Kumba Jan 12 '11 at 11:41
  • 1
    I've said this before, but I end up using this sort command at *least* once a month. It always seems to impress. – Scott Pack Jan 12 '11 at 12:36
  • @pacey: I also wanted to thank you for a sensible answer here, even though it wasn't what I was after. You're not included in the group of people that apparently can't read and closed my question prematurely. – Kumba Jan 13 '11 at 03:08
  • Your question was closed because what you are attempting to do has no meaning. IP addresses are not sortable data. – ThatGraemeGuy Jan 13 '11 at 12:37
1

Oh, OK, so this is your CS homework?

Then sort any way you please; there's no technical reason to prefer one sorting scheme to another. Pacey's idea is good, but if you want to take account of mask as well, I'd probably sort by size of mask first, then use Pacey's scheme to order the addresses with the largest mask, then order those with the next-largest, down to ordering the /32s. It doesn't have any technical meaning, but it seems easier to justify than sorting by address and then deciding that 192.168.0.64/29 is somehow more important than 192.168.0.64/32.

MadHatter
  • 79,770
  • 20
  • 184
  • 232
  • CS Homework? Hah. No, this is a real project I'm working on. Sorting IPv4 (and eventually, IPv6) addresses is one tiny little speck in its overall design. – Kumba Jan 12 '11 at 11:44
  • The catch is, with the function I have to write, there's a set of rules I have to stick to, based on Microsoft's documentation. Assume I am comparing two IP addresses, A and B. The rules are: `If A < B, then return -1`. `If A == B, return 0`. `If A > B, return 1`. – Kumba Jan 12 '11 at 11:47
  • If I just compare the addresses directly, then writing that function is easy. If that's the normal method (accepted or not...there's GOT to me some general/default way people defer to in sorting IP addresses), then that's what I'll use and ignore the CIDR mask. But IF it happens that sorting by CIDR first (or last, or whatever), THEN by address (or vice versa) is a better way, I need to understand it so I can translate that understanding into code. Obviously, SF is not geared for code-asking questions. BUT people here are more schooled in networks and addresses...hence the question. – Kumba Jan 12 '11 at 11:50
  • 1
    You say "there's GOT to [be] some general/default way people defer to in sorting IP addresses". Hopefully it's clear from the upvotes some of these comments are getting that there really isn't. How you sort depends on what you what to achieve. Since you keep refusing to tell us this, I for one really can't help. – MadHatter Jan 12 '11 at 12:05
  • @MadHatter: "Refusing"? Now your the one drawing assumptions here. I'm not refusing to tell you anything. I've told you _exactly_ what I want to do. If I'm not articulating it enough, then what points are you still scratching your head over? Again, chill. This isn't worth getting frustrated over. – Kumba Jan 12 '11 at 12:12
  • And if there isn't a generalized method, then sorry, but those are the words I chose to use, even if they were words in error. How else should I have asked the question? General rule of thumb is that humans, when faced with an obstacle of some nature, default to one or more actions to overcome the obstacle. Everyone does something a little bit differently, but largely, they ALL use a "generalized" method of sorts. You might climb over the obstacle with a piece of rope. I might drive through it with a backhoe. The "generalized" method is to get past the obstacle in some fashion. – Kumba Jan 12 '11 at 12:16
  • 2
    Let me just clarify this for future generations of readers. When you're asked **what** you want to do, it's a big picture question. What's the underlying need you're trying to solve? The details of a proposed solution aren't **what** you're trying to do, they're **how** you're trying to do it. This isn't homework for you, there's a business need at the back of this, and that will most likely determine how it makes most sense to sort. What I wanted to know is what was the underlying business need, not the technical details of how you're trying to satisfy that need. – MadHatter Jan 12 '11 at 12:40
  • @MadHatter: Thanks for putting the point on this. If we understood WHY the OP needs to sort the ip addresses then we might be able to give him some insight into HOW to sort them to achieve his goals. – joeqwerty Jan 12 '11 at 13:23
  • Ya'll are rude. You know that? The **WHY** is because I I need the **ABILITY** to. I'm not doing this in Excel or Access like a network admin might do in order to sort their local netblocks. I was ASKING what's a generalized approach or criteria used by people to sort IP addresses so that I can write a function that implements the sort. I had to go to bed so I could tackle this problem on a fresh mind. But you all come in and close it because you can't read? Shame on you all. – Kumba Jan 12 '11 at 20:37
  • Really, all you people (I'm talking specifically you, @MadHatter), just had to tell me what's the most commonly-used method. If by your own experience, you sort numerically (disregarding the CIDR mask entirely), then you should have just stated that and gotten the points. You guys made the question more complicated by quizzing me for additional details. Granted, I could've cut back on my own detail some, but well, that's my fault. – Kumba Jan 12 '11 at 20:40
1

The last time I did this, I implemented it roughly like this (validation and error checking elided for clarity):

(addressA, maskA) = split('/', a);
(addressB, maskB) = split('/', b);
ipCmp = inet_aton(addressB) - inet_aton(addressA);
if (ipCmp > 0) {
    return -1;
} else if (ipCmp < 0) {
    return 1;
} else {
    if (maskA < maskB) {
        return 1;
    } else if (maskA > maskB) {
        return -1;
    } else {
        return 0;
    }
}

Given the input array { 10.0.1.0/24, 10.0.0.0/24, 10.0.0.0/8 } this should produce { 10.0.0.0/8, 10.0.0.0/24, 10.0.1.0/24 }.

Edit to add: There is no "commonly accepted" method that I know of, the above is simply the method which was most useful for the task I had to accomplish. The reason for using inet_aton is that IP addresses are just ints formatted slightly differently. Compare them as ints and you get a useful ordering.

Conor McDermottroe
  • 948
  • 1
  • 7
  • 17
  • Thank you. This is closer to what I was looking for. Maybe I should've just stuck to asking on SO instead of here.... anyways, I'll analyze your approach later on. VB uses signed integers, so my version of inet_aton returns a number somewhat differently than what C or even PHP will return, and I have to alter my checks slightly to account. – Kumba Jan 12 '11 at 12:21
  • 1
    You're getting the points for this because you gave the most sensible answer here. Thank you. – Kumba Jan 12 '11 at 20:41