Thursday, September 26, 2013

cURL HTTP Pipelining

One of my friend asked me if there was a tool to send pipelined http request from linux command line. Thanks to cURL libcurl, I developed a small tool to do the same. Have put in some basic validations and some restrictions like the maximum no of pipeline request is 32 etc

  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
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/* 
 * Ahamed 
 * Using cURL libcurl
 *
 * For sending pipelined http requests
 * Usage : ./send_pipelined_http <no of pipelined requests> <http://x.x.x.x>
 * Some basic validations added.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>

static void usage();

#define ERR_LEN 512
#define MIN_URL_LEN 14
#define MAX_URL_LEN 32 
#define MIN_PIPELINE_REQ 1
#define MAX_PIPELINE_REQ 32
#define err(x, y) {printf("\nError: %s...\nExiting...\n", x); if(y)exit(0); usage();}

static unsigned int pipeline_req;
static char url[MAX_URL_LEN];
static char err_str[ERR_LEN];

static void handle_curl_error(CURLcode ret, char *func)
{
  if(ret != CURLE_OK){
    fprintf(stderr, "%s() failed: %s\n", func,
            curl_multi_strerror(ret));
  }
  return;
}

static void usage()
{
  printf("\nDeveloped by Ahamed using cURL API via libcurl\n");
  printf("Usage : ./send_pipelined_http <no of req> <http://x.x.x.x>\n");
  printf("        Pipeline Request - Min %d : Max : %d\n", 
                  MIN_PIPELINE_REQ, MAX_PIPELINE_REQ);
  printf("        Hostname not supported yet. Please provide IP address.\n");
  printf("        URL - Min Length %d : Max Length : %d\n\n", 
                  MIN_URL_LEN, MAX_URL_LEN);
  exit(0);
}

static void parse_args(int argc, char **argv)
{

  if(argc <= 2)
    err("Insufficient arguments", 0);

  if(!argv)
    err("Something unexpected happened", 1);

  pipeline_req = atol(argv[1]);
  if(pipeline_req > MAX_PIPELINE_REQ || pipeline_req < MIN_PIPELINE_REQ)
    err("Invalid Pipeline Request", 0);
  
  if(strlen(argv[2]) > MAX_URL_LEN || strlen(argv[2]) < MIN_URL_LEN)
    err("Invalid URL length", 0);

  strncpy(url, argv[2], MAX_URL_LEN);
  
  return;
}
 
int main(int argc, char **argv)
{

  int i=0;
  parse_args(argc, argv);

  CURLM *m_curl;
  CURLMcode res;

  m_curl = curl_multi_init();
  curl_multi_setopt(m_curl, CURLMOPT_PIPELINING, 1L);

  CURL *curl[MAX_PIPELINE_REQ];
  for(i=0; i<pipeline_req; i++){

    curl[i] = curl_easy_init();
    if(!curl[i])
      err("Something went wrong", 0);

    res = curl_easy_setopt(curl[i], CURLOPT_URL, url);
    handle_curl_error(res, "curl_easy_setopt");

    res = curl_easy_setopt(curl[i], CURLOPT_FOLLOWLOCATION, 1L);
    handle_curl_error(res, "curl_easy_setopt");

    res = curl_multi_add_handle(m_curl, curl[i]);
    handle_curl_error(res, "curl_multi_add_handle");
  }

  int ret = 1;
  do {
    res = curl_multi_perform(m_curl, &ret);
  } while(ret);

  handle_curl_error(res, (char*)__FUNCTION__);

  for(i=0; i<pipeline_req; i++){
    curl_multi_remove_handle(m_curl, curl[i]); 
    curl_easy_cleanup(curl[i]);
  }
  curl_multi_cleanup(m_curl);

  return 0;
}

root@Imperfecto_maximuS> gcc send_pipelined_http.c -lcurl -o send_pipelined_http
root@Imperfecto_maximuS> ./send_pipelined_http

Error: Insufficient arguments...
Exiting...

Developed by Ahamed(ahamed.en@gmail.com) using cURL API via libcurl
Usage : ./send_pipelined_http <no of req> <http://x.x.x.x>
        Pipeline Request - Min 1 : Max : 32
        Hostname not supported yet. Please provide IP address.
        URL - Min Length 14 : Max Length : 32

root@Imperfecto_maximuS>  ./send_pipelined_http 3 http://11.1.1.99
<html><body><h1>This is sample page</h1>\0<p>for testing created...</p></body></html>
<html><body><h1>This is sample page</h1>\0<p>for testing created...</p></body></html>
<html><body><h1>This is sample page</h1>\0<p>for testing created...</p></body></html>

Wednesday, May 1, 2013

To find if the nth bit is set

Following from the previous example, this is to find if the nth bit is set or not. Of course, ensure  the second argument i.e. bit_pos is send correctly, have sufficient checks for that. Again, here the assumption is bit_pos starts from 0 to 31 for 32 bit integer.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include "stdio.h"
#include "limits.h"

static unsigned short is_set(unsigned int x,
                        unsigned short bit_pos)
{
        return !!((1<<bit_pos) & x);
}


int main(int argc, char **argv)
{

        /* 0x1000 = 0000 0000 0000 0000 0001 0000 0000 0000
                                           |
                                          12th Bit
        */
        printf("0x%08x - %d \n", 0x1000, is_set(0x1000, 12));
        printf("0x%08x - %d \n", 0x1000, is_set(0x1000, 13));


        return 0;
}


[root@Imperfecto_1 ~]# gcc -g run.c && ./a.out
0x00001000 - 1
0x00001000 - 0

Finding MSB and LSB

How to find if the MSB or the LSB is set?

 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
#include "stdio.h"
#include "limits.h"

/* This creates a 32 bit value with only MSB set
 * 1 << 31 times produces 10000000000000000000000000000000 i.e. 0x80000000
 * And then we AND it with x which will either yield 0x80000000 or 0x0
 * !!(0x80000000) = 1 and !!(0x0) = 0
 */
static unsigned short is_set_MSB(unsigned int x)
{
        return !!((1<<(sizeof(unsigned int) * CHAR_BIT - 1)) & x);
}

/* This is straight forward, x & 1 will either yield 1 or 0 directly.
 */
static unsigned short is_set_LSB(int x)
{
        return (x & 1);
}

int main(int argc, char **argv)
{

        printf("%08x - %d \n", 0xffffffff, is_set_LSB(0xffffffff));
        printf("%08x - %d \n", 0xfffffff0, is_set_LSB(0xfffffff0));
        printf("%08x - %d \n", 0xffffffff, is_set_MSB(0xffffffff));
        printf("%08x - %d \n", 0x0fffffff, is_set_MSB(0x0fffffff));

        return 0;
}


[root@Imperfecto_1 ~]# gcc -g run.c && ./a.out
ffffffff - 1
fffffff0 - 0
ffffffff - 1
0fffffff - 0

Swap without using a third variable

We know how to swap 2 values using a third temp variable. This is how you do it without using a third variable.

 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
#include "stdio.h"

static void swap(int *x, int *y)
{
        *x = *x + *y;
        *y = *x - *y;
        *x = *x - *y;
        return;
}

static void swap_xor(int *x, int *y)
{
        *x = *x ^ *y;
        *y = *x ^ *y;
        *x = *x ^ *y;
        return;
}

int main(int argc, char **argv)
{

        int x = 10, y = 20;
        printf("1> %d %d\n", x, y);
        swap(&x, &y);
        printf("2> %d %d\n", x, y);
        swap_xor(&x, &y);
        printf("3> %d %d\n", x, y);

        return 0;
}

[root@Imperfecto_1 ~]# gcc -g run.c && ./a.out
1> 10 20
2> 20 10
3> 10 20

Print bits in an Integer

How to print bits in an integer? There are many ways to do this, I mean logically. I have 2 functions here, one recursive and the other one using a loop.

 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
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "limits.h"

/* This function prints the bits in a recursive mode
 * It takes out the bits from right side i.e. 0, 1, 2
 * and prints, this being recursive will print the
 * output in reverse order which will be finally
 * the correct order
 */
static void recurse_bits(int x, int *size)
{
        int bit = x & 0x1;
        if((*size)--){
                recurse_bits(x>>=1, size);
                printf("%d ", bit);
        }
}

/* This function prints the bit by taking it from the left
 * side, i.e. 31, 30 etc and printing it right away
 */
static void print_bits(unsigned int x, int *size)
{
        unsigned short bits = *size;
        unsigned int mask = 0x1 << (bits-1);
        while(bits--){
                printf("%d ", !!(x & mask));
                x<<=1;
        }
        return;
}

int main(int argc, char **argv)
{

        int size = sizeof(unsigned int) * CHAR_BIT;
        int val = 9;

        print_bits(val, &size);
        printf("\n");

        recurse_bits(val, &size);
        printf("\n");

        return 0;
}


[root@Imperfecto_1 ~]# gcc -g run.c && ./a.out
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1

Monday, April 29, 2013

The lshw command

The lshw command lists the hardware information in your system. I came across this because I was having issues with wifi connectivity in Ubuntu 12.04. It just keeps disconnecting after a while and connects back. So, wanted to check the wifi card on and look for possible solutions.

root@Imperfecto_:~# lshw
imperfecto_               
    description: Desktop Computer
    product: Parrot ()
    vendor: GOOGLE
    version: 1.0
    serial: 123456789
    width: 64 bits
    capabilities: smbios-2.7 dmi-2.7 vsyscall32
    configuration: boot=normal chassis=desktop
  *-core
       description: Motherboard
       physical id: 0

and so on...

And I was interested in my wifi card, so I gave it some filters
root@Imperfecto_:~# lshw -C network
  *-network               
       description: Wireless interface
       product: AR9462 Wireless Network Adapter
       vendor: Atheros Communications Inc.
       physical id: 0
       bus info: pci@0000:01:00.0
       logical name: wlan0
       version: 01

and so on...

Installing the gnome desktop in Ubuntu 12.04

Yeah, I also didn't like the Unity which comes by default in Ubuntu 12.04. Just install the gnome-session-fallback and you are good to go


sudo apt-get install gnome-session-fallback

#In the newer version you may want to try
sudo apt-get install gnome-session-flashback


agentBUSH@ChrUbuntu:~# sudo apt-get install gnome-session-fallback
Reading package lists... Done
... bla bla bla ...
Processing triggers for libc-bin ...
ldconfig deferred processing now taking place
agentBUSH@ChrUbuntu:~# 

After installation, log out and at the log-in screen you will have the gnome-classic.

Thursday, April 25, 2013

Program to print pattern

Program to print the following pattern (see below for the pattern). More patterns will be posted later.
 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
#include "stdio.h"
#include "stdlib.h"
#include "string.h"

static void print_it(unsigned len)
{
        if(!len) return;

        unsigned i;
        char *star, *buf, fmt[16]="";

        star = malloc(sizeof(char) * len+1);
        if(!star) return;
        buf = malloc(sizeof(char) * len+1);
        if(!buf) return;

        for(i=0; i<len; i++)
                strcat(star, "*");
        snprintf(fmt, 16, "%%%ds\n", len);
        for(i=len; i>0; i--){
                strcpy(buf, star+i-1);
                printf(fmt, buf);
        }
        free(star);
        free(buf);
        return;
}

int main(int argc, char **argv)
{
        print_it(12);
        return 0;
}


[root@Imperfecto_1 ~]gcc run.c && ./a.out
           *
          **
         ***
        ****
       *****
      ******
     *******
    ********
   *********
  **********
 ***********
************


Valgrind Output
[root@Imperfecto_1 ~]valgrind ./a.out

==5472== HEAP SUMMARY:
==5472==     in use at exit: 0 bytes in 0 blocks
==5472==   total heap usage: 2 allocs, 2 frees, 26 bytes allocated
==5472== 
==5472== All heap blocks were freed -- no leaks are possible


Split functionality of awk implementation in C


 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
55
56
57
58
#include "stdio.h"
#include "stdlib.h"
#include "string.h"

static unsigned split(const char *in, char ***t_out, const char *delim)
{

        if( !*in || !*delim ){
                return 0;
        }

        unsigned i_len = strlen(in);
        char *buf = NULL;
        char *ptr = NULL;
        unsigned t_len, i=0;

        buf = malloc(sizeof(char) * i_len);
        if(!buf) return 0;

        if(!memcpy(buf, in, i_len)) return 0;

        ptr = strtok(buf, delim);
        if(ptr) {
                t_len = strlen(ptr);
                *t_out = (char **)malloc(sizeof(char*));
                (*t_out)[0] = (char *)malloc(sizeof(char) * t_len);
                memcpy((*t_out)[0], ptr, t_len);
        }
        while(ptr){
                ptr = strtok(NULL, delim);
                if(ptr) {
                        i++;
                        t_len = strlen(ptr);
                        *t_out = (char **)realloc(*t_out, sizeof(char *) * (i+1));
                        (*t_out)[i] = (char *)malloc(sizeof(char) * t_len);
                        memcpy((*t_out)[i], ptr, t_len);
                }
        }
        free(buf);
        return i;
}

int main(int argc, char **argv)
{

        char *in = "split.implementation.of.awk";
        char **out = NULL;
        int i, len = split(in, &out, ".");

        if(out) {
                for(i=0; i<=len; i++){
                        printf("%s\n", out[i]);
                        free(out[i]);
                }
                free(out);
        }
        return 0;
}


[root@Imperfecto_1 ~] gcc -g run.c && ./a.out
split
implementation
of
awk

Valgrind output

[root@Imperfecto_1 ~]# valgrind ./a.out
==2320== malloc/free: in use at exit: 0 bytes in 0 blocks.
==2320== malloc/free: 9 allocs, 9 frees, 91 bytes allocated.
==2320== For counts of detected errors, rerun with: -v
==2320== All heap blocks were freed -- no leaks are possible.

Wednesday, April 24, 2013

Reverse bits in an Integer


A simple function to reverse the bits in an integer

 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
#include "stdio.h"
#include "stdlib.h"

/* Function to reverse the bits
 * Assuming 32 bits.
 * Simple functionality, get the last bit by right shift
 * and insert into the output by ORing and then left shifting.
 * There are better ways to do this.
 */
void reverse(unsigned *input)
{
        unsigned i=0, mask=0x1, res=0x0, tmp = 0x0;
        unsigned in = *input;

        for(i=0; i<32; i++){
                tmp = in & mask;
                in = in >> 1;

                res = res << 1;
                res |= tmp;
        }
        *input = res;
        return;

}

int main(int argc, char **argv)
{

        unsigned input = 0xffffbbbb;
        printf("%x\n", input);
        reverse(&input);
        printf("%x\n", input);

        return 0;
}

[root@Imperfecto_1 ~] gcc run.c && ./a.out
ffffbbbb
ddddffff

[root@Imperfecto_1 ~] echo "ibase=16;obase=2; FFFFBBBB" | bc
11111111111111111011101110111011

[root@Imperfecto_1 ~] echo "ibase=16;obase=2; DDDDFFFF" | bc
11011101110111011111111111111111

Convert IP to Integer

Formula would be :-

First Octet * (256 ^ 3) + Second Octet * (256 ^ 2) 
+ Third Octet * (256 ^ 1) + Fourth Octet

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include "stdio.h"
#include "math.h"

/* Function to convert IP address into Integer
 * Input  : IP address array
 * Output : Converted IP
 */
unsigned int ip_to_int(unsigned in[])
{
        return ((in[0]*(pow(256,3))) + (in[1]*(pow(256,2))) +
                        (in[2]*(pow(256,1))) + (in[3]));
}

int main(int argc, char **argv)
{

        unsigned ip_addr[] = { 192, 168, 1, 124 };
        printf("Input  : %d.%d.%d.%d\n", ip_addr[0], ip_addr[1],
                                        ip_addr[2], ip_addr[3]);
        printf("Output : %u\n", ip_to_int(ip_addr));

        return 0;
}

[root@Imperfecto_1 ~] gcc run.c && ./a.out
Input  : 192.168.1.124
Output : 3232235900

Monday, April 22, 2013

sshd in chrubuntu

Looks like ChrUbuntu (Chrome + Ubuntu) also doesn't come with sshd installed. Let us install it.

apt-get install openssh-server

If your are not the root, use sudo

sudo apt-get install openssh-server

Post installation it runs the sshd service by default.
Verify it

root@ChrUbuntu:~# ps -eaf | grep sshd
root     14580     1  0 21:58 ?        00:00:00 /usr/sbin/sshd -D

Or start the service, either by

root@ChrUbuntu:~# /etc/init.d/ssh start

or by

root@ChrUbuntu:~# service ssh start

That is all it takes ;)

Saturday, April 20, 2013

To print the buffer in HEX

Nothing big, thought I will add this for my own reference. This will print the buffer in hex.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
static void
print_buffer(unsigned *buffer, int len)
{
   unsigned i = 0;
   for(i=0;i<len;i++){
      if(!(i%8)) 
          printf("\n ");
      printf(" 0x%02x",buffer[i]);
   }
   return;
}

You should get an output something like this based on your input
1
2
3
  0x74 0x65 0x73 0x74 0x20 0x6c 0x61 0x62
  0x65 0x6c 0xa0 0xba 0x9f 0x93 0x6c 0xda
  0x31 0x18 0x27 0xa6 0xf7 0x96 0xff 0xd5

Hope this helps someone.