c
23 TopicsHands-on C: argc and argv from main() function explained
Quick Intro Learning C is is a good way to take our understanding of Operating Systems (OS) to the next level as it touches low-level structures that other languages such as Python often abstract. I'm covering C here not only because BIG-IP runs on top of Linux but also because understanding how the OS works can help us troubleshoot more complex issues. Linux has been gaining popularity and DevOps movement certainly gave it a boost as most DevOps tools run natively on Linux. As C is the nuts and bolts of Linux 'engine', it is also no surprise that we see more Platform (DevOps) Engineers interested in learning C to extend their reach when it comes to diagnosing problems and to have a more in-depth understanding of Linux. In this article, I'm going to use a simple Hello World in C but those who already had exposure to C will also benefit from understanding more thoroughly the default arguments (argc and argv) in main() function by running the code themselves. If you already know something about C, you can skip to last section and test the code yourself. Hello World This is a hello world in Python: This is a typical hello world in C: The main() function is the way we tell C where the execution of our code should start. It is the way C language signals processor where it should look for the main piece of code to run once our program is loaded in memory. The printf() function formats and print string characters to standard output. C doesn't have an interpreter like Python as it's a compiled language. Because of this, in order to execute above code we need to compile it first, i.e. create the executable file that has the binary code ready to run. How to Compile our Hello World We usegcccommand with-oparameter pointing to the name of the executable file name. Thegcccommand compiles our code and create the executablehelloworld. It's a binary file ready to be executed. If we need to change our code, we need to re-compile our code and create another executable file. Understanding #include <library_name> Adding libraries in C is similar to other programming languages. Libraries add capabilities to your code where you can find ready-to-use functions that do something that you might need to use. C libraries end in*.h(shortfor header) and compiler searches for them in/usr/includepath by default on Linux. In this particular case here, we only added thestdio.hlibrary which is the standard C I/O library with file reading/writing/streaming handling capabilities. There are also others we might occasionally bump into in most programs: unistd.h : The Unix standard library. It has utilities for interacting with the kernel such as system calls. stdlib.h : The C standard library with many useful utilities for general data type conversion, memory allocation, etc. ctype.h : Character library with for char conversion sys/types.h : System types library which contains the most definitions for base types and structures of Linux systems. string.h : String library for C string manipulation. Why does main function have argc and argv? argc= number of arguments passed when we execute program (integer) argv= list of arguments we passed when we executed program (array) Simple answer is that this is useful stuff to have natively. It's extensively used in command line tools, for example. Let's say we're creating a command line tool and we need to retrieve the 2nd argument passed to our program. You can just retrieve it directly from main() function by callingargv[2]. No need to create an extra function for that. Let's use this simple program as an example: It should print whatever arguments I pass to it: Notice that by default, the first argument is always the program's name. Even if I don't pass any arguments that's still the case: We can conclude that every program will have at least one argument which is the name of the program itself.1.5KViews1like2Commentsdelete_devices
Problem this snippet solves: Introduced: EM_v3.0 Use the delete_devices API to remove devices currently being managed by an Enterprise Manager. How to use this snippet: Prototype Python ic.Management.EM.deletedevices(deviceaddresses) C#, Java, and Perl ic.getManagementEM().delete_devices(deviceAddresses); Inputs Name Type Description IP addresses String Sequence This parameter specifies the IP addresses or hostnames of the F5 device(s) that you want to delete from the list of managed devices. Return values There is no explicit return when this API executes successfully. Exceptions The table lists error categories that Enterprise Manager can raise if the API call fails. Exception Name This exception is raised when... AccessDenied The credentials supplied by the client do not satisfy the F5 device's validation requirements. OperationFailed The API call causes an operation error. InvalidArgument The API call contains an invalid argument. Code : To view a code sample, click the relevant code type. C# (.net) Java Perl Python289Views0likes0Commentsget_task_status
Problem this snippet solves: Introduced : EM_v3.0 Use the get_task_status API to determine the current status of a device discovery task. How to use this snippet: Python ic.Management.EM.get_task_status(ids = task_ids) C#, Java, and Perl ic.Management.EM.get_task_status(ids = task_ids); Inputs Name Type Description tasks String Sequence This parameter specifies the task IDs of the tasks for which you want to know the status. Return Values Name Type Description task TaskStatus Sequence The ID of the new discovery task. This ID can return the following values: TASK_STATUS_UNKNOWN TASK_STATUS_PENDING TASK_STATUS_STARTED TASK_STATUS_FAILED TASK_STATUS_COMPLETE TASK_STATUS_RUNNING TASK_STATUS_CANCELING TASK_STATUS_CANCELED TASK_STATUS_ABANDONED TASK_STATUS_TERMINATED TASK_STATUS_TIMED_OUT TASK_STATUS_RESCHEDULED Exceptions Exception Name This exception is raised when... AccessDenied The credentials supplied by the client do not satisfy the F5 device's validation requirements. OperationFailed The API call causes an operation error. InvalidArgument The API call contains an invalid argument. Code : To view a code sample, click the relevant code type. C# (.net) Java Perl Python269Views0likes0CommentsHow to programmatically activate license for Bigip using C#
I am looking for some C sample to activate license for Bigip. I have looked into the pycontrol https://devcentral.f5.com/wiki/iControl.pyControl-v2-License-BIGIP.ashx and am trying to do the similar thing in C. The wiki mentions a web service https://activate.f5.com/license/services/urn:com.f5.license.v5b.ActivationService?wsdl, but when I tries to use wsdl.exe to create a proxy class for this web service, I got the following errors: D:\temp>wsdl https://activate.f5.com/license/services/urn:com.f5.license.v5b.Act ivationService?wsdl Microsoft (R) Web Services Description Language Utility [Microsoft (R) .NET Framework, Version 4.0.30319.17929] Copyright (C) Microsoft Corporation. All rights reserved. Error: There was an error processing 'https://activate.f5.com/license/services/u rn:com.f5.license.v5b.ActivationService?wsdl'. - The document at the url https://activate.f5.com/license/services/urn:com.f5. license.v5b.ActivationService?wsdl was not recognized as a known document type. The error message from each known type may help you fix the problem: - Report from 'XML Schema' is 'The root element of a W3C XML Schema should be s chema and its namespace should be 'http://www.w3.org/2001/XMLSchema'.'. - Report from 'DISCO Document' is 'Discovery document at the URL https://activat e.f5.com/license/services/urn:com.f5.license.v5b.ActivationService?wsdl could no t be found.'. - The document format is not recognized. - Report from 'WSDL Document' is 'There is an error in XML document (58, 16).'. - Namespace prefix 'intf:urn' is not defined. If you would like more help, please type "wsdl /?". Does anyone know if how to solve the problem? or is it the right way to access the web service at all in C? thanks Wai419Views0likes1CommentGet all certificates and their virtual servers and SSL profiles via API calls
Problem this snippet solves: Summary F5 will give you a decent report of all your certificates and their expiration dates. However I have not found a way to pull what Virtual Server or SSL Profile the certificates are applied to (or if they are used at all). What this code does is grabs all the virtual servers, all SSL profiles, and all certificates. Then it loops through them to find where a certificate is applied. Then it returns the certificate and virtual server info. I wrote this in C# but the logic can be used anywhere as the API calls are independent of language. How to use this snippet: You will need some way to compile C#. Easiest way is to use Visual Studio. Simply add your API credentials and IP addresses and run the code through a C# compiler. Code : https://github.com/matthewwedlow/F5_Scripts/blob/master/GetCerts.cs2.4KViews1like3CommentsHands-on C: Understanding Pointers step by step
Quick Intro Pointers have always been the most confusing aspect of C for new learners. As a former lecturer, I find simple hands-on examples are the best to get one started. In this article, I will explain the following: What a pointer is How a pointer is declared in C How to assign a memory address to a pointer How to change values using pointers How to move pointer to a different memory address What is a pointer? It's literally a variable that stores and point to the memory address of another variable. Don't worry, it should be clear once we go through some examples. How a pointer is declared in C How to assign a memory address to a pointer Now, imagine there's a variablexlike this: The &x just means we're assigning topthe memory address ofx: In order to retrieve the value 5 fromp, we also need to use*pbecause p (without *) retrieves the memory address ofxand*pgoes after the value stored in the memory's address. Here's the proof: Notice that C understands that adding&in front of variable retrieves its memory address. How to retrieve pointer's value Retrieving pointer's is also known asdereferencingpointer. If we change*pwe also changex. We can also assign the value that*ppoints to a different variable too (effectively changing the value ofx): How to change values using pointers When we point a pointer to an array, it will point to the memory address of array's first item at index 0: The pointer behaves in the same way as if were making the changes to the array: How to move pointer to a different memory address In this example, I pointed p to A's memory address and then pointed p to n's memory address and that's fine: Let's uncomment last line so we can see that we can't do the same with arrays, i.e. re-assigning values: Hope that clarifies a bit of the mystery behind pointers.467Views0likes2CommentsC# Making Async Calls using the iControlAssembly
Problem this snippet solves: This C# example application shows three different ways to make iControl calls Asynchronously using the An iControlAssembly library. Each way serves a slightly different purpose depending on the needs of the application. Code : using System; using System.Collections.Generic; using System.Text; using iControl; using System.Diagnostics; using System.Threading; namespace iControlAssemblyAsyncExample { class AsyncExample { private static Thread mainThread; static void Main(string[] args) { Stopwatch sw = null; Interfaces m_Interfaces = null; IAsyncResult ar = null; string[] poolList = null; //////////////////////////////////////////////////////////////////////////////// // Synchronously connect to the BigIP Appliance Console.WriteLine("Establishing connection to Appliance."); sw = Stopwatch.StartNew(); m_Interfaces = new Interfaces("hostname", "username", "password"); Console.WriteLine("Connection completed in {0} ms\n", sw.ElapsedMilliseconds); //////////////////////////////////////////////////////////////////////////////// // Synchronously Retrieve the Pool List Console.WriteLine("Beginning syncronous Pool list retrieval."); sw = Stopwatch.StartNew(); poolList = m_Interfaces.LocalLBPool.get_list(); Console.WriteLine("Syncronous retrieval completed in {0} ms\n", sw.ElapsedMilliseconds); //////////////////////////////////////////////////////////////////////////////// // Asynchronously retrieve the Pool List, do something and then wait // for the Async call to complete. Console.WriteLine("Beginning async retrieval with wait."); sw = Stopwatch.StartNew(); ar = m_Interfaces.LocalLBPool.Beginget_list(null, null); // Do some work, which may or may not take longer than // the Async call to execute. Console.WriteLine("Done some work after {0} ms. Now waiting.",sw.ElapsedMilliseconds); ar.AsyncWaitHandle.WaitOne(); // Wait indefinitely for the Async Call to complete ar.AsyncWaitHandle.Close(); poolList = m_Interfaces.LocalLBPool.Endget_list(ar); Console.WriteLine("Asyncronous retrieval completed in {0} ms\n", sw.ElapsedMilliseconds); //////////////////////////////////////////////////////////////////////////////// // Asynchronously Retrieve the Pool List while doing something indefinitely. Console.Write("Beginning inline async retrieval"); sw = Stopwatch.StartNew(); ar = m_Interfaces.LocalLBPool.Beginget_list(null, null); while (ar.IsCompleted == false) { Console.Write("."); // Continually to something until the Async Thread.Sleep(15); // call has completed. } poolList = m_Interfaces.LocalLBPool.Endget_list(ar); Console.WriteLine("\nAsyncronous retrieval completed in {0} ms\n", sw.ElapsedMilliseconds); //////////////////////////////////////////////////////////////////////////////// // Asynchronously Retrieve the Pool List with a Callback AsyncCallback myCallBackRoutine = new AsyncCallback(MyAsyncCallback); mainThread = Thread.CurrentThread; Console.WriteLine("Beginning Callback Async retrieval"); sw = Stopwatch.StartNew(); ar = m_Interfaces.LocalLBPool.Beginget_list(myCallBackRoutine, m_Interfaces); try { while (true) { Console.Write("."); // Do something useful while we Thread.Sleep(15); // wait for the Callback to complete. } } catch (ThreadInterruptedException) { Console.WriteLine("\nAsyncronous Callback retrieval completed in {0} ms\n", sw.ElapsedMilliseconds); } Console.WriteLine("Press ANY key to exit."); Console.ReadKey(); } private static void MyAsyncCallback(IAsyncResult ar) { Interfaces m_Interfaces = (Interfaces)ar.AsyncState; string[] poolList = m_Interfaces.LocalLBPool.Endget_list(ar); int c = 0; while (c < 7) { Console.Write("X"); // Do something useful while the main Thread.Sleep(15); // thread is doing what it needs to c++; } mainThread.Interrupt(); } } }492Views0likes1CommentNeed assistance find where i can pull pool member info with iControl
I am pulling Pool information and Pool Member information using the iControl.dll lib in C I would also like to be able to pull the information about a pool member such as when it was disabled like it would show when you look at a member in the UI it shows a data and time and other details about being disabled. Where would i be able to retrieve this data from in the iControl lib?218Views0likes0CommentsUp/Down Nodes: Visual C#
Problem this snippet solves: This app enables and disables nodes. It installs and runs as a stand alone windows application. It connects to an LTM, collects the pools, collects pool members, and allows the user to toggle the enabled/disabled state of nodes. This is my first iControl App. It is also my first run at C# and Visual Studio. It is pretty basic and a little rough around the edges. I am posting it because I did not find many examples of C# using Visual Studio. I plagiarized from other code examples found on DevCentral so you may see some similarities if you look around. The entire project is attached as a .zip. Code : using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class Form1 : Form { public class poolmember { public string poolname { get; set; } public string address { get; set; } public Int64 port { get; set; } public iControl.LocalLBSessionStatus status { get; set; } public iControl.CommonAddressPort addressport { get; set; } } List _poolmember = new List (); //iControl.CommonAddressPort my_addressport() = ""; iControl.Interfaces interfaces = new iControl.Interfaces(); public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { } private void label2_Click(object sender, EventArgs e) { } private void label6_Click(object sender, EventArgs e) { } private void label7_Click(object sender, EventArgs e) { } private void label5_Click(object sender, EventArgs e) { } private void button1_Click(object sender, EventArgs e) { lblVersion.Text = "Connecting ..."; lblFailover.Text = ""; lblHostname.Text = ""; if (interfaces.initialize(txtIPAddr.Text, txtAccount.Text, txtPasswd.Text)) { lblVersion.Text = interfaces.SystemSystemInfo.get_version(); lblFailover.Text = Convert.ToString(interfaces.SystemFailover.get_failover_state()); lblHostname.Text = Convert.ToString(interfaces.ManagementDevice.get_local_device()); string[] pools = interfaces.LocalLBPool.get_list(); foreach (string pool in pools) { lstBxPools.Items.Add(pool); } } else { lblVersion.Text = "Connection Failure"; } } private void lstBxPools_SelectedIndexChanged(object sender, EventArgs e) { if (lstBxPools.SelectedIndex >= 0) { btnGetMembers.Enabled = true; } else { btnGetMembers.Enabled = false; } } private void button1_Click_1(object sender, EventArgs e) { lstbxMembers.Items.Clear(); // List > members = new List >(); string[] pool = new string[1] { lstBxPools.Text }; // lstbxMemUp.Items.Add(lstBxPools.Text); iControl.CommonAddressPort[][] memberlist = interfaces.LocalLBPool.get_member_v2(pool); foreach (iControl.CommonAddressPort member in memberlist[0]) { poolmember node = new poolmember { poolname = lstBxPools.Text, address = member.address, port = member.port, addressport = member, }; _poolmember.Add(node); } foreach (poolmember member in _poolmember) { //Method requires a multi-dimensional array for input. Add CommonAddressPort to new List List convertedserverlist = new List { member.addressport }; //Convert List to Array for input into the next method iControl.CommonAddressPort[] targetarry = convertedserverlist.ToArray(); //Call the BIG-IP - Inputs are an array of Pool Names and a multi-dimensional array of CommonAddressPorts iControl.LocalLBSessionStatus[][] targetstatus = interfaces.LocalLBPool.get_member_session_status(new[] { member.poolname }, new[] { targetarry }); //Only requested a single pool, so specify the first dimension and collect data for output. foreach (iControl.LocalLBSessionStatus status in targetstatus[0]) { lstbxMembers.Items.Add(member.address + ":" + member.port + " " + status); member.status = status; } } _poolmember.Clear(); } private void btnDown_Click(object sender, EventArgs e) { if (lstbxMembers.Text.Contains("SESSION_STATUS_ENABLED")) { label7.Text = "saw Session Status ENABLED"; // string[] poolname = { lstBxPools.Text }; // interfaces.LocalLBPool.set_member_session_enabled_state(poolname[0], my_addressport[1][1], iControl.CommonEnabledState.STATE_DISABLED); string node = lstbxMembers.Text.Split(':')[0]; label7.Text = node; string[] node_a = {node}; iControl.CommonEnabledState[] states = new iControl.CommonEnabledState[] { iControl.CommonEnabledState.STATE_DISABLED }; interfaces.LocalLBNodeAddressV2.set_session_enabled_state(node_a, states); } else if (lstbxMembers.Text.Contains("SESSION_STATUS_ADDRESS_DISABLED")) { string node = lstbxMembers.Text.Split(':')[0]; string[] node_a = { node }; iControl.CommonEnabledState[] states = new iControl.CommonEnabledState[] { iControl.CommonEnabledState.STATE_ENABLED }; interfaces.LocalLBNodeAddressV2.set_session_enabled_state(node_a, states); } else { } lstbxMembers.Items.Clear(); // List > members = new List >(); string[] pool = new string[1] { lstBxPools.Text }; // lstbxMemUp.Items.Add(lstBxPools.Text); iControl.CommonAddressPort[][] memberlist = interfaces.LocalLBPool.get_member_v2(pool); foreach (iControl.CommonAddressPort member in memberlist[0]) { poolmember node = new poolmember { poolname = lstBxPools.Text, address = member.address, port = member.port, addressport = member, }; _poolmember.Add(node); } foreach (poolmember member in _poolmember) { //Method requires a multi-dimensional array for input. Add CommonAddressPort to new List List convertedserverlist = new List { member.addressport }; //Convert List to Array for input into the next method iControl.CommonAddressPort[] targetarry = convertedserverlist.ToArray(); //Call the BIG-IP - Inputs are an array of Pool Names and a multi-dimensional array of CommonAddressPorts iControl.LocalLBSessionStatus[][] targetstatus = interfaces.LocalLBPool.get_member_session_status(new[] { member.poolname }, new[] { targetarry }); //Only requested a single pool, so specify the first dimension and collect data for output. foreach (iControl.LocalLBSessionStatus status in targetstatus[0]) { lstbxMembers.Items.Add(member.address + ":" + member.port + " " + status); member.status = status; } } _poolmember.Clear(); } } }407Views0likes1CommentExporting ASM Policies in C#?
I am exploring the .NET API, and as a test case I'd like to use the export_policy_xml method to export a policy and save the output file to my desktop. I've looked at code samples and read through the API documentation but I haven't found anything that will get me going in the right direction. I am able to connect to our f5 and return bits of information here and there, but I've hit a roadblock trying to export the policy. Thoughts, comments, or suggestions? Thanks!166Views0likes1Comment