File: OptOptionRequest.cpp

package info (click to toggle)
dibbler 0.7.3-1.3
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 11,148 kB
  • ctags: 8,720
  • sloc: cpp: 54,863; sh: 9,389; ansic: 8,659; yacc: 2,570; makefile: 1,061; lex: 842; perl: 49; xml: 6
file content (139 lines) | stat: -rw-r--r-- 3,157 bytes parent folder | download | duplicates (2)
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
 * Dibbler - a portable DHCPv6
 *
 * authors: Tomasz Mrugalski <thomson@klub.com.pl>
 *          Marek Senderski <msend@o2.pl>
 *
 * released under GNU GPL v2 licence
 *
 * $Id: OptOptionRequest.cpp,v 1.8 2007-08-26 10:26:19 thomson Exp $
 *
 */
#include <stdlib.h>
#include "Portable.h"
#include "OptOptionRequest.h"
#include "DHCPConst.h"
#include "Logger.h"

TOptOptionRequest::TOptOptionRequest(TMsg* parent)
	:TOpt(OPTION_ORO, parent)
{
    this->Options=NULL;
    this->OptCnt=0;
}

int  TOptOptionRequest::getReqOpt(int optNr) {
    if ( (!OptCnt) || (optNr>OptCnt) )
      return 0;
    return 
      this->Options[optNr];
}

 int TOptOptionRequest::getSize()
{
	if (!OptCnt) 
        return 0;
	int mySize = 4+(OptCnt<<1);
	return mySize+getSubOptSize();
}

char * TOptOptionRequest::storeSelf( char* buf)
{
    if (!OptCnt) 
        return buf;
    *(uint16_t*)buf = htons(OptType);
    buf+=2;
    *(uint16_t*)buf = htons( getSize()-4 );
    buf+=2;
    int i=0;
    while(i<OptCnt)
    {
        *(uint16_t*)buf = htons( Options[i] );
        buf+=2;
        i++;
    }
    return buf;
}

TOptOptionRequest::TOptOptionRequest( char * &buf,  int &bufSize, TMsg* parent)
	:TOpt(OPTION_ORO, parent)
{
    if (bufSize%2) {
        Log(Error) << "OPTION REQUEST option malformed: odd number of bytes (" << bufSize << ")." << LogEnd;
        Valid   = false;
        Options = NULL;
        OptCnt  = 0;
        return;
    }
    int totalOpts = bufSize/2;
    Options = new unsigned short[totalOpts]; // allocate memory for all options
    
    int i=0;
    for (i=0; i<totalOpts; i++) {
        Options[i] = ntohs(*(unsigned short*) (buf+i*2) );
    }
    OptCnt = totalOpts;
    Valid = true;
}

void TOptOptionRequest::addOption(unsigned short optNr)
{
    //Is option already included
    if (isOption(optNr))
        return; //if it is no need to include once more
    //store for a while old options
    unsigned short *oldOptions=Options;
    //assign memort for additional option
    Options = new unsigned short[++OptCnt];
    //If there were options before
    if (oldOptions)
    {
        //copy them to new memory
        memcpy(Options,oldOptions,(OptCnt-1)*sizeof(short));
        //now they can be deleted
        delete [] oldOptions;
    }
    //and add new option
    Options[OptCnt-1]=optNr;
}

void TOptOptionRequest::delOption(unsigned short optNr)
{
    //find option if any
    if (!OptCnt) return;
    int optIdx=0;
    while((optIdx<OptCnt)&&(Options[optIdx]!=optNr)) 
        optIdx++;
    //if there is no such a option
    if (optIdx>=OptCnt) return;
    memcpy(Options+optIdx,Options+optIdx+1,(OptCnt-optIdx-1)<<1);
    OptCnt--;
}

bool TOptOptionRequest::isOption(unsigned short optNr)
{
    for(int i=0;i<OptCnt;i++)
        if (Options[i]==optNr)
            return true;
    return false;
}

int  TOptOptionRequest::count() {
    return this->OptCnt;
}

void TOptOptionRequest::clearOptions() {
    if (this->OptCnt)
        delete [] this->Options;
    OptCnt=0;
}

bool TOptOptionRequest::isValid() {
    return this->Valid;
}

TOptOptionRequest::~TOptOptionRequest()
{
  if (Options)
    delete [] Options;
}