|
@@ -32,9 +32,9 @@ Option::Option(Universe u, unsigned short type)
|
|
|
|
|
|
}
|
|
|
|
|
|
-Option::Option(Universe u, unsigned short type, boost::shared_array<char> buf,
|
|
|
+Option::Option(Universe u, unsigned short type, boost::shared_array<char> buf,
|
|
|
unsigned int offset, unsigned int len)
|
|
|
- :universe_(u), type_(type), data_(buf),
|
|
|
+ :universe_(u), type_(type), data_(buf),
|
|
|
offset_(offset),
|
|
|
len_(len) {
|
|
|
|
|
@@ -42,51 +42,60 @@ Option::Option(Universe u, unsigned short type, boost::shared_array<char> buf,
|
|
|
// TODO: universe must be in V4 and V6
|
|
|
}
|
|
|
|
|
|
-char* Option::pack(char* buf, unsigned int len) {
|
|
|
+unsigned int
|
|
|
+Option::pack(boost::shared_array<char> buf,
|
|
|
+ unsigned int buf_len,
|
|
|
+ unsigned int offset) {
|
|
|
switch (universe_) {
|
|
|
case V4:
|
|
|
- return pack4(buf, len);
|
|
|
+ return pack4(buf, buf_len, offset);
|
|
|
case V6:
|
|
|
- return pack6(buf, len);
|
|
|
+ return pack6(buf, buf_len, offset);
|
|
|
default:
|
|
|
isc_throw(BadValue, "Unknown universe defined for Option " << type_);
|
|
|
}
|
|
|
-
|
|
|
- return NULL; // should not happen
|
|
|
}
|
|
|
|
|
|
-char*
|
|
|
-Option::pack4(char* buf, unsigned short len) {
|
|
|
- if (this->len()>len) {
|
|
|
- isc_throw(OutOfRange, "Failed to pack v4 option=" <<
|
|
|
+
|
|
|
+unsigned int
|
|
|
+Option::pack4(boost::shared_array<char> buf,
|
|
|
+ unsigned int buf_len,
|
|
|
+ unsigned int offset) {
|
|
|
+ if ( offset+len() > buf_len ) {
|
|
|
+ isc_throw(OutOfRange, "Failed to pack v4 option=" <<
|
|
|
type_ << ",len=" << len_ << ": too small buffer.");
|
|
|
}
|
|
|
- buf[0] = type_;
|
|
|
- buf[1] = len_;
|
|
|
- buf += 2;
|
|
|
- memcpy(buf, &data_[0], len_);
|
|
|
+ char *ptr = &buf[offset];
|
|
|
+ ptr[0] = type_;
|
|
|
+ ptr[1] = len_;
|
|
|
+ ptr += 2;
|
|
|
+ memcpy(ptr, &data_[0], len_);
|
|
|
|
|
|
- return buf + len_;
|
|
|
+ return offset + len();
|
|
|
}
|
|
|
|
|
|
-char* Option::pack6(char* buf, unsigned short len) {
|
|
|
- if (this->len()>len) {
|
|
|
- isc_throw(OutOfRange, "Failed to pack v6 option=" <<
|
|
|
+unsigned int
|
|
|
+Option::pack6(boost::shared_array<char> buf,
|
|
|
+ unsigned int buf_len,
|
|
|
+ unsigned int offset) {
|
|
|
+ if ( offset+len() > buf_len ) {
|
|
|
+ isc_throw(OutOfRange, "Failed to pack v6 option=" <<
|
|
|
type_ << ",len=" << len_ << ": too small buffer.");
|
|
|
}
|
|
|
- *(uint16_t*)buf = htons(type_);
|
|
|
- buf += 2;
|
|
|
- *(uint16_t*)buf = htons(len_);
|
|
|
- buf += 2;
|
|
|
- memcpy(buf, &data_[0], len_);
|
|
|
-
|
|
|
- return buf + len_;
|
|
|
+ char * ptr = &buf[offset];
|
|
|
+ *(uint16_t*)ptr = htons(type_);
|
|
|
+ ptr += 2;
|
|
|
+ *(uint16_t*)ptr = htons(len_);
|
|
|
+ ptr += 2;
|
|
|
+ memcpy(ptr, &data_[0], len_);
|
|
|
+
|
|
|
+ return offset + len();
|
|
|
}
|
|
|
|
|
|
-unsigned int
|
|
|
-Option::unpack(boost::shared_array<char> buf,
|
|
|
+unsigned int
|
|
|
+Option::unpack(boost::shared_array<char> buf,
|
|
|
unsigned int buf_len,
|
|
|
- unsigned int offset,
|
|
|
+ unsigned int offset,
|
|
|
unsigned int parse_len) {
|
|
|
switch (universe_) {
|
|
|
case V4:
|
|
@@ -100,41 +109,41 @@ Option::unpack(boost::shared_array<char> buf,
|
|
|
return 0; // should not happen
|
|
|
}
|
|
|
|
|
|
-unsigned int
|
|
|
-Option::unpack4(boost::shared_array<char>,
|
|
|
+unsigned int
|
|
|
+Option::unpack4(boost::shared_array<char>,
|
|
|
+ unsigned int ,
|
|
|
unsigned int ,
|
|
|
- unsigned int ,
|
|
|
unsigned int ) {
|
|
|
isc_throw(Unexpected, "IPv4 support not implemented yet.");
|
|
|
return 0;
|
|
|
}
|
|
|
-/**
|
|
|
+/**
|
|
|
* Parses buffer and creates collection of Option objects.
|
|
|
- *
|
|
|
+ *
|
|
|
* @param buf pointer to buffer
|
|
|
* @param buf_len length of buf
|
|
|
* @param offset offset, where start parsing option
|
|
|
* @param parse_len how many bytes should be parsed
|
|
|
- *
|
|
|
+ *
|
|
|
* @return offset after last parsed option
|
|
|
*/
|
|
|
-unsigned int
|
|
|
-Option::unpack6(boost::shared_array<char> buf,
|
|
|
+unsigned int
|
|
|
+Option::unpack6(boost::shared_array<char> buf,
|
|
|
unsigned int buf_len,
|
|
|
- unsigned int offset,
|
|
|
+ unsigned int offset,
|
|
|
unsigned int parse_len) {
|
|
|
|
|
|
if (buf_len < offset+parse_len) {
|
|
|
- isc_throw(OutOfRange, "Failed to unpack DHCPv6 option len="
|
|
|
- << parse_len << " offset=" << offset << " from buffer (length="
|
|
|
+ isc_throw(OutOfRange, "Failed to unpack DHCPv6 option len="
|
|
|
+ << parse_len << " offset=" << offset << " from buffer (length="
|
|
|
<< buf_len << "): too small buffer.");
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
data_ = buf;
|
|
|
offset_ = offset;
|
|
|
len_ = buf_len;
|
|
|
|
|
|
- return LibDHCP::unpackOptions6(buf, buf_len, offset,
|
|
|
+ return LibDHCP::unpackOptions6(buf, buf_len, offset, parse_len,
|
|
|
optionLst_);
|
|
|
}
|
|
|
|
|
@@ -155,7 +164,7 @@ bool Option::valid() {
|
|
|
// total length of buffer is not stored. shared_array is not very useful.
|
|
|
// we should either add buf_len field or better replace shared_array
|
|
|
// with shared_ptr to array
|
|
|
- if (universe_ != V4 &&
|
|
|
+ if (universe_ != V4 &&
|
|
|
universe_ != V6) {
|
|
|
return (false);
|
|
|
}
|
|
@@ -163,9 +172,9 @@ bool Option::valid() {
|
|
|
return (true);
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
+/**
|
|
|
* Converts generic option to string.
|
|
|
- *
|
|
|
+ *
|
|
|
* @return string that represents option.
|
|
|
*/
|
|
|
std::string Option::toText() {
|
|
@@ -176,12 +185,12 @@ std::string Option::toText() {
|
|
|
if (i) {
|
|
|
tmp << ":";
|
|
|
}
|
|
|
- tmp << setfill('0') << setw(2) << hex << (unsigned short)data_[offset_+i];
|
|
|
+ tmp << setfill('0') << setw(2) << hex << (unsigned short)(unsigned char)data_[offset_+i];
|
|
|
}
|
|
|
return tmp.str();
|
|
|
}
|
|
|
|
|
|
-unsigned short
|
|
|
+unsigned short
|
|
|
Option::getType() {
|
|
|
return type_;
|
|
|
}
|
|
@@ -189,4 +198,3 @@ Option::getType() {
|
|
|
Option::~Option() {
|
|
|
|
|
|
}
|
|
|
-
|