File: Opt.cpp

package info (click to toggle)
dibbler 1.0.1-2
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 13,352 kB
  • sloc: cpp: 60,323; ansic: 12,235; sh: 11,951; yacc: 3,418; lex: 969; makefile: 940; perl: 319; xml: 116; python: 74
file content (180 lines) | stat: -rw-r--r-- 4,141 bytes parent folder | download | duplicates (3)
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/*
 * Dibbler - a portable DHCPv6
 *
 * authors: Tomasz Mrugalski <thomson@klub.com.pl>
 *          Marek Senderski <msend@o2.pl>
 *
 * released under GNU GPL v2 licence
 *
 */

#include "Portable.h"
#include "Opt.h"
#include "OptGeneric.h"
#include "OptRtPrefix.h"
#include "Logger.h"

int TOpt::getOptType() {
    return OptType;
}

TOpt::~TOpt() {

}

TOpt::TOpt(int optType, TMsg *parent)
    :Valid(true) {
    OptType=optType;
    Parent=parent;
}

int TOpt::getSubOptSize() {
    int size = 0;
    SubOptions.first();
    TOptPtr ptr;
    while (ptr = SubOptions.get())
        size += ptr->getSize();
    return size;
}

char* TOpt::storeHeader(char* buf) {
    buf = writeUint16(buf, OptType);
    buf = writeUint16(buf,getSize() - 4);
    return buf;
}

char* TOpt::storeSubOpt(char* buf){
    TOptPtr ptr;
    SubOptions.first();
    while ( ptr = SubOptions.get() ) {
        ptr->storeSelf(buf);
        buf += ptr->getSize();
    }
    return buf;
}

void TOpt::firstOption() {
    SubOptions.first();
}

TOptPtr TOpt::getOption() {
    return SubOptions.get();
}

TOptPtr TOpt::getOption(int optType) {
    firstOption();
    TOptPtr opt;
    while(opt=getOption()) {
        if (opt->getOptType()==optType)
            return opt;
    }
    return TOptPtr();
}

void TOpt::addOption(TOptPtr opt) {
    SubOptions.append(opt);
}

int TOpt::countOption() {
    return SubOptions.count();
}

void TOpt::setParent(TMsg* Parent) {
    this->Parent=Parent;
}

void TOpt::delAllOptions() {
    SubOptions.clear();
}

bool TOpt::isValid() const {
    return Valid;
}

/// @brief Deletes all specified options of that type
///
/// @param type
///
/// @return
bool TOpt::delOption(uint16_t type) {
    firstOption();
    TOptPtr opt;
    bool del = false;
    while(opt=getOption()) {
        if (opt->getOptType()==type) {
            SubOptions.del();
            SubOptions.first();
            del = true;
        }
    }
    return del;
}

std::string TOpt::getPlain() {
    return "[generic]";
}

TOptPtr TOpt::getOption(const TOptList& list, uint16_t opt_type) {
    for (TOptList::const_iterator opt = list.begin(); opt != list.end();
         ++opt) {
        if ((*opt)->getOptType() == opt_type) {
            return *opt;
        }
    }
    return TOptPtr(); // NULL
}

/// @brief Parses options or suboptions, creates appropriate objects and store them
///        in options container
///
/// @param options options container (new options will be added here)
/// @param buf buffer to be parsed
/// @param len length of the buffer
/// @param parent pointer to parent message
/// @param placeId specifies location of the message (option number for option parsing
///        or 0 for message parsing)
/// @param place text representation of the parsed scope
///
/// @return true if parsing was successful, false if anomalies are detected
bool TOpt::parseOptions(TOptContainer& options, const char* buf, size_t len,
                        TMsg* parent, uint16_t placeId /*= 0*/, // 5 (option 5) or (message 5)
                        std::string place) { /*= "option"*/ // "option" or "message"

    // parse suboptions
    while (len>0) {
        if (len<4) {
            Log(Warning) << "Truncated suboption in " << place << " " << placeId << LogEnd;
            return false;
        }

        uint16_t optType = readUint16(buf);
        buf += sizeof(uint16_t);
        len -= sizeof(uint16_t);
        uint16_t optLen = readUint16(buf);
        buf += sizeof(uint16_t);
        len -= sizeof(uint16_t);

        if (optLen>len) {
            Log(Warning) << "Truncated suboption " << optType << " in " << place << " "
                         << placeId << LogEnd;
            return false;
        }

        switch (optType) {
        case OPTION_RTPREFIX: {
            TOptPtr opt = new TOptRtPrefix(buf, len, parent);
            options.append(opt);
            break;
        }
        default: {
            TOptPtr opt = new TOptGeneric(optType, buf, len, parent);
            options.append(opt);
            break;
        }
        }
        buf += optLen;
        len -= optLen;
    }

    return true;
}