Jump to content

Parsing String Into Several Variables


scottish_jason

Recommended Posts

hi guys, ive spent a good amount of time researching how to parse linux iptables rules into seperate variables so I can use each variable inside appropriate cells inside a table, but without any luck . For example, a possible string could be:

 

$string = "-A INPUT -s 192.168.0.1 -p TCP -j DROP"

 

I want to be able to put:

 

"192.168.0.1" into a $source variable

"TCP" into a $protocol variable

"DROP" into a $jump variable

 

I was thinking about doing an explode splitting each word up using the "space" and then doing if $explode[2] = "-s" then $source = $explode[3] type thing but I would have to check for each available switch on every array number (if you know what I mean). Is there a more efficient way of doing this?

Edited by scottish_jason
Link to comment
Share on other sites

There are many ways you could do this, one being regular expressions. See my example below:

 

<?php
$string = "-A INPUT -s 192.168.0.1 -p TCP -j DROP";
print_r (parse_args($string));

function parse_args($raw_args){
   $pattern = "~\-(.*?)[\x20]+([\S]+)~";
   $args = array();

   if(preg_match_all($pattern, $raw_args, $matches) === FALSE){
    return FALSE;
   }else{
    $args = array_combine($matches[1], $matches[2]);
    return $args;
   }
}


?>

 

The results would be:

 

Array
(
[A] => INPUT
[s] => 192.168.0.1
[p] => TCP
[j] => DROP
)

Edited by derwert
Link to comment
Share on other sites

The only problem I have now is that some of the switches contain two -- characters such as " --state " and I seem to be having problems using the likes of :

 

echo "$parsedarray[-state]";

 

Change the pattern to:

$pattern = "~[\-]{1,2}(.*?)[\x20]+([\S]+)~";

 

Check out:

Edited by derwert
Link to comment
Share on other sites

What about parsing these bold sections into variables... The string can and will change though, depending upon how many host's nmap picks up ( 4 in this case ) and also like in this example the last mac address for 192.168.0.8 was not picked up, but I would need a blank entry for that array so that the ip and mac array numbers correspond. I dont expect an answer, im willing to research and try to figure things out for myself but pointing me in the right direction would be great.

 

for example:

 

$IP[0] = "192.168.0.1"

$IP[1] = "192.168.0.2"

$IP[2] = "192.168.0.4"

$IP[3] = "192.168.0.8"

$MAC[0] = "00:00:00:00:00:01"

$MAC[1] = "00:00:00:00:00:02"

 

$MAC[2] = "00:00:00:00:00:03"

$MAC[3] = " "

 

 

Starting Nmap 5.21 ( http://nmap.org ) at 2012-10-10 20:53 BST Nmap scan report for 192.168.0.1 Host is up (0.0055s latency). MAC Address: 00:00:00:00:00:01 (Unknown) Nmap scan report for 192.168.0.2 Host is up (0.00019s latency). MAC Address: 00:00:00:00:00:02 (DFI) Nmap scan report for 192.168.0.4 Host is up (0.0043s latency). MAC Address: 00:00:00:00:00:03 (Unknown) Nmap scan report for 192.168.0.8 Host is up. Nmap done: 256 IP addresses (4 hosts up) scanned in 5.37 seconds

Edited by scottish_jason
Link to comment
Share on other sites

While I do recommend you get more familiar with regular expressions and practice it, it can be very useful. I had a light bulb go off while I was browsing other posts that reminded that nmap outputs to various formats.

See this link for the documentation of nmap output http://nmap.org/book/man-output.html

nmap supports outputting to XML which given your requirements would be the most straight forward way to handle this.

 

On a off note, if it helps you understand regular expressions better if you want me to explain in more detail what the original code I posted does then let me know and I will.

Edited by derwert
Link to comment
Share on other sites

While I do recommend you get more familiar with regular expressions and practice it, it can be very useful. I had a light bulb go off while I was browsing other posts that reminded that nmap outputs to various formats.

See this link for the documentation of nmap output http://nmap.org/book/man-output.html

nmap supports outputting to XML which given your requirements would be the most straight forward way to handle this.

 

On a off note, if it helps you understand regular expressions better if you want me to explain in more detail what the original code I posted does then let me know and I will.

 

Hi derwert, thanks for the reply..... I have managed to get so far with this problem. I am able to get the information I need into array's but one problem now exists. When I do my nmap scan it does not return the mac address for my local machine, which means my IP and mac array's become out of sync because one of the mac addresses are not stored meaning the mac array is one number behind the ip array ( when it gets to the point where my local machine does not return the mac address ). This is what I have tried:

 

$string = shell_exec ('sudo nmap -sP 192.168.0.0/24');

 

preg_match_all("/\d{1,3{\.\d{1,3}\.\d{1,3}\.\d{1,3}/", $string, $ip);

preg_match_all("/((?:[0-9a-f]{2}[:-]{5}[0-9a-f]{2})/i", $string, $mac);

 

print_r($ip);

print_r($mac);

 

I get the following arrays out. p.s. I have no idea why it prints the mac array out twice but I dont think that should be a problem. But anyway, as you can see im missing the mac address for 0.8 so my ip and mac arrays are out of sync ie. ip[2] does not refer to mac[2]

 

Array ( [0] => Array ( [0] => 192.168.0.1 [1] => 192.168.0.2 [2] => 192.168.0.8 ) )

Array ( [0] => Array ( [0] => A0:21:B7:06:20:67 [1] => 00:01:29:A4:47:F2 ) [1] => Array ( [0] => A0:21:B7:06:20:67 [1] => 00:01:29:A4:47:F2 )i

Link to comment
Share on other sites

When I do regex I tend to try to get the information set in a singular expression as much as possible, my method may be considered messy but it does keep the IP's + MAC Addresses in sync (by sacrificing the host IP) and match the data properly from the format you provided.

 

I use named backreferences in my regex a lot too...

 

Here's mine:

preg_match_all('/(?P<mac>[\d:]{17}).+?r (?P<ip>[\d.]*)/s', $subject, $result);

 

so $result['ip'][1] should always reference $result['mac'][1]

Edited by DarkerAngel
Link to comment
Share on other sites

When I do regex I tend to try to get the information set in a singular expression as much as possible, my method may be considered messy but it does keep the IP's + MAC Addresses in sync (by sacrificing the host IP) and match the data properly from the format you provided.

 

I use named backreferences in my regex a lot too...

 

Here's mine:

preg_match_all('/(?P<mac>[\d:]{17}).+?r (?P<ip>[\d.]*)/s', $subject, $result);

 

so $result['ip'][1] should always reference $result['mac'][1]

 

DarkerAngel, your regular expression does not work correctly, re-read the requirements in the post and look at the results of your regex.

 

Jason, you quoted my post but it doesn't seem like you read it. I'll quote it below for your convenience.

 

While I do recommend you get more familiar with regular expressions and practice it, it can be very useful. I had a light bulb go off while I was browsing other posts that reminded that nmap outputs to various formats.

See this link for the documentation of nmap output http://nmap.org/book/man-output.html

nmap supports outputting to XML which given your requirements would be the most straight forward way to handle this.

Edited by derwert
Link to comment
Share on other sites

Here is a quick and dirty regular expression if you insist on not using the XML output

 

    $pattern  = '~';
    $pattern .= 'Nmap scan report for (.*?)\n';
    $pattern .= 'Host(?:.*?)\n';
    $pattern .= '(?:MAC Address\: ([0-9A-F]{2}\:[0-9A-F]{2}\:[0-9A-F]{2}\:[0-9A-F]{2}\:[0-9A-F]{2}\:[0-9A-F]{2}) (?:.*?)\\n)?';
    $pattern .= '~m';

 

This is assuming your output is standard output from nmap which has a \n after each line of output.

 

So if the sample input was:

 

Starting Nmap 5.21 ( http://nmap.org ) at 2012-10-10 20:53 BST
Nmap scan report for 192.168.0.1
Host is up (0.0055s latency).
MAC Address: 00:00:00:00:00:01 (Unknown)
Nmap scan report for 192.168.0.2
Host is up (0.00019s latency).
MAC Address: 00:00:00:00:00:02 (DFI)
Nmap scan report for 192.168.0.4
Host is up (0.0043s latency).
MAC Address: 00:00:00:00:00:03 (Unknown)
Nmap scan report for 192.168.0.8
Host is up.
Nmap scan report for 192.168.0.10
Host is up (0.0043s latency).
MAC Address: 00:00:00:00:00:10 (Unknown)
Nmap done: 256 IP addresses (4 hosts up) scanned in 5.37 seconds

 

The output would be:

 

Array
(
[0] => Array ( ~ Edited out ~ )

[1] => Array
(
[0] => 192.168.0.1
[1] => 192.168.0.2
[2] => 192.168.0.4
[3] => 192.168.0.8
[4] => 192.168.0.10
)

[2] => Array
(
[0] => 00:00:00:00:00:01
[1] => 00:00:00:00:00:02
[2] => 00:00:00:00:00:03
[3] =>
[4] => 00:00:00:00:00:10
)

)

Edited by derwert
Link to comment
Share on other sites

Ok so I got the format of the nmap output incorrect (reversed, I hadn't seen it before and based on what he pasted I thought the "." ended the result set, and I forgot the alpha characters in the MAC address, the just numbers threw me off because it matched correctly in my tester.)

 

Here I rewrote mine:

preg_match_all('/report.+?(?P<ip>(?:[\d.]{2,4}){4}).+?(?:Mac.+?: (?P<mac>[\da-f:]{17})|Nmap)/si', $subject, $result)

 

Result: [Ran against dewerts sample input]

Array
(
   [0] => Array ( ~full matches inc. irrelevant data~ )

   [ip] => Array
       (
           [0] => 192.168.0.1
           [1] => 192.168.0.2
           [2] => 192.168.0.4
           [3] => 192.168.0.8
           [4] => 192.168.0.10
       )

   [1] => Array
       (
           [0] => 192.168.0.1
           [1] => 192.168.0.2
           [2] => 192.168.0.4
           [3] => 192.168.0.8
           [4] => 192.168.0.10
       )

   [mac] => Array
       (
           [0] => 00:00:00:00:00:01
           [1] => 00:00:00:00:00:02
           [2] => 00:00:00:00:00:03
           [3] => 
           [4] => 00:00:00:00:00:10
       )

   [2] => Array
       (
           [0] => 00:00:00:00:00:01
           [1] => 00:00:00:00:00:02
           [2] => 00:00:00:00:00:03
           [3] => 
           [4] => 00:00:00:00:00:10
       )

)

 

Mine's working the same way, but Like I said, I'm a fan of named backref's so the backref's appear twice, named and indexed id.

Link to comment
Share on other sites

DarkerAngel, your regular expression does not work correctly, re-read the requirements in the post and look at the results of your regex.

 

Jason, you quoted my post but it doesn't seem like you read it. I'll quote it below for your convenience.

 

derwert, thanks again. I did read your post and your right, I probably should go down the XML route, thanks for reminding me of that output functionality. On the other hand though I had been working on the regular expression for quite a while and was mostly wanting to learn how you could do it with that method for future programming/regular expression needs, and also it was bugging me! hehe. But anyway, thanks for all the help. Im starting to understand regular expressions but will go down the XML route!

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.