ABOUT THIS DOCUMENT
===================

This document contains a number of rules for the HIPL project and
related projects. The intention of this document is to provide
everyone with a common understanding of the standards and rules in
the project. Please read these rules carefully. With your first
commit to the project repository you implicitly indicate that you
read and understood all of the rules in this document.

The intention of this document is not to make your life as a programmer
harder. On the contrary: everyone wants and deserves to work with
good code. Only if you (you personally) adhere to the following
rules, can we ensure code quality and joy while working with HIPL.
You are in this project for two reasons: to learn and to work.
Take your time to learn how to do things properly and take your time
to do things properly. Reading this document completely is your
first step towards this goal.

EVERYTHING in this document is important. We would not take the
effort to write anything down if we wouldn't care about it with
every pore. Please read every single line in this document. It may
take some time but it will help you to fit into the project neatly.

This document is continuously updated. Feel free to add more information
if you feel that we missed an important topic.



HOWTO Bazaar VCS
================

This step by step guide will provide you with the knowledge necessary
to develop with Bazaar on a day-to-day basis. For more detailed
information, please follow the links provided below.


Setting up Bazaar
-----------------

Before you start working with Bazaar, you should provide some
information about yourself, such that your work can be properly
identified in the revision logs.

  bzr whoami "#FIRST_NAME# #LAST_NAME# <#EMAIL_ADDRESS#>"


Bazaar plugins
--------------

HIPL comes with Bazaar plugins which are very strongly recommended because
they help with improving code style and quality.
They can be installed with the following commands:

#> mkdir -p ~/.bazaar/plugins
#> cp tools/bazaar/plugins/* ~/.bazaar/plugins/


Creating a local shared repository (optional, but recommended)
--------------------------------------------------------------

Bazaar does not only provide a working copy and history information
for the current revision, but instead it maintains the complete
history of a retrieved branch locally. This allows Bazaar to
dramatically speed up operations such as log, diff, annotate and
merge. The advantage of having a shared repository is that all history
information will be shared among the branches set up within this
repository. As branches are expected to share a lot of common history
in our branch layout, this step will result in:

- quicker creation of additional local branches,

- faster merging, due to purely local operations,

- history located in the top-level directory and not in branch directories
  (especially good in case you are using Eclipse or other IDEs).

To create a local shared repository run

  bzr init-repo #REPOSITORY_NAME#

Change into the just created repository before continuing with the next
steps.

  cd #REPOSITORY_NAME#


Getting the history of a remote branch
--------------------------------------

Bazaar allows a centralized SVN-like workflow, i.e. each commit is applied to
the local as well as to the remote repository in one go. This means you have
to be online in order to commit changes. The command associated with this
kind of tracking branch is checkout.

  bzr checkout lp:hipl

NOTE: If this is the first branch you check out into a local shared
repository or if you are merely checking out this branch stand-alone,
the checkout will take some time, as the history information currently
accounts for about 200MB.

If you checkout a branch as described above, you just have to run an
update from within the branch directory in order to retrieve the most
current revision of the branch.

  bzr update


Committing to a remote branch
-----------------------------

If you checkout a branch as described above, doing a commit from within the
checkout directory will try to apply your changes to the remote repository.

It is good practice to ALWAYS check your modifications and to ensure
that your commit only contains changes you actually want to publish at
that very moment:

  bzr diff

If bzrtools are installed, you can get colorized output:

  bzr cdiff

NOTE: By providing the parameter -r #REVISION#, you can create a diff
against the specified revision.

Once you have confirmed that your modifications are correct, you can
commit the changes:

  bzr commit

NOTE: Please, don't use the -m "#COMMIT_COMMENT#" option. It is strongly
encouraged to use an editor for your commit messages.

Good log messages consist of a one-line summary followed by an empty line
and then a more detailed description of your changes. Your fellow developers
will have much less trouble understanding your changes and will be able to
employ the extra information for bug fixes in the future.

NOTE: To automatically close a bug in launchpad, use

  bzr commit --fixes lp:#BUG_ID#

NOTE: You can set your preferred editor by editing the [DEFAULT] section of
the Bazaar configuration located at $HOME/.bazaar/bazaar.conf, e.g.:

[DEFAULT]
BZR_EDITOR = nano

NOTE: To support code quality and style, please use the stylecheck pre-commit
hook found in tools/bazaar/plugins/stylecheck.py - this script contains its own
documentation, including how to set it up. See also 'Style Checking'.

TBD: further useful commands

  bzr conflicts/resolve

A list of possible conflicts can be found at:
http://doc.bazaar.canonical.com/bzr.2.0/en/user-reference/index.html#conflicts-types

NOTE: If you commit a patch by someone else, use the --author parameter for
correct attribution.


Fixing mistakes
---------------

Everybody makes mistakes, so - inevitably - you will as well. If you botched a
local commit you can use

  bzr uncommit

to undo it and start afresh. However, if you have committed or pushed a change
to the central repository then you must *NEVER* uncommit it. If you do it, you
will wreak havoc with the repositories of other developers that have pulled
changes from the central repository in the meantime. Also note that there are
automated build bots like the HIPL autobuilder, the ohloh.net enlistenment and
possibly others that pull from the central repository and are unable to cope
with conflicts caused by messed-up history. Inconsistent repository states can
only be fixed via manual intervention there and might go unnoticed for a long
time.

This is so important that it bears repeating: *NEVER* mess with the history
of the central repository through uncommit or similar means. If you fail to
abide by this rule you will be publicly shamed, laughed at, tarred, feathered
and put on display in the heart of your city for bystanders to insult, spit
at and mistreat you. Afterwards you will be dipped in honey and dropped into
your choice of a termite mound or ant colony and finally abducted by aliens
to a lonesome place in the remotest north of Finland where nobody can hear
you over the maniacal laughter of mad scientists tormenting their human
victims. In short: Don't do it, ever. :-)



C CODING QUALITY
================

HIPL is a project written in C. There are several best practices
and language constructs in C that can help you improve your code
quality considerably. Since everyone in this project depends on the
quality of your code we expect you to write it carefully as much
as you expect everyone else to write their code carefully. No one
likes to work in a mess. Please don't leave one.

Some of the following programming guidelines (marked with an *) are
taken from a book by Robert Martin: "Clean Code". Ask your adviser
for the book if you want to read more. Some rules are basic C
programming best practices and some are even standard C language
constructs. Take your time to go through these rules. They will
help you become a better programmer and they will protect you from
messy code.


The boy scout rule*
-------------------

"Leave the camping ground cleaner than you found it". This is a
simple yet powerful rule. We try to work with code in a professional
manner. However, you may encounter code parts that can be improved.
Don't take these code parts as justification to also produce messy
code but improve them. Try to leave the code in a better shape
than you encountered it. Your efforts will be noticed by
your adviser and will not be forgotten.


The compiler is your friend:
----------------------------

The GCC compiler is a great tool that can save you hours of run-time debugging
if you decide to listen to it. In HIPL we use a number of GCC warning options
that will provide you with detailed warning output in cases where the compiler
suspects something is wrong.

Since HIPL has -Werror in CFLAGS these warnings will be treated as errors and
halt compilation. Be sure to fix the underlying issues that caused a warning
properly. If you just quickly paper over a warning you may mask serious errors
and make them really hard to debug later on. Just doing a change to silence the
compiler is not an option because the code will soon break and the code base
deteriorate. Instead you should try to understand the underlying problem that
the compiler complains about (not the symptom). For example:

  Cast align warnings tell you whenever two structs that are not
  compatible are assigned and casted. There are two things you
  can do about a cast align warning. You can either cast the
  source struct to void* and the compiler will not notice the
  problem anymore and won't produce the warning. Although this
  option suppresses the warning, this is NOT intended programmer
  behavior. The right way to do it is to look at the structs,
  read about the problem in Internet resources, think about the
  problem and rearrange the structs using unions and such. Although
  this takes some time you will have a proper solution to the
  problem and you will not have ugly surprises (e.g., hard to
  track run-time errors.)

So the main point of the above section is: Don't take the easy
path that only treats the symptom. Cure the cause. This will save
you trouble in the long run. Listen to the compiler and take its
warnings seriously.


Tell your friend (the compiler) what you are doing
--------------------------------------------------

C has a number of language constructs that do not provide
functionality but rather enable the compiler to do some sanity
checks on your and others' codes. These little helpers are the
keywords "static" and "const" in function definitions/declarations.
If you have only been working in small projects (e.g. homework
assignments) you probably haven't really used these mechanisms
because you don't see the necessity. However in larger projects
that live for quite some time, these keywords are not just useful
but essential because they can help the compiler detect errors
that happen when different persons work with the same code base.
Learn what these keywords do and use them appropriately! A short
explanation will help you understand why we rely on these little
helpers.

  Const: const tells the compiler that something is not supposed
  to be changed. It can be applied to variables and function
  parameters. When writing a new function, take some time to
  consider which input parameters may be changed within this
  function and which shouldn't be changed. Add const wherever
  you believe that a parameter should not be touched. Use const
  generously!  Const can help you to discover errors like unwanted
  modification of variables, function calls with mixed up function
  parameters, etc. Missing a const is considered an error although
  the code works. Please take care.

  Static functions: Making a function static tells the compiler
  that it is only used in the C file in which it is defined. This
  makes it easy for the compiler to find functions that are used
  nowhere. Funding unused functions can be very hard in code that
  is maintained by a number of people. Unused functions are dead
  code that is not tested anymore. They should be removed because
  someone could try to use them again not knowing that the function
  wasn't tested for months and does something slightly wrong.
  Moreover, the keyword static tells other programmers: Stop! You
  are not supposed to use this function in another file. This
  helps programmers identify the functionality that is supposed
  to be used within a module and the functionality that the module
  (C file) provides as interface.This distinction is essential
  if you try to maintain data integrity (cf. Section about Header
  files).

Please make sure that you help the compiler and your co-workers
in doing a good job. Use const and static properly.


Header Files
------------

Since C headers are included from many other files, the contents
of the *.h files must be selected carefully. Otherwise the global
namespace of C is polluted with tons of globally visible declarations
and definitions. These globally visible declarations can clash with
other declarations and thus make working with, understanding and
maintaining a C project a pain.

A header file serves a single purpose: it is an interface. It
declares symbols for EVERY file that includes the .h file so that
the compiler knows what's in the .c file. Three things that a
header file is NOT.

A) An overview of the contents of the .c file and
B) a good place to define stuff that's used in the .c file,
C) a good place to make forward declarations for the C file.

Hence, header files should ONLY contain things of the *.c file
that are used by OTHER *.c files. Don't put stuff in the header
file that is used only in the C file. Put that stuff in the C
file and make it static.

Selectively putting stuff into header files helps understanding
the code because people can just look at the header file and see
what functions they are supposed to use when working with that
header file. Everything in there is free for use and you don't
have to worry that you mess up by calling the wrong functions.

Selectively putting stuff into header files also prevents namespace
conflicts.


Copy & paste and external code
------------------------------

Copying code from somewhere else (within the project as well as
from outside the project) is a bad habit and an absolute no-go.
First, copying from within the project is a sign of poor software
design. If you need a particular piece of code in a different
context consider generalizing the function that provides the code
instead of just copying it. Copy & paste programming leads to
duplicated code. Duplicated code is often redundant and doubles
the maintenance overhead. Moreover, copied code often does not solve
the problem well and uses names and types that are not appropriate
for solving the problem. Copy & pasting code is bad. Don't do it.
If you feel the urge to copy code from somewhere within the
project, ask your adviser first!

Copying code from outside the project is even worse. By doing it,
you inject code for which someone else can claim authorship into
the project. We try to keep our licensing situation (GPL, LGPL,
etc.) as straightforward as possible. Mixing code from different
(possibly unknown) sources with unknown or incompatible licenses
puts the whole project in jeopardy. This applies to code from
other projects but also to example code found in wikis and forums.
If you think you need to copy code from somewhere else inform your
adviser about it BEFORE you do it. Please take this very seriously.


On naming*
----------

Names (function names, file names, parameter names, variable
names) are important: It's one of the core task of a programmer
to use good names. Names should be consistent with the rest of
the code base.

Names should convey the intention of the code. Names should be
unambiguous (show real differences between things)

Be careful with unspecific names containing words like info, data,
etc. they just confuse people. Be as specific as possible.

Use shorter names for things that are only used in a very restricted
context (just a few lines). The larger the context, the longer
the names - things should not be ambiguous in a large context.
Single letter names (i, j, k, ...) are reserved for integer counter
variables only.

We use underscores (_) to structure names - No CamelCase!


On namespaces
-------------

C reserves names starting with two underscores '__' and those starting with
an underscore '_' and a capital letter for the system. Other names starting
with an underscore are reserved at the file level, i.e. should only be used
for file-local symbols. To not have to worry about such fineprint we forbid
all names starting with underscores in HIPL.

POSIX reserves the _t suffix namespace. Avoid creating identifiers that
pollute this namespace.

Note that pollution of the POSIX and system namespaces is extremely common in
other projects as it was in HIPL before this issue was addressed. Please do
not copy from these bad examples and keep your environment clean.


On Functions*
-------------

Functions should be short - period. Long functions are a sign
that you try to do too much within a function. Long functions are
error magnets because they are hard to understand and they lack
proper problem boundaries. They are a pain to maintain, ... you
got it: they are pure evil. Try to keep your functions simple and
short. If you write a function with more than 30 lines: reconsider
and try to split it up into sub-functions. If you write a function
with more than 50 lines tell your adviser about it and discuss its
necessity with him. As usual you will find functions with more
than 50 lines in the code. The existence of these behemoth functions
is, of course, no justification for introducing more long functions
but an encouragement to split up these monsters.

Likewise, functions with many arguments are error magnets, too.
Again they are hard to maintain, provoke errors, ... and are evil,
too. If you feel the need to write a function with more than four
parameters: reconsider and try to find out why you have so many
parameters there. If you write a function with six or more
parameters, inform you adviser.

Short functions with good names are easy to understand, make
finding errors simpler and help to prevent bugs and bad code.
Everyone else dislikes long functions as much as you do. Don't
pester others with them.


On Types
--------

Be very careful which type you use for a variable. Be very careful
about the signedness of a variable. Short, int, and long are
signed types by default, meaning that they are designed to hold
positive and NEGATIVE values. Don't use signed types if you only
expect positive values. Mismatches in signedness are often the
cause for security weaknesses like buffer overflows.

Use typedefs where appropriate. However, note that typedefs are
not a tool for saving keystrokes. Don't define typedefs as
shorthands for structs. Use typedefs when you want to convey
additional semantics. Sometimes typedefs are useful (e.g. for a
special data type for which the concrete type may change in the
future (short, long) or if a generic type would be misleading:
some things stored as ints are not necessarily integers.

Prefer enums over long lists of preprocessor defines. The compiler
will see the enums and it can give you useful hints. In general,
prefer to not use the preprocessor but the compiler. The compiler
is much smarter.  Rather use global constants than preprocessor
defines. They are typed and help the compiler make smart choices.


On Magic Numbers
----------------

Magic numbers are numbers that pop up in the code without context.
Almost every number you find in code can be considered a magic
number. For example:

  unsigned int special_prize[52];
  unsigned int extra_winner;
  unsigned int i;

  extra_winner = rand() % 52;

  for (i = 0; i < 52; i++) {
      special_prize[i] = extra_winner;
  }

What does the number 52 stand for? Is the first 52 related to the
second one? If I decide to choose the winner from 56 numbers do
I have to change the second occurrence of 52 as well? 52 is
obviously a magic number. The use of definitions and constants
can make the code much easier to understand:

  unsigned int special_prize[WEEKS_PER_YEAR];
  unsigned int extra_winner;
  unsigned int i;

  extra_winner = rand() % NUM_CLIENTS;

  for (i = 0; i < WEEKS_PER_YEAR; i++) {
      special_prize[i] = extra_winner;
  }

If a programmer had changed all occurrences of 52 in the first
example above to 56 the result would have been pure nonsense. In
the second example it is clear what happens. The example shows
an extreme case of a magic number but small numbers like 1 and 2
can also be magic numbers.

Another bad thing about magic numbers is that it is hard to grep
or search for them. Try to grep for 1 or 2 in your source tree.
You'll find way too much. If you use a good constant name you can
easily search for it and identify the relevant code parts.

Therefore: NO magic numbers. Nowhere.



CODING STYLE
============

C code formatting and style:
----------------------------

NOTE: As a tool to help with good style, please use the stylecheck pre-commit
hook found in tools/bazaar/plugins/stylecheck.py - this script contains its own
documentation, including how to set it up. See also 'Style Checking'.

HIPL uses the Kernighan & Ritchie (K&R) coding style in the one true brace
style (1TBS) variant. Indentation width is four spaces.

K&R style was chosen because it is the most common style and the
one used by the creators of C. Insisting on another style is thus
inherently heretical.

Here is a quick reminder of what K&R style means in practice:

- spacing:
  In general use spaces generously, i.e. place a space

    * between keywords and '(' (except for sizeof),
    * between ')' and '{',
    * around operators (+, *, /, &, &&, ||, etc.),
    * after ',' - for example in function arguments.

  but avoid spaces

    * between function names and '(',
    * inside '()'.

- brace placement:
  Opening braces should be kept on the same line as the corresponding
  statement, except for functions where the opening brace is placed
  on the next line.

  Optional '{}' for control statements (if/for/while/..) should
  always be added.  This is the 1TBS variant of K&R style.

- case statements are not indented separately, they remain at the
  same level as the corresponding switch statement.

- The function type should be kept on the same line as the function
  name.


In addition to K&R style
------------------------

- line length:
  Long lines (>80 characters) should be broken at suitable places if
  and only if doing so improves readability. Broken lines should not
  be mechanically indented by four spaces. Instead they should be
  indented for optimum readability. For example function arguments
  placed on the next line should align with the first character
  after the '('.

- prettyprinting:
  In cases where this improves readability, vertical alignment
  around operators etc. should be applied.

Remember that code should be formatted consistently to aid readability,
especially for people unfamiliar with the code.

If in doubt you can use the uncrustify tool to format code for you.
It should do the right thing. A suitable configuration file that
was used to initially reformat HIPL can be found in '.uncrustify.cfg'.

Here is an example piece of C code to showcase K&R style as used
in HIPL. Pay special attention to spacing and the placement of
parentheses:


#include <stddef.h>     // System #includes come first, use <> and
                        // are separated by an empty line from
#include "header.h"     // local #includes, which use "".

struct whatever {
    /* Observe how the variable names and the stars are aligned. */
    int            var;
    float         *var2;
    char          *var3;
    struct ip_pkt  pkt;
}

/* Function declarations are broken down to avoid overly long lines. */
static void a_function_with_a_long_name(struct ip_pkt *pkt,
                                        struct opaque op,
                                        int value)
{
    int i;

    /* Notice that the = signs are aligned. */
    pkt->destination_addr = local_destination;
    pkt->source_addr      = local_source;
    pkt->other_member    += value;

    switch (value) {
    case CONSTANT_FOO:
        transmogrify(value);
    case CONSTANT_BAR:
        inspect(&pkt);
    }

    /* Note where spaces are placed and left out in this block. */
    if (value <= CONSTANT1 && value >= CONSTANT2) {
        some_function(addr, op, value);
    } else {
        for (i = 0; i < 100; i++) {
            some_other_function(addr + i, hl / i,
                                strange_name_function(sizeof(op.member)));
        }
    }
}


Style Checking
--------------

As a tool to help with good style, please use the pre-commit hooks in the
directory tools/bazaar/plugins/ - installing them should be as easy as
copying them to your Bazaar plugin directory:

#> cp tools/bazaar/plugins/* ~/.bazaar/plugins/

Currently, there are two Bazaar plugins:
- The commit guard plugin implements a set of pre-commit hooks that check
  general style conventions in HIPL, e.g., that all files must have UNIX-
  style line breaks.
- The stylecheck plugin specifically uses a code beautifier to check for
  C code-style violations. More on it below.

Both scripts contain their own documentation, including how to set them up.

You are strongly recommended to use stylecheck based on the code beautifier
uncrustify because it gets things right almost all the time. So you can and
should throw all code at uncrustify (via the commit hook) to have it checked.

Currently the only problem is alignment of consecutive variable declarations and
initializations (where uncrustify might accidentally align unrelated code or not
align related code). Obviously, it never hurts to check the uncrustify output.

If the above style recommendations are unclear about a topic, you should trust
the style decisions that uncrustify takes.

The style rules used by uncrustify can be found in the .uncrustify*.cfg files in
the top-level directory of the HIPL sources. If these rules need to be changed,
please make sure that
0) other developers are OK with the change in code style;
1) the modified rules have no undesirable side-effects across the code base
   (always test new rules with the whole code base);
2) all .uncrustify*.cfg files are modified and the rules remain consistent.

The rationale for introducing and using the uncrustify-based pre-commit hook has
been derived from the HIPL development process. The fundamental problem is that
poor style ties up resources and precious time. How? Well, first of all, it can
be difficult to get code style right manually. Thus, a lot of commits and merge
proposals can contain varying amounts of style violations of varying severity.
Consequently, code reviewers are forced to look out for and comment on style
violations and thus have less time to focus on a meaningful semantic review,
spotting actual bugs or defects. And spending time on minor, non-functional
issues creates friction both for the reviewers and the original authors.

Thus, checking and enforcing style automatically may not always produce the
perfect result but it frees valuable developer time for more important tasks.

To manually uncrustify the whole code base, you can execute, e.g., the
following command:

find . -name \*.[ch] |
  xargs uncrustify -c .uncrustify-0.57.cfg --no-backup --replace

CODING CONVENTIONS
==================

- Do NOT use typedefs for structures, enumerations or pointers.
  Typedefs, in these situations, do NOT improve code readability.

- Comment only in English. Do not use special characters (umlauts,
  accents, etc.) even if your name contains one and you add your
  name to the authors list. Use ASCII compatible workarounds. This
  may have some ugly side effects with some editors.

- There should be a doxygen header for EVERY function (see
  DOCUMENTATION)

- Don't invent your own coding style. It will give the code an
  untidy look.

- Use under_scores instead of CamelCase

- HIPL code should use the prefix "hip_" in all functions and
  global variables

- Use global variables only with GOOD reason. Ask your adviser
  before introducing a new global variable.

- USE ASCII encoding, no fancy symbols!

- Do not make unreadable code by nesting code too much:

  if (foo) {
      if (bar) {
          if (hello) {
              confuse_me();
          }
      }
  }

  Instead, join the conditional expressions (foo && bar && hello)
  or use goto (goto skip;). However, use goto only for error handling.

- Declare variables before all statements, not in the middle of the code:

  int foo
  {
      int i;  /* integers declared in the beginning of the function */
      char c;

      bar();

      for (i = 0; i < 100; i++) {
          int x; /* This is fine because it is after the beginning
                  * brace of the loop. */
          hello(i, x);
      }
  }

- All functions should return an error value instead of "ok" value. That, is
  zero for success and non-zero for failure.

- Use the HIP_IFE, HIP_IFEL macros to reduce the number of lines of code.

- Memory (de)allocation procedure is as follows:

  int f(void)
  {
      char *mem = NULL;
      HIP_IFEL(!(mem = HIP_ALLOC(256, 0)), -1, "alloc\n");

  out_err:
      free(mem);
      return err;
  }


EMACS
-----

To adjust emacs to the right spacing conventions for the code, you can
add the following lines to your *empty* ~/.emacs configuration file:

(setq c-default-style "k&r")
(setq-default c-basic-offset 4)
(setq-default indent-tabs-mode nil)

If you have other configurations in your ~/.emacs, may need to
surround this by c-mode-hook and lambda function:

(setq c-mode-hook
    (function (lambda ()
        (setq c-default-style "k&r")
            (setq indent-tabs-mode nil)
            (setq c-basic-offset 4)
            (setq c-indent-level 8))
    )
)


ECLIPSE
-------

Eclipse is an IDE originally developed for Java but there's also
CDT (C/C++ Development Tooling) extension that can be used while
developing for HIPL. It has a nice IDE similar to Visual Studio
but it also consumes resources more with compared to editors such
as vi or emacs.

First download Eclipse-CDT from the Eclipse site. It is more convenient
than downloading from CDT because Eclipse site has it set up already.

Then follow these steps for creating a project:

1. Get the files to your local drive from the repository with bzr.
2. Select File/New/C Project
3. Fill in the dialog appropriately. (For our purposes Empty Project
   project type and Linux GCC toolchains are OK)
4. Right click the Project in the Project folder.
5. Select New/Folder
6. Press Advanced
7. Click "link to folder in the file system"
8. Browse and select the branch

For debugging:

1. Select Run/Debug Configurations
2. Create one debug configuration for hipd, one for hipconf
3. Use "Search Project" or "Browse" for finding the executable.
4. Use the arguments tab to feed the arguments to the executables
5. Notice that you can switch between Debug and Editor perspectives.

If you face memory problems, append the following to the eclipse.ini:

-Xms512m
-Xmx1024m
-XX:MaxPermSize=256m
-XX:MaxPermSize=512M

Modify the numbers depending on your hardware to suit your needs.



UNIT TESTS
==========

You can (and are recommended to) use unit testing to improve code quality.

The command

#> make check

runs the existing unit tests.
HIPL uses the check framework (http://check.sourceforge.net/) for unit tests.
It is available in source and binary form, e.g. the Debian package 'check'.


What To Test?
-------------

Unit tests check whether implementations conform to their specification (i.e.,
their documentation). Some rules of thumb for writing tests are:

- test the documented aspects of a function: does it behave as expected? does
  it catch invalid input as documented?

- test undocumented aspects of a function: how does it handle invalid input
  (e.g., NULL pointers, empty strings, negative integers) that the compiler
  cannot catch?

Test coverage: At the very least, tests should ensure that a function can
handle valid and invalid input as documented. Ideally, they also test corner
cases and unusual input and state. Obviously, unit tests are limited
in testing whether a function fully behaves as documented because that can be
very complex, slow, or impossible on a local system.


Unit Tests Organization
-----------------------

The unit tests are organized as follows:

- all test code resides in the test directory. The directories below test
  mirror those in the main hipl directory to organize the tests in the same
  layout.

- test programs: There is one test program per hipl component. At the time of
  this writing, the only test program is check_lib_core for all tests that
  relate to the files from lib/core. By convention, each test program is
  called check_<component name> where <component name> is the name of the
  directory that contains the component. Test programs are defined in
  Makefile.am.

- test suites: Each test program consists of several test suites, one for each
  implementation file to test. By convention, the tests of the test suite for
  lib/core/hit.c are contained in test/lib/core/hit.c, which exports them as a
  suite to the check_lib_core test program.

- tests: Each test suite consists of one or more tests that test a specific
  aspect of a function from the implementation. For example, the test function
  test_hip_convert_hit_to_str_valid() in test/lib/core/hit.c tests whether the
  function hip_convert_hit_to_str() from lib/core/hit.c works as expected with
  valid input parameters. By convention, the test function is called
  test_<function under test>_<test aspect>().


Adding Unit Tests
-----------------

To add a unit test for the function foo() in the file hipd/bar.c, follow these
steps:

* If it does not exist, create a test program for the hipd component:
  - copy an existing test program implementation (test/check_*.c) to
    test/check_hipd.c
  - remove the existing "extern Suite" and "srunner_add_suite()" statements
  - in Makefile.am:
    * add the check_hipd test program to TESTS
    * add the check_hipd test program to check_PROGRAMS
    * add the file test/check_hipd.c to check_hipd_SOURCES
    * add the check library from the check framework and all libraries your
      test program depends on (usually the same as the original component
      hipd) to check_hipd_LDADD
  - create the directory test/hipd for your test suites
  - re-run the automake tool chain
* If it does not exist, create the test suite for the file hipd/bar.c:
  - copy an existing test suite (test/hipd/*.c) to test/hipd/bar.c.
  - in test/hipd/bar.c, make sure you include the test target's header file
    (#include "hipd/bar.h" in this example)
  - in test/hipd/bar.c, remove all tests and tcase_add_test() statements
  - in test/hipd/bar.c, adapt the name of the test suite in the invocation of
    suite_create() to "hipd/bar"
  - add test/hipd/bar.c to check_hipd_SOURCES in Makefile.am
  - re-run the automake tool chain
* Create the test case:
  - implement the test function called test_foo_<test aspect>() in
    test/hipd/bar.c (see other test suites and the check documentation for
    details)
  - register the test function to the test suite by adding a corresponding
    tcase_add_test() function call to hipd_bar() in test/hipd/bar.c.
    If you'd like to test for an HIP_ASSERT() to occur, use
    tcase_add_exit_test().
  - run "make check"


Testing Static Functions
------------------------

Usually, unit tests are not intended to apply to static functions and doing so
is difficult because these functions are not accessible by test programs
from outside of the files that define them. However, static functions
are commonplace in HIPL and often form relevant test targets. Developers are
thus encouraged to apply unit tests to static functions as well as to
non-static functions with external visibility.

There are two approaches to making static functions visible within the test
programs (adopting the names from the organization example above):

a) Instead of including hipd/bar.h, include the implementation file hipd/bar.c
   directly. While not an elegant solution, it is the simplest approach that
   should work in most cases.

b) For the test target static foo() create the wrapper foo_test_wrapper() that
   is not static. Declare all such wrappers in hipd/bar_test_wrappers.h and
   include that file instead of hipd/bar.h. While more effort, this is cleaner
   than solution a) and should work where a) proves problematic.



DEBUGGING
=========

You can debug HIPL code using gdb. The recommended way to configure a
debug build is as follows:

./configure <options> CFLAGS='-g -O0'

Alternatively, HIPL provides a set of wrappers for printing or logging
debugging statements in a unified way:

- HIP_DIE(arguments as for printk)
- HIP_ERROR(arguments as for printk)
- HIP_INFO(arguments as for printk)
- HIP_DEBUG(arguments as for printk)

The wrappers exist for many reasons. First, it is very convenient to
have the same syntax for the debug statements independently of whether
you are debugging in kernel- or userspace.

Second, an "ad hoc" debug statement mechanism would make it more
difficult to adopt HIPL into a production environment because it would
be awkward to comment-out all the superfluous debug messages. The
superfluous debug messages can be suppressed by a single switch to
configure (CONFIG_HIP_DEBUG) if a unified interface for debugging is
used.

The third reason for the existence of wrappers is that a uniform
importance level of debug messages can be enforced. For example, error
messages are more important than info messages and info messages are
more important than debug messages. One benefit of the importance of
levels is that the debug messages can be categorized into two groups:
the ones that are always included in a build and the ones that are
included only in a development build. HIP_DEBUG belongs to the latter
group and the other functions belong to the second group.

The fourth reason for justifying the wrappers is that some programs
cannot be run interactively on the screen in a production environment.
For example, the HIP daemon is preferred to be run as a background
process in these cases. The debug statements cannot be printed on the
screen then; instead, the statements have to passed via syslog. On the
other hand, the developer wants to run the daemon interactively. The
wrappers make it possible to please both groups easily.



COMMENTING AND DOCUMENTING THE CODE
===================================

Doxygen is used for documenting HIPL. The manual for doxygen documentation
is at:
http://www.stack.nl/~dimitri/doxygen/manual.html

To create doxygen documentation in HTML format, execute "make doxygen".
Doxygen will create documentation under doc/doxy/html.
You can view the generated documentation with
"firefox doc/doxy/html/index.html"

The aforementioned doxygen manual has detailed instructions on how to document
the code. We present the basics next.

First of all, doxygen supports different commenting styles. We use the JavaDoc
style in this project. In this style, every Doxygen comment starts and ends with
constant character sequence. To start a commenting block use "/**", and to end a
commenting block use "*/". Example 1:

  /** The number of items in the list. */
  int count;

In example 1 we have a variable named count to which we wish to add a Doxygen
comment "The number of items in the list." As a general rule, a Doxygen comment
is bound to the next item. So if in Example 1 we had "int count2" just after
count, the doxygen comment would have been bound only to "int count".

If you wish to add a Doxygen comment on the same line as the variable, put an
additional "<" marker in the comment block. Example 2:

  int count; /**< The number of items in the list. */

This has the same effect as Example 1. Remember that the comment with the "<"
marker has to start from the same line as the variable. Using the special marker
"<" one can comment also structure members. Example 3:

  /** A HIP FROM parameter. */
  struct hip_from {
       hip_tlv      type;         /**< type code for the parameter */
       hip_tlv_len  length;       /**< length of the parameter contents in bytes */
       uint8_t      address[16];  /**< IPv6 address */
  } __attribute__ ((packed));

Here the whole structure gets the doxygen comment "A HIP FROM parameter", and
the members get commented as illustrated. The structure members can also be
commented using the plain /** ... */ comment block by placing the comment block
on the line before the member, but the "<" marker saves some space.

Next up: commenting function. Example 4.

  /**
   * Set a type for a host association.
   * Set the type for a host association and validate the type number.
   * If the type number is illegal, the @c entry is left untouched.
   *
   * @param entry       a pointer to a host association entry
   * @param type_number a type number to be set for @c entry
   * @return            zero on success, non-zero else
   * @note              The entry must not be NULL.
   * @see               hip_clear_type()
   */
  int hip_set_type(struct hip_hadb_state *entry, int type_number);

Notice how that whole comment is placed before the function block. The function
comment block contains three elements, the brief description, the description
and the special commands starting with "@". The brief description is the first
comment line which ends at the first period followed by a space or newline.
Thus, in example 4 the brief description is "Set a type for a host association."
The description consists of the brief description and the rest of the lines
following the brief description before the special commands.

The special commands comment the function parameters and the return value.
Furthermore an extra note is added to this comment with "@note" and a reference
to a related function with "@see". Notice how we refer to the function
parameters in the description text with the special command "@a" Including this
special command is by no way obligatory. It only makes the next word be
rendered using Courier instead of the default font. If that causes a
doxygen warning, try "@c" which results in courier too, but doesn't confer
semantics like "@a". However, be careful not to add your own special commands
by accidentally typing something like @entry.

Function comment blocks must be placed in the C-source file. Generally, if
possible, place the doxygen comment in the C-source file instead of the
C-header file. However, if no implementation exists in the C-source file, you
must document the code in the C-header file (e.g., inline function in C-header
file). This applies to all doxygen comments, not just function comments.

To ensure correct cross-referencing, global variables should be prefixed
by :: and functions appended by () in comment blocks, like this:

/**
 * Store information about one ESP connection endpoint (i.e., one SPI).
 *
 * @todo Write allocator/deallocator for automatic syncing with ::esp_list.
 */
struct esp_tuple { /* ... */ };

/**
 * A connection (i.e., two tuples).
 * alloc/dealloc using insert_new_connection() or
 * remove_connection(), respectively.
 */
struct connection { /*...*/  };

Doxygen includes a special tag for TODO items. The TODO tag is "@todo". The TODO
tag can be placed anywhere in the code. When placed inside of a function, the
TODO item becomes a TODO item for the respective function. When placed outside
of a function, the TODO item becomes a TODO item for the whole file. To create
a TODO item for a variable, insert an @todo inside the variable's doxygen
comment block.

Example 5 is an example of a TODO item placed inside a function, in the middle
of the code. Hence, this becomes a TODO item for the whole function. Doxygen
maintains a list that contains all the TODO items of the project. Example 5.

  HIP_DEBUG("outgoing UPDATE ID=%u\n", update_id_out);
  /** @todo Handle this case. */
  HIP_IFEL(!update_id_out, -EINVAL, "Outgoing UPDATE ID overflowed.\n");

Entire files can be commented with the "@file" special tag as illustrated in
Example 6. From example 6 we notice that Doxygen comments can also include
simple HTML.

/**
 * @file
 * This file defines various functions for handling HIP messages.
 */

Sometimes you can find yourself in a situation where you have a large number of
repetitive comments. Say that you have similar type definitions which are nicely
aligned in a header file. You could, of course, insert a normal Doxygen comment
before (or after, using "<") every definition, but you just don't want to break
the alignment for comments sake. lib/core/protodefs.h is a good example of
that kind of file.

To help in a situation like this, the HIPL project has a special file just for
doxygen comments, i.e. it has no code whatsoever. The file is doc/doxygen.h.
We can target comments from this file to another file using the "@file" special
command. For example, to insert a Doxygen comment for the definition of
HIP_NTF_INVALID_SYNTAX located in lib/core/protodefs.h you can add the
following comment block in doc/doxygen.h, example 7.

/**
 * @file
 * @def  HIP_NTF_INVALID_SYNTAX
 *       Indicates that the HIP message received was invalid because...
 */

doc/doxygen.h is also a good place for declaring groups. Groups are declared
with the "@defgroup" special tag. Example 8.

/** @defgroup notification NOTIFICATION parameter values */

To add members to a group, use the "@addtogroup" special tag together with the
group name. Moreover, you need to use the special tag "@{" to start inclusion,
and the special tag "@}" to stop the inclusion. example 9 illustrates how we can
add members to the group declared in example 8.

/** @addtogroup notification
 * @{
 */
#define HIP_NTF_UNSUPPORTED_CRITICAL_PARAMETER_TYPE 1
#define HIP_NTF_INVALID_SYNTAX                      7
/* @} */

The general JavaDoc style guide applies to the HIPL project. This style guide
is available at:
http://java.sun.com/j2se/javadoc/writingdoccomments/index.html

Remember that normal non-doxygen comments are always valid. Thus if you need
to comment something more specific to the code, use the regular

/* comment here. */

and

// end of line comment here.

commenting style.

Please don't forget to update the Copyright dates when you modify
files with Copyright headers. Scatterbrains may want to try out the
experimental pre-commit hook that automatically checks for that:

https://code.launchpad.net/~stefan.goetz/hipl/commitguard


SUBMITTING PATCHES
==================

HIPL is still work in progress. The code is being constantly developed
and it may be difficult to merge your contribution to the HIPL code.
If you still want to submit patches to the HIPL project, build your
patches against the main branch.  Please try the test matrix below at
least partially before you contribute.



CREATING A TARBALL OF THE SOURCE CODE
=====================================

There is a "make dist" target which builds a tarball of the HIPL source
code. It includes all the files declared as SOURCES, plus whatever gets
declared in EXTRA_DIST.



PREBUILT BINARY PACKAGES
========================

Red Hat
-------

Note well: Currently the status of the packaging scripts is in release
phase.

There are scripts in the 'packaging' directory that can be used to create
binary packages. The aim for these packages is for easier testing of HIPL
software. With the scripts, RPM (e.g. for Fedora Core) and DEB (for Debian)
packages can be created.

To create the RPM package, type:

autoreconf --install && ./configure && make rpm

This will create a source tar.gz (in the same directory) which will be used
when building the RPM file. After the script has run successfully, follow the
instructions given by the script. That is, login as root and copy the source
package (e.g. hipl--1.0.6.tar.gz) to the directory /usr/src/redhat/SOURCES.
Then issue the command "rpmbuild -ba <hiplroot>/packaging/hipl.spec". When
everything is finished successfully, there will be a binary RPM package
"/usr/src/rpm/RPMS/i386/hipl-1.0.6.i386.rpm". The package can then be
installed with rpm -i.

For more info about RPM packaging, please see:

http://www.redhat.com/docs/books/max-rpm/max-rpm-html/index.html
http://fedoranews.org/tchung/htmldoc/htmldoc.spec
http://fedoraproject.org/wiki/Packaging/Guidelines


Debian
------

Debian packages are created in a similar fashion:

autoreconf --install && ./configure && make deb

The binary packages are placed one level above the build directory.



REPOSITORY MANAGEMENT FOR FEDORA AND UBUNTU
===========================================

This chapter describes how to manage (and add new servers) to
semi-automatic HIPL binary package system and how to use the
repositories at clients.


Prerequisites for Server Configuration
--------------------------------------

For server configuration, you must first do the following things:
* Make sure that you set up authorized keys for ssh as follows:
  * @build.host: adduser hipl
  * @build.host: su hipl and then ssh-keygen
  * hipl@hipl.hiit.fi can login to hipl@build.host
  * hipl@build.host can login to hipl@packages.infrahip.net
* Add hipl to /etc/sudoers at build host: hipl ALL=(ALL) NOPASSWD: ALL
* Comment out "Defaults    requiretty" from /etc/sudoers


Updating Fedora Server Repository
---------------------------------

You must do the following things first at the server:
* yum install <required packages>
* yum install createrepo
* ln -s /usr/src/redhat /home/hipl

Install repository tool at the host where you are building packages:
* yum -y install createrepo

Create binaries and synchronize to repository:
* make bin syncrepo


Fedora Client-side Configuration
--------------------------------

To install the packages from the repo, modify /etc/yum.conf:

[hipl]
name=HIPL
baseurl=http://packages.infrahip.net/fedora/base/$releasever/$basearch
gpgcheck=0
enabled=1


Updating Ubuntu Server Repository
---------------------------------

You must do the following things first at the server:
* apt-get install <required packages>

Install the following tool to the host where building packages:
* apt-get install dpkg-scanpackages

Build the binaries and synchronize to repository:
* make bin syncrepo

Packages are copied to hipl.hiit.fi:
  * /var/www/html/ubuntu/dists/<release>/main/binary-<arch>

The release is gutsy, intrepid etc and the arch is i386, amd64 or armel.

TODO: Currently the scripting just "forgets" older versions of the software.
It's not clear if some rsyncing should be done to preserve older versions.
Also, source packages are not yet supported.


Ubuntu Client-side Configuration
--------------------------------

To configure apt-get for Debian modify sources.list

$ nano /etc/apt/sources.list

deb http://packages.infrahip.net/ubuntu/ intrepid main

- update and install hipl packages

$ apt-get update
$ apt-get install hipl-daemon hipl-firewall hipl-dnsproxy hipl-doc



TEST MATRIX
===========

* platform: 32-bit bit, 64-bit, mixed (32-bit Initiator, 64-bit Resp,
  or reversed)
  * 64-bit AMD vs. Intel
* OS: Fedora, Ubuntu
* memory leaks; run hipd through valgrind in all tests


1. Compilation
--------------

* Compilation on Ubuntu
* Compilation on Fedora


2. Applications
---------------

Applications:

* ping6 HIT
* nc6 HIT
* nc LSI
* use dnsproxy to obtain HITs from DNS
* hipconf run opp nc/nc6 (both client & server side)


3. Base Exchange
----------------

* hipconf nat on
* hipconf nat off
* hipconf locator on
* hipconf locator off
* retransmissions


4. Mobility Management
----------------------

Soft IPv4-Only Handover, no locators in base exchange

* hipconf locator off
* hipconf add map PEER_HIT PEER_IPV4
* ping6 PEER_HIT
* ip addr add NEW_LOCAL_IPV4
* ip addr del OLD_LOCAL_IPV4
* ping6 PEER_HIT

Soft IPv6-Only Handover, no locators in base exchange

* hipconf locator off
* hipconf add map PEER_HIT PEER_IPV6
* ping6 PEER_HIT
* ip addr add NEW_LOCAL_IPV6
* ip addr del OLD_LOCAL_IPV6
* ping6 PEER_HIT

Hard IPv4-Only Handover, no locators in base exchange

* hipconf locator off
* hipconf add map PEER_HIT PEER_IPV4
* ping6 PEER_HIT
* ip addr del OLD_LOCAL_IPV4
* ip addr add NEW_LOCAL_IPV4
* ping6 PEER_HIT

Hard IPv6-Only Handover, no locators in base exchange

* hipconf locator off
* hipconf add map PEER_HIT PEER_IPV6
* ping6 PEER_HIT
* ip addr del OLD_LOCAL_IPV6
* ip addr add NEW_LOCAL_IPV6
* ping6 PEER_HIT

Soft Interfamily Handover From IPv4 to IPv6, no locators in base exchange

* hipconf locator off
* hipconf add map PEER_HIT PEER_IPV4
* ping6 PEER_HIT
* ip addr add NEW_LOCAL_IPV6
* ip addr del OLD_LOCAL_IPV4
* ping6 PEER_HIT

Soft Interfamily Handover From IPv6 to IPv4, no locators in base exchange

* hipconf locator off
* hipconf add map PEER_HIT PEER_IPV6
* ping6 PEER_HIT
* ip addr add NEW_LOCAL_IPV4
* ip addr del OLD_LOCAL_IPV6
* ping6 PEER_HIT

Hard Interfamily Handover From IPv4 to IPv6, no locators in base exchange

* hipconf locator off
* hipconf add map PEER_HIT PEER_IPV4
* ping6 PEER_HIT
* ip addr del OLD_LOCAL_IPV4
* ip addr add NEW_LOCAL_IPV6
* ping6 PEER_HIT

Hard Interfamily Handover From IPv6 to IPv4, no locators in base exchange

* hipconf locator off
* hipconf add map PEER_HIT PEER_IPV6
* ping6 PEER_HIT
* ip addr del OLD_LOCAL_IPV6
* ip addr add NEW_LOCAL_IPV4
* ping6 PEER_HIT

Soft IPv4-Only Handover, locators present in base exchange

* hipconf locator on
* hipconf add map PEER_HIT PEER_IPV4
* ping6 PEER_HIT
* ip addr add NEW_LOCAL_IPV4
* ip addr del OLD_LOCAL_IPV4
* ping6 PEER_HIT

Soft IPv6-Only Handover, locators present in base exchange

* hipconf locator on
* hipconf add map PEER_HIT PEER_IPV6
* ping6 PEER_HIT
* ip addr add NEW_LOCAL_IPV6
* ip addr del OLD_LOCAL_IPV6
* ping6 PEER_HIT

Hard IPv4-Only Handover, locators present in base exchange

* hipconf locator on
* hipconf add map PEER_HIT PEER_IPV4
* ping6 PEER_HIT
* ip addr del OLD_LOCAL_IPV4
* ip addr add NEW_LOCAL_IPV4
* ping6 PEER_HIT

Hard IPv6-Only Handover, locators present in base exchange

* hipconf locator on
* hipconf add map PEER_HIT PEER_IPV6
* ping6 PEER_HIT
* ip addr del OLD_LOCAL_IPV6
* ip addr add NEW_LOCAL_IPV6
* ping6 PEER_HIT

Soft Interfamily Handover From IPv4 to IPv6, locators present in base exchange

* hipconf locator on
* hipconf add map PEER_HIT PEER_IPV4
* ping6 PEER_HIT
* ip addr add NEW_LOCAL_IPV6
* ip addr del OLD_LOCAL_IPV4
* ping6 PEER_HIT

Soft Interfamily Handover From IPv6 to IPv4, locators present in base exchange

* hipconf locator on
* hipconf add map PEER_HIT PEER_IPV6
* ping6 PEER_HIT
* ip addr add NEW_LOCAL_IPV4
* ip addr del OLD_LOCAL_IPV6
* ping6 PEER_HIT

Hard Interfamily Handover From IPv4 to IPv6, locators present in base exchange

* hipconf locator on
* hipconf add map PEER_HIT PEER_IPV4
* ping6 PEER_HIT
* ip addr del OLD_LOCAL_IPV4
* ip addr add NEW_LOCAL_IPV6
* ping6 PEER_HIT

Hard Interfamily Handover From IPv6 to IPv4, locators present in base exchange

* hipconf locator on
* hipconf add map PEER_HIT PEER_IPV6
* ping6 PEER_HIT
* ip addr del OLD_LOCAL_IPV6
* ip addr add NEW_LOCAL_IPV4
* ping6 PEER_HIT

Retransmissions in hard IPv4-Only Handover, no locators in base exchange

* hipconf locator off
* hipconf add map PEER_HIT PEER_IPV4
* ping6 PEER_HIT
* ip addr del OLD_LOCAL_IPV4
* kill hipd from the other side
* ip addr add NEW_LOCAL_IPV4
* does it retransmit?

NAT handover in hard IPv4-Only Handover, no locators in base exchange

* hipconf locator off
* hipconf nat on
* hipconf add map PEER_HIT PEER_IPV4
* ping6 PEER_HIT
* ip addr del OLD_LOCAL_IPV4
* ip addr add NEW_LOCAL_IPV4
* ping6 PEER_HIT


5. Rendezvous
-------------

* Test rendezvous as instructed in the manual.


6. NAT Relay
----------------

* not supported officially yet


7. Firewall
-----------


8. Closing of connections
-------------------------

* tools/hipconf rst all



ADDING HIPCONF ACTIONS AND PARAMETERS
=====================================

If you want to add some actions and parameters to hipconf, do the following
things carefully. Otherwise your code could cause bugs not only for hipconf
but also for hipd.

Assume that you want to add an action named as 'NEWACT'.


1.1. ACTION_NEWACT in lib/core/conf.h
-------------------------------------

Define a constant ACTION_NEWACT which has a value between 0 and ACTION_MAX.
Probably you also need to increase the value of ACTION_MAX.


1.2. hip_conf_get_action() in lib/core/conf.c
---------------------------------------------

Add a proper sentence in the strcmp() series, like that:

    ...
    else if (!strcmp("newaction", text))
        ret = ACTION_NEWACT;
    ...


1.3. hip_conf_check_action_argc() in lib/core/conf.c
----------------------------------------------------

Add a case block for your ACTION_NEWACT constant in the switch(action) block.


1.4. hip_conf_get_type_arg() in lib/core/conf.c
-----------------------------------------------

Add a case block for your ACTION_NEWACT constant in the switch(action) block.


2.1. HIP_MSG_NEWMODE in lib/core/icomm.h
---------------------------------------

Define a constant HIP_MSG_NEWMODE which has a value between 0 and
HIP_MSG_ROOT_MAX. Take also care of the value of HIP_MSG_ROOT_MAX.


2.2. hip_handle_user_msg() in hipd/user.c
-----------------------------------------

Add a case block for your HIP_MSG_NEWMODE constant in the switch(msg_type) block.


2.3. hip_message_type_name() in lib/core/builder.c
--------------------------------------------------

Add a case block for your HIP_MSG_NEWMODE constant in the switch(msg_type) block.
In this case, you just need to return the same string as the constant.


3.1. action_handler[] in lib/core/conf.c
----------------------------------------

Add a handler function for your new action in the action_handler[] array.
NOTE: the location and the order of these handlers are important, because
each entry of the handler array is to be accessed via type index.


3.2. TYPE_NEWTYPE in lib/core/conf.h
------------------------------------

Define a constant TYPE_NEWTYPE which has a value between 0 and TYPE_MAX.
Probably you also need to increase the value of TYPE_MAX.

NOTE: TYPE_MAX must be exactly the largest value of all type variables:
no more, no less. If that is set as a wrong value, the hip daemon can become
incapable of communicating with any hipconf requests.

NOTE: the value of TYPE_NEWTYPE must be a correct index for looking up
each handler function in action_handler[], which you just added above
at the step 3.1.


3.3. hip_conf_handle_NEWACT() in lib/core/conf.c
------------------------------------------------

Define a handler function added above at the step 3.1, somewhere in conf.c.


3.4. hip_conf_handle_NEWACT() in lib/core/conf.h
------------------------------------------------

Declare a prototype for your new handler function hip_conf_handle_NEWACT
defined above at the step 3.1.


4. hipconf_usage in lib/core/conf.c
-----------------------------------

Add a simple usage for your new action in the usage string.
