itevad – How to write your own protocol and its stack – part 3

Previous_Part_2

In this post, we will focus on writing Itevad Protocol Binary Ber Encoder. With the necessary headers and sources generated in Part_2, now we could write our Ber Encoder. Then we will run our encoder and use hexdump to see what is our Itevad msg looking like. Fire!

/* Ber encoder for Binary Itevad Protocol */
[root@localhost itevad2]# cat itevadBerEncoder.c
/*
Itevad Protocol Binary Ber Encoder Example
http://daveti.blog.com
April 1, 2012
Reference: Using the Open Source ASN.1 Compiler
by Lev Walkin
*/

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include "ItevadMessage.h"

/*
 * This is a custom function which writes the
 * encoded output into some FILE stream.
 */
static int
write_out( const void *buffer, size_t size, void *app_key)
{
 FILE *out_fp = app_key;
 size_t wrote;
 wrote = fwrite( buffer, 1, size, out_fp);
 return ((wrote == size) ? 0 : -1);
}

int main( int ac, char **av)
{
 /* Type to encode */
 ItevadMessage_t *itevadMsg;

 /* Encoder return value */
 asn_enc_rval_t ec;

 /* Allocate the ItevadMessage_t */
 itevadMsg = calloc( 1, sizeof(ItevadMessage_t));
 if ( !itevadMsg)
 {
 perror("calloc() failed");
 exit(71); /* better, EX_OSERR */
 }

 /* Initialize the ItevadMessage members */

 /* Set version number - 1 */
 itevadMsg->version = 1;

 /* Set IPv4 address - "1111" */
 if ( OCTET_STRING_fromString( &(itevadMsg->ip4Address.address), "1111") == -1)
 {
 perror("OCTET_STRING_fromString() failed for encoding 'address'");
 exit(71);
 }

 /* Set port number - 7777 */
 long portNumber = 7777;
 itevadMsg->ip4Address.portNumber = &portNumber;

 /* Set the msg as a request */
 itevadMsg->messageBody.present = MessageBody_PR_messageRequest;

 /* Set the transId - 0xffff */
 long transId = 0xffff;
 if ( asn_long2INTEGER( &(itevadMsg->messageBody.choice.messageRequest.transactionId),
 transId) == -1)
 {
 perror("asn_long2INTEGER() failed for encoding 'transId'");
 exit(71);
 }

 /* Set the askContent - 'who r you?' */
 const char* askContent = "who r you?";
 if ( OCTET_STRING_fromString( &(itevadMsg->messageBody.choice.messageRequest.askContent),
 askContent) == -1)
 {
 perror("OCTET_STRING_fromString() failed for encoding 'askContent'");
 exit(71);
 }

 /* BER encode the data if filename is given */
 if ( ac < 2)
 {
 fprintf( stderr, "Specify filename for BER outputn");
 }
 else
 {
 /* NOTE: need memory deallocaiton before exit ! */

 const char *filename = av[ 1];
 FILE *fp = fopen( filename, "wb"); /* for BER output */
 if ( !fp)
 {
 perror( filename);
 exit(71);
 }

 /* Encode the ItevadMessage type as BER (DER) */
 ec = der_encode( &asn_DEF_ItevadMessage, itevadMsg, write_out, fp);
 fclose( fp);

 if ( ec.encoded == -1)
 {
 fprintf( stderr, "Could not encode ItevadMessage (at %s)n",
 ec.failed_type ? ec.failed_type->name : "unknown");
 exit(65); /* Better, EX_DATAERR */
 }
 else
 {
 fprintf( stderr, "Created %s with BER encoded ItevadMessagen", filename);
 }
 } /* else... */

 /* Also print the constructured Itevad XER encoded (XML) */
 xer_fprint( stdout, &asn_DEF_ItevadMessage, itevadMsg);

 /* NOTE: Need memory deallocaiton here! */

 /* Encoding finished successfully */
 return 0;
}
[root@localhost itevad2]#


/* Generate and run itevadBerEncoderBin */
[root@localhost itevad2]# gcc -I. -o itevadBerEncoderBin *.c
[root@localhost Itevad2]# ./itevadBerEncoderBin itevad_binary.msg
Created itevad_binary.msg with BER encoded ItevadMessage
<ItevadMessage>
    <version>1</version>
    <ip4Address>
        <address>31 31 31 31</address>
        <portNumber>7777</portNumber>
    </ip4Address>
    <messageBody>
        <messageRequest>
            <transactionId>65535</transactionId>
            <askContent>who r you?</askContent>
        </messageRequest>
    </messageBody>
</ItevadMessage>
[root@localhost Itevad2]# hexdump -C itevad_binary.msg
00000000  30 24 80 01 01 a1 0a 80  04 31 31 31 31 81 02 1e  |0$.......1111...|
00000010  61 a2 13 a0 11 80 03 00  ff ff 81 0a 77 68 6f 20  |a...........who |
00000020  72 20 79 6f 75 3f                                 |r you?|
00000026
[root@localhost Itevad2]# hexdump -c itevad_binary.msg
0000000   0   $ 200 001 001 241  n 200 004   1   1   1   1 201 002 036
0000010   a 242 023 240 021 200 003   377 377 201  n   w   h   o
0000020   r       y   o   u   ?
0000026
[root@localhost itevad2]#

About daveti

Interested in kernel hacking, compilers, machine learning and guitars.
This entry was posted in Dave's Tools, H.248/MEGACO/EGCP, Programming, Stuff about Compiler and tagged , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.