{"id":372,"date":"2016-09-27T21:59:20","date_gmt":"2016-09-27T20:59:20","guid":{"rendered":"http:\/\/www.troliver.com\/?p=372"},"modified":"2017-07-07T11:57:13","modified_gmt":"2017-07-07T10:57:13","slug":"uploading-data-to-a-webserver-part-1-cc-and-curl","status":"publish","type":"post","link":"https:\/\/www.troliver.com\/?p=372","title":{"rendered":"Uploading data to a webserver Part 1 &#8211; C\/C++ and CURL"},"content":{"rendered":"<p><a href=\"http:\/\/www.troliver.com\/?p=348\">Following on from the last post on the\u00a0topic of capturing packet data from a network<\/a>, this guide\u00a0demonstrates how you can use a cURL library to upload data from\u00a0an application written in C (or C++) to a webserver.\u00a0Although at times I refer to previous examples, you can use this in\u00a0any number of applications.<\/p>\n<p>This will touch on\u00a0a number of areas and require a little more\u00a0prep work\u00a0than previous examples, due to needing a few extra libraries and a server running PHP and SQL.\u00a0In a nutshell, you have to cobble together a string with all your data in, send it along to your\u00a0server with a request and then have that server do something with it.\u00a0The steps covered are:<\/p>\n<ol>\n<li>(Setup) LAMP server and database<\/li>\n<li>(Client)\u00a0Generate a URL string from variables in your program<\/li>\n<li>(Client) Send a web request to the URL generated in step 1<\/li>\n<li>(Server) Process the uploaded string to retrieve values from data<\/li>\n<li>(Server) Store the data as a new record in a database<\/li>\n<\/ol>\n<p>Finally, there are some really quick and horrible things that I do here, with minimal catching of errors, but the purpose is to show the process from start to finish as briefly as possible!<\/p>\n<h2>Environment<\/h2>\n<p>First of all, its worth mentioning the set-up I am using for this system. Just to demonstrate, I have a\u00a0<strong>LAMP server<\/strong> running on <strong>Ubuntu<\/strong>\u00a0with\u00a0a\u00a0<strong>MySQL<\/strong>\u00a0<strong>database. <\/strong>I won&#8217;t cover how to actually get as far as having those running because there&#8217;s plenty of articles that explain how to do that. The only other thing you may want to use is <strong>phpMyAdmin<\/strong>, as this makes database management via a web UI much easier than just command line interaction. It also helps hugely to understand basics of HTML\/PHP &#8211; but you may well be able to stumble through this if you&#8217;ve never touched either before!<\/p>\n<h2>Setup<\/h2>\n<h3>Database Table<\/h3>\n<p>The first thing to do\u00a0is to create a new table to store the records in. This may as well just be a spreadsheet at this point, but later on I will be talking about queries and combining\u00a0data from different tables. You can either create a new table with phpMyAdmin by selecting the appropriate settings from the code below or you can simply copy and paste the entire thing into an SQL query box and run it, which will create a new table for you.<\/p>\n<pre class=\"lang:mysql decode:true\">CREATE TABLE inventory\r\n(\r\nhostName varchar(25) NOT NULL,\r\nhostIP varchar(25),\r\nhostMAC varchar(18),\r\nhostCreateDate timestamp DEFAULT CURRENT_TIMESTAMP,\r\nvlanID int(4),\r\nswitchPort varchar(32),\r\nswitchIP varchar(25),\r\nswitchName varchar(64),\r\nswitchPlatform varchar(64),\r\nUNIQUE (hostName)\r\n);<\/pre>\n<p>This single table consists of host information (name, mac, ip), switch information (name, platform, IP, port) and a date that the entry was created. Note that this also adds the constraint to the hostName to ensure that it is unique (and stipulates that it can&#8217;t be empty). <em>There is a logical argument that, perhaps, it should be the MAC address that is unique; but I am quite happy with my domain and that it won&#8217;t give me hostname duplication for this demo. Plus, the focus is on getting data of different types in, rather than necessarily what the data is.<\/em><\/p>\n<h3>PHP page\u00a0to process data<\/h3>\n<p>This is the part that is going to bring it all together later. When we want to place data into the database, we need something that will take data sent to the server and process that into the database. This file is going to store the database credentials, so its really important that it\u00a0isn&#8217;t made available outside of your webserver. Since PHP files execute on the server, rather than the client, the file contents aren&#8217;t sent back when requested (unless the PHP service stops and breaks, in which case everything will be displayed in plaintext..). In fact, we really don&#8217;t have to &#8211; or necessarily want to &#8211; output anything with a PHP file; in this instance, it is simply used as a way to process data from clients to be stored in a database as follows:<\/p>\n<p>The first thing to do is to specify some variables for the database\u00a0details. These are used to connect to the database (on the same server, in this case):<\/p>\n<pre class=\"theme:sublime-text lang:php decode:true\">&lt;?php\r\n\t$servername = \"localhost\";\r\n\t$username = \"user\";\r\n\t$password = \"Passw0rd\";\r\n\t$dbname = \"inventory\";\r\n\r\n\/\/Rest of the code goes here\r\n\r\n?&gt;<\/pre>\n<p>&nbsp;<\/p>\n<p>The next thing to do is to create a connection object that handles the connection to a MySQL database, passing it the above variables as parameters:<\/p>\n<pre class=\"theme:sublime-text lang:php decode:true\">$conn = new mysqli($servername, $username, $password, $dbname);<\/pre>\n<p>Before we can go any further, however, we need to actually have some data to process &#8211; or know what data we want to process. I&#8217;ll come back to this in a while, but first let&#8217;s generate the URL string.<\/p>\n<h2>Generate a URL string<\/h2>\n<p>At this point, I am making an assumption that you already have variables that you want to send. The key thing is to prepare that data to be sent to the server.<\/p>\n<p>There are a number of ways in which you could send data with a web request; HTTP <strong>GET<\/strong>\u00a0and\u00a0<strong>POST <\/strong>being probably the most suited.<\/p>\n<ul>\n<li><strong>GET\u00a0<\/strong>is easy; you can just construct a string consisting of the URL of the server to send the data too and then append all the extra data you want onto the end of it. However, you&#8217;re limited to 2048 characters, the URL is very &#8220;visible&#8221; (like any URL, the data included is going to pop up in search history, it can be cached) and so it is better used when trying to retrieve data (IE when you need to include some specific parameters as part of the request).<\/li>\n<li><strong>POST<\/strong>, on the other hand, hasn&#8217;t got the same limits on what &#8211; and how much &#8211; data you can include in the request. Possibly more crucially, however, is that the data isn&#8217;t sent along in the header of the request, so it isn&#8217;t as easily seen directly through the URL.<\/li>\n<\/ul>\n<p>For good practice, I&#8217;m going to focus on using POST to upload the data. We&#8217;re using the request to send data, not simply retrieve it (which is where using GET would be appropriate). We can upload quite a bit of data\u00a0this way, but it\u00a0has to be formatted first. The string is pretty much the same for GET as it would be for POST; the difference is that the POST data\u00a0will be sent separately to the header, in the body of the request, in the following format:<\/p>\n<p>&nbsp;<\/p>\n<pre class=\"lang:php decode:true \">variable1=value&amp;variable2=value&amp;variable3=value<\/pre>\n<p>These are sets of variables and values that are accessible by the page requested; but the variable name must be used as it is on the page. If your local variable is <em>myHostName<\/em>, for example, but you send it as <em>val1<\/em>, then once it has reached the server, it has to be referred to by the name\u00a0<em>val1.<\/em><\/p>\n<p>So how do you construct this string from many smaller strings?<\/p>\n<p>There are a few ways to do this (<em>str::append<\/em>, for example). I&#8217;m using a mixture of C and C++ throughout these examples (which is probably a horrible thing to do in practice), but to break down how it works, I am going to manually stick the different strings together.<\/p>\n<p>First of all, I&#8217;ve created a function called\u00a0<em>generatePOSTData()\u00a0<\/em>that will prepare the different parts of a string to be added together, consisting of 8 example variables. Note that each one has an equals operator next to it, which is used by the webserver:<\/p>\n<pre class=\"lang:c++ decode:true\">void generatePOSTData()\r\n{\r\n\tchar *prefixhost = \"host=\";\r\n\tchar *prefixip = \"ip=\";\r\n\tchar *prefixmac = \"mac=\";\r\n\tchar *prefixvlan = \"vlan=\";\r\n\tchar *prefixswPort = \"swPort=\";\r\n\tchar *prefixswName = \"swName=\";\r\n\tchar *prefixswIP = \"swIP=\";\r\n\tchar *prefixswMAC = \"swMAC=\";\r\n\r\n\t\r\n\tint slhost = strlen(prefixhost);\r\n\tint slip = strlen(prefixip);\r\n\tint slvlan = strlen(prefixvlan);\r\n\tint slmac = strlen(prefixmac);\r\n\tint slswPort = strlen(prefixswPort);\r\n\tint slswName = strlen(prefixswName);\r\n\tint slswIP = strlen(prefixswIP);\r\n\tint slswMAC = strlen(prefixswMAC);\r\n...<\/pre>\n<p>Note that this also calculates the length of each of the strings we&#8217;ve just created. This is important when adding the strings together, later.<\/p>\n<p>Next, we can take the strings and add them together, storing them in another variable. The function,\u00a0<em>addStrings<\/em>, is something I have <a href=\"http:\/\/www.troliver.com\/?p=133\">discussed in a previous post<\/a>.<\/p>\n<pre class=\"lang:c++ decode:true \">\taddStrings(&amp;host, prefixhost, systemhostname, slhost, slsystemhostname);\r\n\taddStrings(&amp;ip, prefixip, systemip, slip, slsystemip);\r\n\taddStrings(&amp;vlan, prefixvlan, systemvlan, slvlan, slsystemvlan);\r\n\taddStrings(&amp;mac, prefixmac, systemmac, slmac, slsystemmac);\r\n\r\n\taddStrings(&amp;swPort, prefixswPort, systemswitchport, slswPort, slsystemswitchport);\r\n\taddStrings(&amp;swIP, prefixswIP, systemswIP, slswIP, slsystemswIP);\r\n\taddStrings(&amp;swName, prefixswName, systemswName, slswName, slsystemswName);\r\n\taddStrings(&amp;swMAC, prefixswMAC, systemswMAC, slswMAC, slsystemswMAC);\r\n}\r\n\r\nvoid addStrings(char ** result, const char * prefix, const char * body, int &amp;prefixlength, int &amp;bodylength)\r\n{\r\n\t*result = (char *)malloc((prefixlength + bodylength + 1) * sizeof(char));\r\n\tmemcpy(*result, prefix, prefixlength);\r\n\tmemcpy(*result + prefixlength, body, bodylength);\r\n\t(*result)[prefixlength + bodylength] = '\\0'; \/\/Must be set like this as array notation takes precendence over a dereferencing\r\n\tprefixlength = strlen(*result);\r\n}<\/pre>\n<p>Finally, we can start to construct a single string of all of these together.<\/p>\n<pre class=\"lang:c++ decode:true\">requestString = (char *)malloc((slhost + slip + slswPort + slvlan + slmac + slswName + slswIP + slswMAC + 7 + 1) * sizeof(char));\r\n<\/pre>\n<p>This string is going to be long enough for each of the lengths of the above variables, plus one extra character for the ampersands to connect them. Plus a terminating character.<\/p>\n<p>Now it is time to go through each string (I could use a recursive function here, but I&#8217;m keeping it long and simple here.. optimisation will\u00a0come later!) and, bit by bit, copy the next piece of data over from individual variables over to <em>requestString<\/em>\u00a0with an ampersand added after each set of values:<\/p>\n<pre class=\"lang:c++ decode:true\">memcpy(requestString, host, slhost);\r\n\trequestString[slhost] = '&amp;'; \r\n\r\n\tmemcpy(requestString+ slhost + 1,\r\n\t\tip, slip);\r\n\trequestString[slhost + slip + 1] = '&amp;';\r\n\r\n\tmemcpy(requestString+ slhost + slip + 2,\r\n\t\tswPort, slswPort);\r\n\trequestString[slhost + slip + slswPort + 2] = '&amp;';\r\n\r\n\tmemcpy(requestString+ slhost + slip + slswPort + 3,\r\n\t\tvlan, slvlan);\r\n\trequestString[slhost + slip + slswPort + slvlan + 3] = '&amp;';\r\n\r\n\tmemcpy(requestString+ slhost + slip + slswPort + slvlan + 4,\r\n\t\tmac, slmac);\r\n\trequestString[slhost + slip + slswPort + slvlan + slmac + 4] = '&amp;';\r\n\r\n\tmemcpy(requestString+ slhost + slip + slswPort + slvlan + slmac + 5,\r\n\t\tswName, slswName);\r\n\trequestString[slhost + slip + slswPort + slvlan + slmac + slswName + 5] = '&amp;';\r\n\r\n\tmemcpy(requestString+ slhost + slip + slswPort + slvlan + slmac + slswName + 6,\r\n\t\tswIP, slswIP);\r\n\trequestString[slhost + slip + slswPort + slvlan + slmac + slswName + slswIP + 6] = '&amp;';\r\n\r\n\tmemcpy(requestString+ slhost + slip + slswPort + slvlan + slmac + slswName + slswIP + 7,\r\n\t\tswMAC, slswMAC);\r\n\trequestString[slhost + slip + slswPort + slvlan + slmac + slswName + slswIP + slswMAC + 7] = '\\0';\r\n\r\n<\/pre>\n<p>This is kind of ridiculous, admittedly. I could just use the addStrings function from above, or as I said before, just functions in C++ to do this. However, it shows you how you really have to add strings together at a lower level than simply doing something at a higher level such as\u00a0<em>string1 <\/em>+= <em>string2.<\/em><\/p>\n<h2>Send a web request with cURL to the webserver<\/h2>\n<p>Now that we have the post string, we can prepare it for sending with cURL; and it isn&#8217;t very hard. The first thing to do is to create a new curl object and then initialise it. If that works, you can use <em>curl_setopt<\/em> to\u00a0set the URL on the object to your webpage (so http:\/\/www. your-site.com\/ sendData.php) and the post string to send that was constructed above. Finally, you can initiate the request with <em>curl_easy_perform<\/em> and then do cleanup to remove the cURL object.<\/p>\n<pre class=\"lang:c++ decode:true\">\/\/Library available from https:\/\/curl.haxx.se\/libcurl\/\r\n#define CURL_STATICLIB \/\/You may or may not need this!\r\n#include \"curl\/curl.h\"\r\n#pragma comment ( lib, \"libcurl.lib\" )\r\n\r\n\/\/...\r\n\/\/...\r\n\r\n\tCURL * curl;\r\n\tcurl_global_init(CURL_GLOBAL_ALL);\r\n\tCURLcode res;\r\n\tcurl = curl_easy_init();\r\n\tif (curl)\r\n\t{\r\n\t\tcurl_easy_setopt(curl, CURLOPT_URL, address);\r\n\t\tcurl_easy_setopt(curl, CURLOPT_POSTFIELDS, requestString);\t\t\t\r\n\t\tres = curl_easy_perform(curl);\r\n\t\tif (res != CURLE_OK)\r\n\t\t{\r\n\t\t\tfprintf(stderr, \"curl_easy_perform() failed: %s\\n\", curl_easy_strerror(res));\r\n\t\t}\t\r\n\t\tcurl_easy_cleanup(curl);\r\n\t}\r\n\tcurl_global_cleanup();<\/pre>\n<p>Outside the scope of this document would be handling the response from the server, but it is important to provision for this later as this will allow you to know whether or not things worked on the client side!<\/p>\n<h2>Process the uploaded string<\/h2>\n<p>Now it is time to go back to where we were with the PHP page. We know what data is going to be sent now, so we know what will be received by the page.<\/p>\n<h3>Loading in the data<\/h3>\n<p>Although the string was all wrapped up with ampersands and formatted with a header, when the page receives the data, it is available as an associative array called\u00a0<em>$_POST<\/em>. This means that you can access a value by using the name of it in the index (for example,\u00a0$_POST[&#8220;host&#8221;] will return you the value of the hostname). The other thing about $_POST is that it is accessible from anywhere on your page, as it is a\u00a0<em>superglobal<\/em> type. However, in this example, we only access it once to load in the values and process them into variables used throughout the page.<\/p>\n<p>Where you declare the other variables in your code, so around $conn or the database details, add the following:<\/p>\n<pre class=\"lang:php decode:true\">$host = mysql_escape_string($_POST['host']);\r\n$ip = mysql_escape_string($_POST['ip']);\r\n$swPort = mysql_escape_string($_POST['swPort']);\r\n$swIP = mysql_escape_string($_POST['swIP']);\r\n$swName = mysql_escape_string($_POST['swName']);\r\n$swMAC = mysql_escape_string($_POST['swMAC']);\r\n$vlan = mysql_escape_string($_POST['vlan']);\r\n$mac = mysql_escape_string($_POST['mac']);<\/pre>\n<p>What this will do is quite important; it (hopefully) will prevent against SQL injection attacks by escaping the string. In other words, it stops code from being added to text that could unexpectedly end the string and roll over into executing the code that was submitted. However, see <a href=\"http:\/\/stackoverflow.com\/questions\/3665572\/mysql-escape-string-vs-mysql-real-escape-string\">this post for a bit more information<\/a> &#8211; and why you might not want to use it in the real world.<\/p>\n<p>Additionally, we now can refer to the variables by their name prefixed with a dollar symbol, rather than having to use $POST[&#8216;variableName&#8217;] for everything. (Interestingly there are some\u00a0<a href=\"http:\/\/stackoverflow.com\/questions\/3446216\/what-is-the-difference-between-single-quoted-and-double-quoted-strings-in-php\">differences between single and double quotes<\/a>\u00a0in php.).<\/p>\n<h3>Validate the data<\/h3>\n<p>The next test we want to do on the incoming data is to make sure it is, in fact, populated and not simply. This can be done by simply checking through each variable and seeing if it is null or not. Note that anything echo&#8217;d will be returned to the requestor. If this was a browser, you would see the response on screen, but this application doesn&#8217;t have a way to handle this, yet.<\/p>\n<pre class=\"lang:php decode:true\">if ($host == NULL)\r\n\t{\r\n\t\techo \"Error, host is empty! \";\t\r\n\t}\r\n<\/pre>\n<p>There is also one more thing that I want to add in; a test to see if the host is valid or not. If\u00a0there is junk data and there are blank entries, for fields that must not be empty, this can create problems for us. If we specify an invalidation flag, that can be set if one of the variables is empty, then we can stop any database processing from happening.<\/p>\n<pre class=\"lang:php decode:true\">$testInValid = 0;\r\n\r\nif ($host == NULL)\r\n\t{\r\n\t\techo \"Error, host is empty! \";\r\n\t\t$testInValid = 1;\r\n\t}\r\n\r\nif ($ip == NULL)\r\n\t{\r\n\t\techo \"Error, ip is empty! \";\t\t\r\n\t\t$testInValid = 1;\r\n\t}\r\n\r\nif ($swPort == NULL)\r\n\t{\r\n\t\techo \"Error, swPort is empty! \";\r\n\t\t$testInValid = 1;\r\n\t}\r\n\r\nif ($vlan == NULL)\r\n\t{\r\n\t\techo \"Error, vlan is empty! \";\t\t\r\n\t\t$testInValid = 1;\r\n\t}\r\n\r\nif ($mac == NULL)\r\n\t{\r\n\t\techo \"Error, mac is empty! \";\t\t\r\n\t\t$testInValid = 1;\r\n\t}\r\n\r\nif ($swName == NULL)\r\n\t{\r\n\t\techo \"Error, swName is empty! \";\t\t\r\n\t\t\/\/$testInValid = 1;\r\n\t}\r\n\r\nif ($swMAC == NULL)\r\n\t{\r\n\t\techo \"Error, swMAC is empty! \";\t\t\r\n\t\t\/\/$testInValid = 1;\r\n\r\n\t}\r\n\r\nif ($swIP == NULL)\r\n\t{\r\n\t\techo \"Error, swIP is empty! \";\r\n\t\t\/\/$testInValid = 1;\r\n\t}\r\n\r\nif (testInValid == 0)\r\n{<\/pre>\n<p>We begin by declaring a variable called\u00a0<em>testInValid<\/em> which, by default, will remain as 0 so long as all the key pieces of data exist. At the bottom, we continue the program so long as <em>testInValid<\/em> remains as 0. It is a quick and dirty trick, but it ensures that we don&#8217;t execute code if it could break anything in the database.<\/p>\n<h2>Store the data as a new record in a database<\/h2>\n<p>With the data validated and in the form, it is time to add it to the database. Be sure that you have you added the following line to create the connection object:<\/p>\n<pre class=\"theme:sublime-text lang:php decode:true\">$conn = new mysqli($servername, $username, $password, $dbname);<\/pre>\n<p>The first thing to do is to see if we can connect to it. This will also catch the error if it can&#8217;t, but you don&#8217;t have to populate it yet:<\/p>\n<pre class=\"lang:php decode:true\">if ($conn-&gt;connect_error)\r\n{\r\n}<\/pre>\n<p>Instead,\u00a0we can now create an SQL Select statement, which will be run as a query by the object.<\/p>\n<pre class=\"lang:mysql decode:true\">$sqlSelect = \"SELECT * from hosts WHERE hostName = '$host'\";<\/pre>\n<p>What this will do, is to return records for\u00a0any hosts that exist with the hostname that we have specified in the request. Note that, although the query is in double quotation marks, the hostname is within single quotes. This allows us to use the <em>$host\u00a0<\/em>variable from the page, expanded to its actual value. Another way to do that would be to use a full stop to join two strings together, with the second string being $host and the first string being the SQL statement up until the end of the equals sign, as so:<\/p>\n<pre class=\"lang:php decode:true\">$sqlSelect = \"SELECT * from hosts WHERE hostName = \" . $host;<\/pre>\n<p>Back to the statements: we need another one. This one will be the SQL\u00a0Insert statement, used to add an entry into the database.<\/p>\n<pre class=\"lang:mysql decode:true\">$sqlInsert = \"INSERT INTO hosts (hostName, hostIP, switchPort, switchIP, switchName, switchPlatform, vlanID, hostMac)\t\t\r\n\r\n\t\t\t\tVALUES ('$host', '$ip', '$swPort', '$swIP','$swName','$swMAC','$vlan','$mac')\";\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>Finally, we run the queries. First we check to see if there is already a record with that hostname which &#8211; if there is &#8211; means that we do nothing other than report that to be the case. However, if there are no results for the query, this means that there are no hosts with that name and we can now run the second query. If that returns true &#8211; in other words, there were no errors &#8211; then we can assume it worked and output that to be the case.<\/p>\n<pre class=\"lang:default decode:true\">$result = $conn-&gt;query($sqlSelect);\r\n\r\nif ($result-&gt;num_rows &gt; 0)\r\n{\r\n echo \"Host already exists!\"\r\n}\r\n\r\nelse\r\nif ($conn-&gt;query($sqlInsert) === TRUE) \r\n{\r\n\techo \"Success!\";\r\n}\r\n<\/pre>\n<h2><\/h2>\n<h2>Viewing the results<\/h2>\n<p>You can now check this by making a new page with the same database connection details that fetches and outputs the data to a webpage. Below is a commented example of something that you can use to view the results into a table. Note that anything echo&#8217;d will be output as HTML &#8211; you can view how the code is generated in the browser by right clicking the screen (in most browsers) and clicking &#8220;View Source&#8221; when you run this:<\/p>\n<pre class=\"lang:mysql decode:true  \">&lt;?php\r\n\r\n\/\/Connection strings\r\n\t$servername = \"myserver\";\r\n\t$username = \"user1\";\r\n\t$password = \"p@ssw0rd\";\r\n\t$dbname = \"database1\";\r\n\t$tableName = \"inventory\";\r\n\r\n\/\/Connection object\r\n\t$conn = new mysqli($servername, $username, $password, $dbname);\r\n\r\n\/\/Check to see if the connection succeeds\r\n\tif ($conn-&gt;connect_error) {\r\n\t\tdie(\"Connection failed: \" . $conn-&gt;connect_error);\r\n\t}\r\n\r\n\r\n\/\/SQL statement to select various fields from the table. Note that you could say, instead, \"SELECT * FROM\" . $tableName;\t\r\n\t$sql = \"SELECT hostName, hostIP, hostMac, hostCreateDate, vlanID, switchPort, switchIP FROM \". $tableName ;\r\n\r\n\/\/Run the query and store the results in an array\r\n\t$result = $conn-&gt;query($sql);\r\n\r\n\tif ($result-&gt;num_rows &gt; 0) \r\n\t{\t\r\n\/\/This will spit out a table with some headers on the first row\r\n\t\techo \"&lt;table&gt;&lt;tr&gt;&lt;th&gt;Hostname&lt;\/th&gt;&lt;th&gt;IP Address&lt;\/th&gt;&lt;th&gt;MAC&lt;\/th&gt;&lt;th&gt;Switch IP&lt;\/th&gt;&lt;th&gt;Switchport ID&lt;\/th&gt;&lt;th&gt;VLAN ID&lt;\/th&gt;&lt;th&gt;Created On&lt;\/th&gt;&lt;\/tr&gt;\";\r\n\r\n\/\/Here we just create a new table row with the results displayed in each column\r\n\t\twhile($row = $result-&gt;fetch_assoc()) \r\n\t\t{\r\n\t\t\t  echo \"&lt;tr&gt;&lt;td&gt;\".\r\n\t\t\t  $row[\"hostName\"].\"&lt;\/td&gt;&lt;td&gt;\". \r\n\t\t\t  $row[\"hostIP\"].\"&lt;\/td&gt;&lt;td&gt;\". \r\n\t\t\t  $row[\"hostMac\"].\"&lt;\/td&gt;&lt;td&gt;\". \r\n\t\t\t  $row[\"switchIP\"].\"&lt;\/td&gt;&lt;td&gt;\" .\r\n\t\t\t  $row[\"switchPort\"].\"&lt;\/td&gt;&lt;td&gt;\" .\r\n\t\t\t  $row[\"vlanID\"].\"&lt;\/td&gt;&lt;td&gt;\".\r\n\t\t\t  $row[\"hostCreateDate\"].\"&lt;\/tr&gt;\"; \r\n\t\t}\r\n\t}\r\n\r\n\/\/Just in case we have nothing!\r\n\telse \r\n\t{\r\n\t\techo \"0 results\";\r\n\t}\r\n\r\n$conn-&gt;close();\r\n\r\n?&gt;<\/pre>\n<p>&nbsp;<\/p>\n<p>That concludes a very hacky &#8211; but functional &#8211; guide to how to get data from an application written in C\/C++ into a database and displayed on a webpage using cURL. Please do post comments, issues and questions in reply!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Following on from the last post on the\u00a0topic of capturing packet data from a network, this guide\u00a0demonstrates how you can use a cURL library to upload data from\u00a0an application written in C (or C++) to a webserver.\u00a0Although at times I refer to previous examples, you can use this in\u00a0any number of applications. This will touch [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_newsletter_tier_id":0,"jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false}}},"categories":[21],"tags":[30,60,61,15,62,34],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p6PQZ3-60","_links":{"self":[{"href":"https:\/\/www.troliver.com\/index.php?rest_route=\/wp\/v2\/posts\/372"}],"collection":[{"href":"https:\/\/www.troliver.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.troliver.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.troliver.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.troliver.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=372"}],"version-history":[{"count":17,"href":"https:\/\/www.troliver.com\/index.php?rest_route=\/wp\/v2\/posts\/372\/revisions"}],"predecessor-version":[{"id":433,"href":"https:\/\/www.troliver.com\/index.php?rest_route=\/wp\/v2\/posts\/372\/revisions\/433"}],"wp:attachment":[{"href":"https:\/\/www.troliver.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=372"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.troliver.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=372"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.troliver.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=372"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}