0

Using (learning) c to create a mini packet sniffer which adds the src IPs to a json object and adds them to a json array.

The pcap filter works without issue, and now I'm trying to create a json object of the src ips and a counter of packets sent to this IP.

{
    "ips": [
        {
            "ip": "1.2.3.4",
            "count": 10
        },
        {
            "ip": "4.3.2.1",
            "count": 103
        }
    ]
}

Excluding all the pcap code, I have a loop as so:

pcap_loop(pcap, 1000, ethernet_packet, NULL);

Within the ethernet_packet function, I created an array for the IPs so I could check if one had already been added.

if (!array_contains(buf, src_ip)) {
  // Do things
}

int array_contains(char *array, char *ip ) {
  if ( strchr(array, *ip) )
    return 1;
}

Here's what I have so far which was supposed to get the IP and add to the array:

void ethernet_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet)
{

  static int count = 1;
  printf("\nPacket number %d:\n", count); */
  count++;

  struct json_object *obj1, *obj2, *array;
  array = json_object_new_array();
  obj1 = json_object_new_object();

  char buf[MESSAGE_BUFF_LEN];

  /* Some Pcap stuff to get the ips etc. */

  src_ip = inet_ntoa(ip->ip_src);

  if (!array_contains(buf, src_ip)) {
   /* Add IP to array */
   sprintf(buf, src_ip);

   /* Create a new object */
   obj2 = json_object_new_object();
   json_object *jstring = json_object_new_string(src_ip);
   json_object_object_add(obj2,"ip", jstring);

   /* Add to array */
   json_object_array_add(array,obj2);
  }
}

The problem I have is that the object isn't added to an existing array, it creates a new one each time.

The json object created: [ { "ip": "79.65.10.0" } ]
The json object created: [ { "ip": "80.152.10.0" } ]
The json object created: [ { "ip": "99.211.10.0" } ]

I even tried checking the type of object at the start of the loop and only initialising when it was not an array but that threw an error when trying to add.

It's probably obvious to someone who's spent more than 2 days with c but I don't understand how to fix this.

What's the best / most efficient way to solve this?

--- EDIT ---

Have it working by checking the type and initialising if it's not an array. Just not sure this is the best way to do so.

Full code for the fn is here:

https://gist.github.com/simonmorley/9850f2a42453e4f54b75

simonmorley
  • 2,810
  • 4
  • 30
  • 61
  • the ips are different so isn't this correct that new object are created? – 4pie0 Aug 30 '15 at 14:06
  • @tinky_winky no, they should be in a single array. Just got it working by not added the array to the parent and using a select for json_type_array to test if it's empty. Just doesn't seem efficient to do this for thousands of packets. – simonmorley Aug 30 '15 at 14:10
  • what is res in ethernet_packet? please add complete code – 4pie0 Aug 30 '15 at 14:17
  • @tinky_winky - typo when copying, edited. Should have been array. – simonmorley Aug 30 '15 at 14:19

1 Answers1

0

This is wrong

char buf[MESSAGE_BUFF_LEN];
/* Some Pcap stuff to get the ips etc. */
src_ip = inet_ntoa(ip->ip_src);
if (!array_contains(buf, src_ip)) {

because buf is initialized with garbages, as it is local variable, so doing strchr on its content is not what you want.

Additionally, it seems like you are not adding the object to correct array:

/* Add to array */
json_object_array_add(res,obj2);
//                    ^^^
4pie0
  • 29,204
  • 9
  • 82
  • 118