標籤:linux vim
前言
題目說的有點長,其實就是以下幾件事,第一是讓Shell命令可以在程式內執行,然後將執行結果傳遞給變數,從而可以進行後續的交易處理,第二是使用nmap命令擷取當前區域網路內所有線上IP和開放的連接埠,最後就是對nmap獲得的結果進行處理,得到只有IP和連接埠的結果。
Linux命令列的強大功能相信使用Linux的人都知道,一個命令等於你在windows用幾百行甚至上千行的代碼量才能實現,所以,如果很好的利用shell命令,可以說是事半功倍。
而要充分利用shell的結果,必然是需要獲得可以處理的命令返回結果。
程式內執行Shell命令
主要是利用以下的函數:
函數定義:
#include <stdio.h>FILE * popen(const char *command , const char *type );int pclose(FILE *stream);
函數說明:
popen()函數通過建立一個管道,調用fork()產生一個子進程,執行一個shell以運行命令來開啟一個進程。這個管道必須由pclose()函數關閉,而不是fclose()函數。pclose()函數關閉標準I/O流,等待命令執行結束,然後返回shell的終止狀態。如果shell不能被執行,則pclose()返回的終止狀態與shell已執行exit一樣。
type參數只能是讀或者寫中的一種,得到的返回值(標準I/O流)也具有和type相應的唯讀或唯寫類型。如果type是"r"則檔案指標串連到command的標準輸出;如果type是"w"則檔案指標串連到command的標準輸入。
command參數是一個指向以NULL結束的shell命令字串的指標。這行命令將被傳到bin/sh並使用-c標誌,shell將執行這個命令。
popen()的返回值是個標準I/O流,必須由pclose來終止。前面提到這個流是單向的(只能用於讀或寫)。向這個流寫內容相當於寫入該命令的標準輸入,命令的標準輸出和調用popen()的進程相同;與之相反的,從流中讀資料相當於讀取命令的標準輸出,命令的標準輸入和調用popen()的進程相同。
返回值:
如果調用fork()或pipe()失敗,或者不能分配記憶體將返回NULL,否則返回標準I/O流。popen()沒有為記憶體配置失敗設定errno值。如果調用fork()或pipe()時出現錯誤,errno被設為相應的錯誤類型。如果type參數不合法,errno將返回EINVAL。
使用方法:
//execute shell command//執行一個shell命令,輸出結果逐行儲存在resvec中,並返回行數int32_t myexec(const char *cmd, vector<string> &resvec) { resvec.clear(); FILE *pp = popen(cmd, "r"); //建立管道 if (!pp) { return -1; } char tmp[1024]; //設定一個合適的長度,以儲存每一行輸出 while (fgets(tmp, sizeof(tmp), pp) != NULL) { if (tmp[strlen(tmp) - 1] == '\n') { tmp[strlen(tmp) - 1] = '\0'; //去除分行符號 } resvec.push_back(tmp); } pclose(pp); //關閉管道 return resvec.size();}
使用nmap擷取所有線上IP和開放連接埠
強大的nmap,具體介紹網上太多了,附上官網http://nmap.org/ ,使用以下命令
nmap -sT 192.168.1.0/24
對C類網段進行掃描,得到結果圖,格式,查看格式可以方便後續對結果的處理:
如果是B類網段,則改成:
nmap -sT 192.168.*.*/24
對結果進行處理
處理的目標主要是要直接獲得IP地址和對應的連接埠號碼,儲存到向量數組中,然後方便後續的處理,處理代碼如下:
int32_t get_ip_port( vector<string> input,map<string,vector<string> > &result){ result.clear(); vector<string>::iterator it=input.begin(); int flag=0; while(it!=input.end()) { if((*it)[0]!='\0') { flag++; if(flag==1) { //get IP address and push_back a pair to reslut vector<string> tmp; const char* IP=new char(24); IP=it->data()+21; result.insert(pair<string,vector<string> >(IP,tmp)); } else if(flag==2||3) { //skip } else { //get port information map<string,vector<string> >::iterator itt=result.end(); char Port[5]; const char* p=new char(5); p=it->data(); for(int i=0;i<5;i++) { if((*p)!='/') { Port[i]=*p; p++; } else break; } itt->second.push_back(Port); } ++it; } else { flag=0; ++it; } } return 1;}
目前處理起來速度是比較慢的,後續看是否可以對速度有所提升,歡迎交流。雖然這些網路的識別技術對於做系統的開發人員來說非常有用,但是同時也給了惡意駭客們很多機會,所以有利有弊。
轉載請註明出處:http://blog.csdn.net/luoyun614/article/details/42967695
程式內執行shell命令自動擷取區域網路內所有線上IP和開放連接埠(Linux)