pi@desktoppi ~ $ sudo apt-get install libcurl4-openssl-dev
Also the example below is written in C++11, so you will need to install g++-4.7, which supports C++11.
pi@desktoppi ~ $ sudo apt-get install g++-4.7
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | // MycURL.hpp written by Jae Hyuk Kwak namespace MycURLNS { class MycURL { unique_ptr< CURL, decltype( curl_easy_cleanup )* > curl_; public: MycURL() : curl_( curl_easy_init(), curl_easy_cleanup ) { if ( nullptr == curl_ ) throw runtime_error( "curl_easy_init() failed." ); } CURL *native() { return curl_.get(); } }; template< typename ParamType > void SetOpt_( MycURL *mycURL, CURLoption option, const ParamType ¶m ) { CURLcode res = curl_easy_setopt( mycURL->native(), option, param ); if ( CURLE_OK != res ) throw runtime_error( string( "curl_easy_setopt() failed." ) + curl_easy_strerror( res ) ); } void SetOpt_URL( MycURL *mycURL, const string url ) { SetOpt_( mycURL, CURLOPT_URL, url.c_str() ); } void SetOpt_USERPWD( MycURL *mycURL, const string user, const string pwd ) { SetOpt_( mycURL, CURLOPT_USERPWD, ( user + ":" + pwd ).c_str() ); } size_t WriteMemoryCallback_( void *contents, size_t size, size_t numberOfMemoryBlocks, void *userChunk ) { const size_t realSize = size * numberOfMemoryBlocks; string &html = *static_cast< string * >( userChunk ); html += string( static_cast< char * >( contents ), realSize ); return realSize; } string RequestGet( MycURL *mycURL ) { string html; SetOpt_( mycURL, CURLOPT_WRITEDATA, &html ); SetOpt_( mycURL, CURLOPT_WRITEFUNCTION, WriteMemoryCallback_ ); const CURLcode res = curl_easy_perform( mycURL->native() ); if ( CURLE_OK != res ) throw runtime_error( string( "curl_easy_perform() failed: " ) + curl_easy_strerror( res ) ); return html; } } |
The source code above is a wrapping class for libcurl easy-functions. You can find document from here. There are three functions from libcurl:
- curl_easy_init() : will create an handle for CURL,
- curl_easy_setopt() : will allow us to set options such as user id and URL and
- curl_easy_perform() : will allow us to execute whatever options you set.
There are several options with curl_easy_setopt() and that was little tricky part:
- CURLOPT_URL : is for setting the URL,
- CURLOPT_USERPWD : is for setting user ID and Password,
- CURLOPT_WRITEFUNCTION : is to set a function pointer that will be called when HTML data is retrieved.
- CURLOPT_WRITEDATA : is to set a data point which will be used by a function set with CURLOPT_WRITEFUNCTION.
The source code also reveals my C++ programming style little bit.
- I like to have private member variable and methods to have "_" at the end of the name.
- I almost always hold member pointer with shared_ptr or unique_ptr; when I return the pointer to users, I return the raw-pointer not the share_ptr or unique_ptr so that the ownership remains.
- I use a lot of exceptions because it makes source code simpler.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | // public_ip.cpp written by Jae Hyuk Kwak #include "stdafx.h" #include "MycURL.hpp" #include "config.hpp" using namespace Configuration; using namespace MycURLNS; int main( int argn, const char *argv[] ) { curl_global_init( CURL_GLOBAL_ALL ); // required once const string html = []() // lamda with C++11 { MycURL curl; SetOpt_URL( &curl, URL ); SetOpt_USERPWD( &curl, ID, PW ); //SetOpt_( &curl, CURLOPT_VERBOSE, 1 ); return RequestGet( &curl ); }(); // find and filter "<td>IP Address</td><td><b>XX.XX.XX.XX</b>" stringstream ss( [&]() { const size_t offset0 = html.find( "IP Address" ); const size_t offset1 = html.find_first_of( "0123456789", offset0 ); return ( html.c_str() + offset1 ); }() ); char dot; int ip0, ip1, ip2, ip3; ss >> ip0 >> dot >> ip1 >> dot >> ip2 >> dot >> ip3; cout << ip0 << "." << ip1 << "." << ip2 << "." << ip3 << endl; return 0; } |
1 2 3 4 5 6 7 | // stdafx.h written by jae hyuk kwak. #include <stdexcept> // runtime_exception #include <memory> // unique_ptr #include <iostream> // cerr, cout #include <curl/curl.h> #include <sstream> // stringstream using namespace std; |
1 2 3 4 5 6 7 | // config.hpp written by Jae Hyuk Kwak namespace Configuration { static const string ID = "admin"; // modify this for your setting static const string PW = "your_password"; // modify this static const string URL = "http://192.168.0.1/RgSetup.asp"; // modify this } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | # Makefile written by Jae Hyuk Kwak CC=g++-4.7 CFLAGS=-Wall -g -std=c++11 all: public_ip public_ip: *.hpp public_ip.cpp stdafx.h.gch $(CC) $(CFLAGS) -o public_ip -lcurl public_ip.cpp stdafx.h.gch: stdafx.h $(CC) $(CFLAGS) -c stdafx.h clean: rm stdafx.h.gch public_ip |
I am using -std=c++11, which is supported only by 4.7 at the moment of writing this post.
*Note: don't be confused with gcc-4.7, which is C compiler not C++ compiler.
The Makefile uses pre-compiled-header, which improves a lot of compile time; the compiled file from the pre-compile-header is 14MB, which is very large.
pi@desktoppi ~/prog/MycURL $ make g++-4.7 -Wall -g -std=c++11 -c stdafx.h g++-4.7 -Wall -g -std=c++11 -o public_ip -lcurl public_ip.cpp pi@desktoppi ~/prog/MycURL $ ./public_ip 68.6.129.115 pi@desktoppi ~/prog/MycURL $
You will get the executable, public_ip.
After you have logged into the Arris admin interface you should have the ability to change any settings here that are readily available.
ReplyDelete