Parsing SIP message body - c

I'm implementing SIP protocol and I'm stuck while parsing SIP message. I'm using the oSIP library. My code is like that:
#include <stdio.h>
#include <stdlib.h>
#include <osip2/osip.h>
#include <osipparser2/osip_parser.h>
#include <string.h>
void main()
{
int i,error;
osip_message_t *message;
char text[]="INVITE sip:jarsku#feanor.pc.lut.fi SIP/2.0\nCall-ID: 123456789#aradan\nVia: SIP/2.0/UDP 157.24.25.137:5060\nFrom: Arto <sip:athamala#feanor.pc.lut.fi>\nTo: Jari <sip:jarsku#feanor.pc.lut.fi>\nCSeq: 1 INVITE\nContent-Type: application/sdp\n\nv=0\na=3333aaa333";
char *p=(char *)&text;
i = strlen(text);
error = osip_init(&message);
error = osip_message_init(&message);
error = osip_message_parse(message, p, i);
}
When I run this code, the message structure is filled with data from text. Respective the fields call_id, content_lenght, content_type, cseq, from, req_uri, sip_method, sip_version, to and vias are filled correctly, but in the field message is value 0x0, message_length is 0 and message_property is 2.
Error codes are 0 for all three commands.
Why is the message body not parsed ? I'm confused of this things:
In RFC is stated, that every line should be ended with CLRF sequence, but I'm simply using \n and it seems like working.
Next I dont like this statement:
error = osip_init(&message);
error = osip_message_init(&message);
For me, is this weird. In the documentation of oSIP is stated that sequence of:
osip_message_t *sip;
osip_message_init(&sip);
osip_message_parse(sip, buffer, length_of_buffer);
osip_message_free(sip);
should be enough (in my code I'm using init and message_init), but this is throwing me a Segmentation fault.
And why is possible, that the field content_length is autofilled but the message is not parsed ?
Last question : why is this topic so terribly covered on Internet ? No manuals, oSIP documentation is bad
Thank you

I think you might be reading the documentation wrong. The function osip_init() wants a osip_t **osip not a message. Re: http://www.gnu.org/software/osip/doc/html/group_howto0_initialize.html

osip_init is not needed to use just the parser, but you should init the parser with parser_init(); instead.

I got the same error as Matka mentioned in his comment.
return value -5 from osip_message_parse
It was due to a malformed sip message that I was passing to the program while debugging.

Related

Polyspace Run-time check alert with C open() function

First, please consider the following piece of code (static function called once from main()):
#define SYSFS_GPIO_DIR "/sys/class/gpio"
#define MAX_BUF ((UI_8)64)
typedef uint8_t UI_8
typedef int32_t SI_32
typedef char CHAR_8
static SI_32 ImuGpioFdOpen(UI_8 gpio)
{
SI_32 fd_gpio_open = -1;
SI_32 byte_count = -1;
CHAR_8 aux_buf[MAX_BUF] = {'\0'};
byte_count = snprintf(aux_buf, sizeof(aux_buf), SYSFS_GPIO_DIR "/gpio%d/value", gpio);
if((byte_count > 0) && (byte_count < sizeof(aux_buf))){
fd_gpio_open = open(aux_buf, O_RDONLY | O_NONBLOCK );
if(fd_gpio_open < 0){
syslog (LOG_ERR,"gpio/fd_open");
fd_gpio_open = ERROR;
}
}
return fd_gpio_open;
}/*ImuGpioFdOpen*/
On the call to open(), static analysis with Polyspace Code Prover raises and alert regarding MISRA's "Dir 4.1 Run-time failures shall be minimized". The alerts says that: "first argument (file path) may not be a valid string"
We don't seem to understand the directive very well, because all our efforts to solve the alerts like this (we have several similar ones) are not yielding results. I mean, we are clearly not building the string correctly, but since the program compiles and runs correctly, we are at a loss.
What kind of run-time check are we missing?
Thank you!
EDIT: I forgot to mention that passing a string literal seems to work for Polyspace, but it doesn't work if we try to pass string generated at runtime (like in the code). Could it be because open()'s prototype declares that the first argument is const char* and Polyspace is taking it too seriously?
The issue has been judged to be a false positive. The alerts shall be justified accordingly.
Thanks!

reading the 'return' value of mruby program via C

I am facing an issue with calling of mruby VM in C. I could invoke the mruby vm and execute the ruby code from C. I could also trigger the methods defined in the ruby code as well. But I am facing issue while trying to read the return value of the ruby method. I have provided my example scenario below.
CODE:
#include <stdlib.h>
#include <stdio.h>
#include <mruby.h>
#include <mruby/compile.h>
int main(void)
{
mrb_state *mrb = mrb_open();
char code[] = "def helloworld() return'OK' end";
printf("Executing Ruby code from C!\n");
mrb_load_string(mrb, code);
mrb_load_string(mrb, "helloworld()");
// How to read the return value?
return 0;
}
I am not sure if this is the right way of calling the ruby methods? I couldnt find any documentation or examples on the web. Anyone who tried calling ruby code via c (using mruby) can you please help me?
Regards,
The return value of mrb_load_string() is the value of the last evaluated expression. But it's also mrb_undef_value() on failure that happened during parsing or code generation like a syntax error. In general the exc member of mrb_state is non-null if there was an uncaught exception:
mrb_value rv = mrb_load_string(mrb, "helloworld()");
if (mrb->exc) { // if uncaught exception …
if (!mrb_undef_p(rv)) { // … during execution/run-time
mrb_print_error(mrb); // write backtrace and other details to stderr
}
}
else {
mrb_p(mrb, rv); // similar to Kernel#p
}
If you only want to call a method, the mrb_funcall() family of functions can be used:
mrb_value rv = mrb_funcall(mrb, mrb_top_self(mrb), "helloworld", 0);
Or:
mrb_value rv = mrb_funcall_argv(mrb, mrb_top_self(mrb), mrb_intern_cstr(mrb, "helloworld"), 0, NULL);
Then the parser and code generator won't be used, thus it'll be faster and unless they're used elsewhere, the executable or (shared) library will be much smaller too. Plus mrb_undef_value() isn't a possible return value, otherwise checking for an uncaught exception and retrieving the return value can be done in the same way.

protoc-c: Nested structure with optional string throws seg fault

Trying out Google protocol buffers for my code in C language.
messagefile.proto
===================
mesage othermessage
{
optional string otherstring = 1;
}
message onemessage
{
optional string messagestring = 1;
optional int32 aninteger = 2;
optional othermessage otr_message= 3;
}
==============================================
--> protoc-c messagefile.proto --c_out=./
this resulted in two files
--> messagefile.pb-c.c and messagefile.pb-c.h
Now my code file which would try to use the
simpleexample.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "messagefile.pb-c.h"
#include <stdbool.h>
int main(int argc, const char * argv[])
{
onemessage msg = ONE__MESSAGE__INIT; //from generated .h code file
void *buf;
unsigned int len;
char *ptr;
//integer initialization
msg.has_aninteger = true;
msg.aninteger = 1;
//accessing the string in onemessage
msg.messagestring = malloc(sizeof("a simple string"));
strncpy(msg.messagestring,"a simple string",strlen("a simple string"));
//trying to initialize the string in the nested structure othermessage
msg.otr_message = malloc(sizeof(othermessage));
msg.otr_message->otherstring = malloc(sizeof("a not so simple string"));
strncpy(msg.otr_message->otherstring,"a not so simple string",strlen("a not so simple string"));
//lets find the length of the packed structure
len = one_message__get_packed_size(&msg); //from generated .h code
//lets arrange for as much size as len
buf = malloc(len);
//lets get the serialized structure in buf
one_message__pack_to_buffer(&msg,buf); //from generated code
//write it to a stream, for now the screen
fwrite(buf,len,1,stdout);
//free buffer
free(buf);
return 0;
}
I compile it as gcc -o testout messagefile.pb-c.c simpleexample.c -lprotobuf-c
The Problem I am facing is when trying to initialize the nested othermessage variables and then call the get_packed_size it throws a segmentation fault.
I tried various combinations and I can say that whenever having strings in a nested class, I am facing problem to access those using google protoc.
Am i missing something? Is there anything wrong.
Can anyone please help.
note:There might be a few general syntax errors please ignore them.
ThankYou.
note:There might be a few general syntax errors please ignore them.
Err... they are kinda hard to ignore since your code does not compile :-)
Anyway, apart from the syntax errors, you need to make several corrections to your code. In order to use the field otr_message, it is not sufficient to just malloc() it. You also need to initialize it so the headers in the message get the right values. This is done with init(), like this:
//trying to initialize the string in the nested structure othermessage
msg.otr_message = malloc(sizeof(othermessage));
othermessage__init(msg.otr_message);
Then you use the wrong function to do the packing to your own array. As explained here, you need to use pack() as opposed to pack_to_buffer(), like this:
//lets get the serialized structure in buf
onemessage__pack(&msg,buf); //from generated code
Finally, your strncpy() invocations have a mistake. The length calculated with strlen() does not include the null terminator, which you do need. So you need to take strlen()+1 or use sizeof(), like this:
strncpy(msg.messagestring,"a simple string",sizeof("a simple string"));
After making those changes, the example worked for me:
$ ./testout
a simple string
a not so simple string

Why Rename in C not working correctly?

It was working correctly a while ago. But i dont know what was is the error.
My Code:
char oldfn[] = "d://booksdata.txt";
char newfn[] = "d://booksdata_temp.txt";
remove(oldfn);
rename(newfn, oldfn);
Remove function works correctly but my rename function does not work.
From ISO/IEC9899:
7.19.4.2 The rename function
Synopsis
1 #include < stdio.h>
int rename(const char *old, const char *new);
As you can see by the prototype: you are using the old and new arguments in the wrong place.
Just switch then and one error is fixed.
If there is still one... Tell us the error text please.
I think you have the rename() call backwards. It should be:
rename(oldfn, newfn);
Although it wouldn't hurt to have copied the error message in the first place!

libxml2: Not report characters like ' or " individually

I'm new to libxml and so far everything is good, but I noticed one thing that annoys me:
When libxml reports characters, i.e. the handler's characters function is being called, "special" characters like ' or " or reported individually.
example:
"It's a nice day today. Don't you agree?"
report:"
report: It
report: '
report: s a nice day today. Don
report: '
report: you aggree?
report: "
Is there any way to change that behavior, so it would be reported as a complete string?
Don't get me wrong, it's not a problem to use strcat to put the original string together, but that's additional work ;)
I searched the headers and the net and found no solution. Thank you in advance.
Edit: Because the handler description above needs some more explaining.
By reporting characters I mean when the handler's (htmlSAXHandler) handler.characters callback function is called, which I assigned:
void _characters(void *context, const xmlChar *ch, int len) {
printf("report: %s\n", chars);
}
You might want to look at DOM parsing instead of registering SAX callbacks, if your document isn't going to be so large that you can't hold it all in memory.
#include <stdio.h>
#include <libxml/HTMLparser.h>
#include <libxml/tree.h>
int main()
{
htmlDocPtr doc;
xmlNodePtr root, node;
char *output;
char *rawhtml = "<html><body>\"It's a nice day today. Don't you agree?\"</body></html>";
doc = htmlReadDoc(rawhtml, NULL, NULL, XML_PARSE_NOBLANKS);
root = xmlDocGetRootElement(doc);
node = root->children;
output = xmlNodeGetContent(node);
printf("output=[%s]\n", output);
if(output)
xmlFree(output);
if(doc)
xmlFreeDoc(doc);
}
produces
output=["It's a nice day today. Don't you agree?"]
I'm afraid you should live with that. If you encounter an HTML document with 100K chars do you also expect it to deliver all chars in one go? I think you should just be ready for splitting the characters at any moment. Then splitting them at special characters makes no difference.
This answer is not adequate if your software aims to read only small HTML documents, but I bet that the libxml authors were not thinking of special handling for such cases.

Resources