scottish_jason Posted October 7, 2012 Share Posted October 7, 2012 (edited) 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 October 7, 2012 by scottish_jason Quote Link to comment Share on other sites More sharing options...
derwert Posted October 7, 2012 Share Posted October 7, 2012 (edited) 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 October 7, 2012 by derwert Quote Link to comment Share on other sites More sharing options...
scottish_jason Posted October 7, 2012 Author Share Posted October 7, 2012 thanks very much for the reply, im not entirely sure how this code works but I will try it. Will this also work if the string has more switches? and I assume I just call these variables with $args[A] etc? Quote Link to comment Share on other sites More sharing options...
Jessica Posted October 7, 2012 Share Posted October 7, 2012 Did you try? Quote Link to comment Share on other sites More sharing options...
scottish_jason Posted October 7, 2012 Author Share Posted October 7, 2012 Did you try? yes I have managed to get the array printed out with the correct entries. Just need to call them in the appropriate table cells now. Thanks guys Quote Link to comment Share on other sites More sharing options...
scottish_jason Posted October 7, 2012 Author Share Posted October 7, 2012 (edited) edit: got it thanks Edited October 7, 2012 by scottish_jason Quote Link to comment Share on other sites More sharing options...
scottish_jason Posted October 7, 2012 Author Share Posted October 7, 2012 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]"; Quote Link to comment Share on other sites More sharing options...
Jessica Posted October 7, 2012 Share Posted October 7, 2012 echo $parsedarray['-state']; Quote Link to comment Share on other sites More sharing options...
scottish_jason Posted October 7, 2012 Author Share Posted October 7, 2012 echo $parsedarray['-state']; yeah just thought of that, thanks alot Quote Link to comment Share on other sites More sharing options...
derwert Posted October 7, 2012 Share Posted October 7, 2012 (edited) 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: http://us.php.net/ma...cre.pattern.php www.regular-expressions.info Edited October 7, 2012 by derwert Quote Link to comment Share on other sites More sharing options...
scottish_jason Posted October 10, 2012 Author Share Posted October 10, 2012 (edited) 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 October 10, 2012 by scottish_jason Quote Link to comment Share on other sites More sharing options...
derwert Posted October 10, 2012 Share Posted October 10, 2012 (edited) What have you tried so far? Check out: http://us.php.net/ma...cre.pattern.php www.regular-expressions.info Edited October 10, 2012 by derwert Quote Link to comment Share on other sites More sharing options...
derwert Posted October 11, 2012 Share Posted October 11, 2012 (edited) 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 October 11, 2012 by derwert Quote Link to comment Share on other sites More sharing options...
scottish_jason Posted October 11, 2012 Author Share Posted October 11, 2012 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 Quote Link to comment Share on other sites More sharing options...
DarkerAngel Posted October 11, 2012 Share Posted October 11, 2012 (edited) 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 October 11, 2012 by DarkerAngel Quote Link to comment Share on other sites More sharing options...
derwert Posted October 11, 2012 Share Posted October 11, 2012 (edited) 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 October 11, 2012 by derwert Quote Link to comment Share on other sites More sharing options...
derwert Posted October 11, 2012 Share Posted October 11, 2012 (edited) 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 October 11, 2012 by derwert Quote Link to comment Share on other sites More sharing options...
DarkerAngel Posted October 11, 2012 Share Posted October 11, 2012 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. Quote Link to comment Share on other sites More sharing options...
scottish_jason Posted October 11, 2012 Author Share Posted October 11, 2012 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! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.