ReactOS  0.4.12-dev-36-g472787f
options.c File Reference
#include <rosdhcp.h>
Include dependency graph for options.c:

Go to the source code of this file.

Macros

#define DHCP_OPTION_DATA
 

Functions

void parse_options (struct packet *)
 
void parse_option_buffer (struct packet *, unsigned char *, int)
 
int store_options (unsigned char *, int, struct tree_cache **, unsigned char *, int, int, int, int)
 
int cons_options (struct packet *inpacket, struct dhcp_packet *outpacket, int mms, struct tree_cache **options, int overload, int terminate, int bootpp, u_int8_t *prl, int prl_len)
 
charpretty_print_option (unsigned int code, unsigned char *data, int len, int emit_commas, int emit_quotes)
 
void do_packet (struct interface_info *interface, struct dhcp_packet *packet, int len, unsigned int from_port, struct iaddr from, struct hardware *hfrom)
 

Variables

int bad_options = 0
 
int bad_options_max = 5
 

Macro Definition Documentation

◆ DHCP_OPTION_DATA

#define DHCP_OPTION_DATA

Definition at line 43 of file options.c.

Function Documentation

◆ cons_options()

int cons_options ( struct packet inpacket,
struct dhcp_packet outpacket,
int  mms,
struct tree_cache **  options,
int  overload,
int  terminate,
int  bootpp,
u_int8_t prl,
int  prl_len 
)

Definition at line 199 of file options.c.

Referenced by make_decline(), make_discover(), and make_request().

203 {
204  unsigned char priority_list[300], buffer[4096];
205  int priority_len, main_buffer_size, mainbufix, bufix;
206  int option_size, length;
207 
208  /*
209  * If the client has provided a maximum DHCP message size, use
210  * that; otherwise, if it's BOOTP, only 64 bytes; otherwise use
211  * up to the minimum IP MTU size (576 bytes).
212  *
213  * XXX if a BOOTP client specifies a max message size, we will
214  * honor it.
215  */
216  if (!mms &&
217  inpacket &&
218  inpacket->options[DHO_DHCP_MAX_MESSAGE_SIZE].data &&
219  (inpacket->options[DHO_DHCP_MAX_MESSAGE_SIZE].len >=
220  sizeof(u_int16_t)))
221  mms = getUShort(
222  inpacket->options[DHO_DHCP_MAX_MESSAGE_SIZE].data);
223 
224  if (mms)
225  main_buffer_size = mms - DHCP_FIXED_LEN;
226  else if (bootpp)
227  main_buffer_size = 64;
228  else
229  main_buffer_size = 576 - DHCP_FIXED_LEN;
230 
231  if (main_buffer_size > sizeof(buffer))
232  main_buffer_size = sizeof(buffer);
233 
234  /* Preload the option priority list with mandatory options. */
235  priority_len = 0;
236  priority_list[priority_len++] = DHO_DHCP_MESSAGE_TYPE;
237  priority_list[priority_len++] = DHO_DHCP_SERVER_IDENTIFIER;
238  priority_list[priority_len++] = DHO_DHCP_LEASE_TIME;
239  priority_list[priority_len++] = DHO_DHCP_MESSAGE;
240 
241  /*
242  * If the client has provided a list of options that it wishes
243  * returned, use it to prioritize. Otherwise, prioritize based
244  * on the default priority list.
245  */
246  if (inpacket &&
247  inpacket->options[DHO_DHCP_PARAMETER_REQUEST_LIST].data) {
248  int prlen =
250  if (prlen + priority_len > sizeof(priority_list))
251  prlen = sizeof(priority_list) - priority_len;
252 
253  memcpy(&priority_list[priority_len],
255  prlen);
256  priority_len += prlen;
257  prl = priority_list;
258  } else if (prl) {
259  if (prl_len + priority_len > sizeof(priority_list))
260  prl_len = sizeof(priority_list) - priority_len;
261 
262  memcpy(&priority_list[priority_len], prl, prl_len);
263  priority_len += prl_len;
264  prl = priority_list;
265  } else {
266  memcpy(&priority_list[priority_len],
270  }
271 
272  /* Copy the options into the big buffer... */
273  option_size = store_options(
274  buffer,
275  (main_buffer_size - 7 + ((overload & 1) ? DHCP_FILE_LEN : 0) +
276  ((overload & 2) ? DHCP_SNAME_LEN : 0)),
277  options, priority_list, priority_len, main_buffer_size,
278  (main_buffer_size + ((overload & 1) ? DHCP_FILE_LEN : 0)),
279  terminate);
280 
281  /* Put the cookie up front... */
282  memcpy(outpacket->options, DHCP_OPTIONS_COOKIE, 4);
283  mainbufix = 4;
284 
285  /*
286  * If we're going to have to overload, store the overload option
287  * at the beginning. If we can, though, just store the whole
288  * thing in the packet's option buffer and leave it at that.
289  */
290  if (option_size <= main_buffer_size - mainbufix) {
291  memcpy(&outpacket->options[mainbufix],
292  buffer, option_size);
293  mainbufix += option_size;
294  if (mainbufix < main_buffer_size)
295  outpacket->options[mainbufix++] = DHO_END;
296  length = DHCP_FIXED_NON_UDP + mainbufix;
297  } else {
298  outpacket->options[mainbufix++] = DHO_DHCP_OPTION_OVERLOAD;
299  outpacket->options[mainbufix++] = 1;
300  if (option_size >
301  main_buffer_size - mainbufix + DHCP_FILE_LEN)
302  outpacket->options[mainbufix++] = 3;
303  else
304  outpacket->options[mainbufix++] = 1;
305 
306  memcpy(&outpacket->options[mainbufix],
307  buffer, main_buffer_size - mainbufix);
308  bufix = main_buffer_size - mainbufix;
309  length = DHCP_FIXED_NON_UDP + mainbufix;
310  if (overload & 1) {
311  if (option_size - bufix <= DHCP_FILE_LEN) {
312  memcpy(outpacket->file,
313  &buffer[bufix], option_size - bufix);
314  mainbufix = option_size - bufix;
315  if (mainbufix < DHCP_FILE_LEN)
316  outpacket->file[mainbufix++] = (char)DHO_END;
317  while (mainbufix < DHCP_FILE_LEN)
318  outpacket->file[mainbufix++] = (char)DHO_PAD;
319  } else {
320  memcpy(outpacket->file,
321  &buffer[bufix], DHCP_FILE_LEN);
322  bufix += DHCP_FILE_LEN;
323  }
324  }
325  if ((overload & 2) && option_size < bufix) {
326  memcpy(outpacket->sname,
327  &buffer[bufix], option_size - bufix);
328 
329  mainbufix = option_size - bufix;
330  if (mainbufix < DHCP_SNAME_LEN)
331  outpacket->file[mainbufix++] = (char)DHO_END;
332  while (mainbufix < DHCP_SNAME_LEN)
333  outpacket->file[mainbufix++] = (char)DHO_PAD;
334  }
335  }
336  return (length);
337 }
char file[DHCP_FILE_LEN]
Definition: dhcp.h:71
#define DHO_DHCP_MESSAGE
Definition: dhcp.h:152
char sname[DHCP_SNAME_LEN]
Definition: dhcp.h:70
#define DHO_END
Definition: dhcp.h:159
#define DHO_DHCP_LEASE_TIME
Definition: dhcp.h:147
#define DHCP_FIXED_NON_UDP
Definition: dhcp.h:48
#define DHO_DHCP_MESSAGE_TYPE
Definition: dhcp.h:149
#define DHO_PAD
Definition: dhcp.h:96
GLuint buffer
Definition: glext.h:5915
#define DHO_DHCP_PARAMETER_REQUEST_LIST
Definition: dhcp.h:151
u_int16_t getUShort(unsigned char *data)
Definition: util.c:88
#define DHCP_FILE_LEN
Definition: dhcp.h:47
#define DHCP_OPTIONS_COOKIE
Definition: dhcp.h:91
unsigned char
Definition: typeof.h:27
unsigned char options[DHCP_OPTION_LEN]
Definition: dhcp.h:72
void MSVCRT() terminate()
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
#define DHO_DHCP_OPTION_OVERLOAD
Definition: dhcp.h:148
#define DHCP_FIXED_LEN
Definition: dhcp.h:49
struct option_data options[256]
Definition: dhcpd.h:144
unsigned short u_int16_t
Definition: rosdhcp.h:34
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
int sizeof_dhcp_option_default_priority_list
Definition: tables.c:408
#define DHO_DHCP_SERVER_IDENTIFIER
Definition: dhcp.h:150
unsigned char dhcp_option_default_priority_list[]
Definition: tables.c:329
#define DHO_DHCP_MAX_MESSAGE_SIZE
Definition: dhcp.h:153
int store_options(unsigned char *, int, struct tree_cache **, unsigned char *, int, int, int, int)
Definition: options.c:343
#define DHCP_SNAME_LEN
Definition: dhcp.h:46

◆ do_packet()

void do_packet ( struct interface_info interface,
struct dhcp_packet packet,
int  len,
unsigned int  from_port,
struct iaddr  from,
struct hardware hfrom 
)

Definition at line 687 of file options.c.

Referenced by init_client().

689 {
690  struct packet tp;
691  int i;
692 
693  if (packet->hlen > sizeof(packet->chaddr)) {
694  note("Discarding packet with invalid hlen.");
695  return;
696  }
697 
698  memset(&tp, 0, sizeof(tp));
699  tp.raw = packet;
700  tp.packet_length = len;
701  tp.client_port = from_port;
702  tp.client_addr = from;
703  tp.interface = interface;
704  tp.haddr = hfrom;
705 
706  parse_options(&tp);
707  if (tp.options_valid &&
708  tp.options[DHO_DHCP_MESSAGE_TYPE].data)
709  tp.packet_type = tp.options[DHO_DHCP_MESSAGE_TYPE].data[0];
710  if (tp.packet_type)
711  dhcp(&tp);
712  else
713  bootp(&tp);
714 
715  /* Free the data associated with the options. */
716  for (i = 0; i < 256; i++)
717  if (tp.options[i].len && tp.options[i].data)
718  free(tp.options[i].data);
719 }
UCHAR packet[_PAGE_SIZE]
Definition: serial.c:53
#define free
Definition: debug_ros.c:5
#define DHO_DHCP_MESSAGE_TYPE
Definition: dhcp.h:149
u_int8_t hlen
Definition: dhcp.h:60
void bootp(struct packet *packet)
Definition: dhclient.c:662
_In_ UINT64 _In_ UINT64 _In_ UINT64 _In_opt_ traverse_ptr * tp
Definition: btrfs.c:2630
GLenum GLclampf GLint i
Definition: glfuncs.h:14
int note(char *format,...)
Definition: util.c:12
unsigned char chaddr[16]
Definition: dhcp.h:69
GLenum GLsizei len
Definition: glext.h:6722
#define interface
Definition: basetyps.h:61
void dhcp(struct packet *packet)
Definition: dhclient.c:682
void parse_options(struct packet *)
Definition: options.c:59
CardRegion * from
Definition: spigame.cpp:19
#define memset(x, y, z)
Definition: compat.h:39

◆ parse_option_buffer()

void parse_option_buffer ( struct packet packet,
unsigned char buffer,
int  length 
)

Definition at line 100 of file options.c.

Referenced by parse_options().

102 {
103  unsigned char *s, *t, *end = buffer + length;
104  int len, code;
105 
106  for (s = buffer; *s != DHO_END && s < end; ) {
107  code = s[0];
108 
109  /* Pad options don't have a length - just skip them. */
110  if (code == DHO_PAD) {
111  s++;
112  continue;
113  }
114  if (s + 2 > end) {
115  len = 65536;
116  goto bogus;
117  }
118 
119  /*
120  * All other fields (except end, see above) have a
121  * one-byte length.
122  */
123  len = s[1];
124 
125  /*
126  * If the length is outrageous, silently skip the rest,
127  * and mark the packet bad. Unfortunately some crappy
128  * dhcp servers always seem to give us garbage on the
129  * end of a packet. so rather than keep refusing, give
130  * up and try to take one after seeing a few without
131  * anything good.
132  */
133  if (s + len + 2 > end) {
134  bogus:
135  bad_options++;
136  warning("option %s (%d) %s.",
137  dhcp_options[code].name, len,
138  "larger than buffer");
139  if (bad_options == bad_options_max) {
140  packet->options_valid = 1;
141  bad_options = 0;
142  warning("Many bogus options seen in offers. "
143  "Taking this offer in spite of bogus "
144  "options - hope for the best!");
145  } else {
146  warning("rejecting bogus offer.");
147  packet->options_valid = 0;
148  }
149  return;
150  }
151  /*
152  * If we haven't seen this option before, just make
153  * space for it and copy it there.
154  */
155  if (!packet->options[code].data) {
156  if (!(t = calloc(1, len + 1)))
157  error("Can't allocate storage for option %s.",
158  dhcp_options[code].name);
159  /*
160  * Copy and NUL-terminate the option (in case
161  * it's an ASCII string.
162  */
163  memcpy(t, &s[2], len);
164  t[len] = 0;
165  packet->options[code].len = len;
166  packet->options[code].data = t;
167  } else {
168  /*
169  * If it's a repeat, concatenate it to whatever
170  * we last saw. This is really only required
171  * for clients, but what the heck...
172  */
173  t = calloc(1, len + packet->options[code].len + 1);
174  if (!t) {
175  error("Can't expand storage for option %s.",
176  dhcp_options[code].name);
177  return;
178  }
179  memcpy(t, packet->options[code].data,
180  packet->options[code].len);
181  memcpy(t + packet->options[code].len,
182  &s[2], len);
183  packet->options[code].len += len;
184  t[packet->options[code].len] = 0;
185  free(packet->options[code].data);
186  packet->options[code].data = t;
187  }
188  s += len + 2;
189  }
190  packet->options_valid = 1;
191 }
#define DHO_END
Definition: dhcp.h:159
#define error(str)
Definition: mkdosfs.c:1605
#define free
Definition: debug_ros.c:5
GLdouble GLdouble t
Definition: gl.h:2047
#define DHO_PAD
Definition: dhcp.h:96
GLuint buffer
Definition: glext.h:5915
GLuint GLuint end
Definition: gl.h:1545
struct dhcp_option dhcp_options[256]
Definition: tables.c:68
int bad_options_max
Definition: options.c:47
int options_valid
Definition: dhcpd.h:139
int bad_options
Definition: options.c:46
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
struct option_data options[256]
Definition: dhcpd.h:144
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
GLdouble s
Definition: gl.h:2039
int code
Definition: i386-dis.c:3591
Definition: name.c:36
#define calloc
Definition: rosglue.h:14
#define warning(s)
Definition: debug.h:71

◆ parse_options()

void parse_options ( struct packet packet)

Definition at line 59 of file options.c.

Referenced by do_packet().

60 {
61  /* Initially, zero all option pointers. */
62  memset(packet->options, 0, sizeof(packet->options));
63 
64  /* If we don't see the magic cookie, there's nothing to parse. */
65  if (memcmp(packet->raw->options, DHCP_OPTIONS_COOKIE, 4)) {
66  packet->options_valid = 0;
67  return;
68  }
69 
70  /*
71  * Go through the options field, up to the end of the packet or
72  * the End field.
73  */
74  parse_option_buffer(packet, &packet->raw->options[4],
75  packet->packet_length - DHCP_FIXED_NON_UDP - 4);
76 
77  /*
78  * If we parsed a DHCP Option Overload option, parse more
79  * options out of the buffer(s) containing them.
80  */
81  if (packet->options_valid &&
82  packet->options[DHO_DHCP_OPTION_OVERLOAD].data) {
83  if (packet->options[DHO_DHCP_OPTION_OVERLOAD].data[0] & 1)
84  parse_option_buffer(packet,
85  (unsigned char *)packet->raw->file,
86  sizeof(packet->raw->file));
87  if (packet->options[DHO_DHCP_OPTION_OVERLOAD].data[0] & 2)
88  parse_option_buffer(packet,
89  (unsigned char *)packet->raw->sname,
90  sizeof(packet->raw->sname));
91  }
92 }
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define DHCP_FIXED_NON_UDP
Definition: dhcp.h:48
void parse_option_buffer(struct packet *, unsigned char *, int)
Definition: options.c:100
#define DHCP_OPTIONS_COOKIE
Definition: dhcp.h:91
struct dhcp_packet * raw
Definition: dhcpd.h:136
int options_valid
Definition: dhcpd.h:139
#define DHO_DHCP_OPTION_OVERLOAD
Definition: dhcp.h:148
struct option_data options[256]
Definition: dhcpd.h:144
int packet_length
Definition: dhcpd.h:137
#define memset(x, y, z)
Definition: compat.h:39

◆ pretty_print_option()

char* pretty_print_option ( unsigned int  code,
unsigned char data,
int  len,
int  emit_commas,
int  emit_quotes 
)

Definition at line 448 of file options.c.

Referenced by check_option(), priv_script_write_params(), and write_client_lease().

450 {
451  static char optbuf[32768]; /* XXX */
452  int hunksize = 0, numhunk = -1, numelem = 0;
453  char fmtbuf[32], *op = optbuf;
454  int i, j, k, opleft = sizeof(optbuf);
455  unsigned char *dp = data;
456  struct in_addr foo;
457  char comma;
458 
459  /* Code should be between 0 and 255. */
460  if (code > 255)
461  error("pretty_print_option: bad code %d", code);
462 
463  if (emit_commas)
464  comma = ',';
465  else
466  comma = ' ';
467 
468  /* Figure out the size of the data. */
469  for (i = 0; dhcp_options[code].format[i]; i++) {
470  if (!numhunk) {
471  warning("%s: Excess information in format string: %s",
473  &(dhcp_options[code].format[i]));
474  break;
475  }
476  numelem++;
477  fmtbuf[i] = dhcp_options[code].format[i];
478  switch (dhcp_options[code].format[i]) {
479  case 'A':
480  --numelem;
481  fmtbuf[i] = 0;
482  numhunk = 0;
483  break;
484  case 'X':
485  for (k = 0; k < len; k++)
486  if (!isascii(data[k]) ||
487  !isprint(data[k]))
488  break;
489  if (k == len) {
490  fmtbuf[i] = 't';
491  numhunk = -2;
492  } else {
493  fmtbuf[i] = 'x';
494  hunksize++;
495  comma = ':';
496  numhunk = 0;
497  }
498  fmtbuf[i + 1] = 0;
499  break;
500  case 't':
501  fmtbuf[i] = 't';
502  fmtbuf[i + 1] = 0;
503  numhunk = -2;
504  break;
505  case 'I':
506  case 'l':
507  case 'L':
508  hunksize += 4;
509  break;
510  case 's':
511  case 'S':
512  hunksize += 2;
513  break;
514  case 'b':
515  case 'B':
516  case 'f':
517  hunksize++;
518  break;
519  case 'e':
520  break;
521  default:
522  warning("%s: garbage in format string: %s",
524  &(dhcp_options[code].format[i]));
525  break;
526  }
527  }
528 
529  /* Check for too few bytes... */
530  if (hunksize > len) {
531  warning("%s: expecting at least %d bytes; got %d",
532  dhcp_options[code].name, hunksize, len);
533  return ("<error>");
534  }
535  /* Check for too many bytes... */
536  if (numhunk == -1 && hunksize < len)
537  warning("%s: %d extra bytes",
538  dhcp_options[code].name, len - hunksize);
539 
540  /* If this is an array, compute its size. */
541  if (!numhunk)
542  numhunk = len / hunksize;
543  /* See if we got an exact number of hunks. */
544  if (numhunk > 0 && numhunk * hunksize < len)
545  warning("%s: %d extra bytes at end of array",
546  dhcp_options[code].name, len - numhunk * hunksize);
547 
548  /* A one-hunk array prints the same as a single hunk. */
549  if (numhunk < 0)
550  numhunk = 1;
551 
552  /* Cycle through the array (or hunk) printing the data. */
553  for (i = 0; i < numhunk; i++) {
554  for (j = 0; j < numelem; j++) {
555  int opcount;
556  switch (fmtbuf[j]) {
557  case 't':
558  if (emit_quotes) {
559  *op++ = '"';
560  opleft--;
561  }
562  for (; dp < data + len; dp++) {
563  if (!isascii(*dp) ||
564  !isprint(*dp)) {
565  if (dp + 1 != data + len ||
566  *dp != 0) {
567  _snprintf(op, opleft,
568  "\\%03o", *dp);
569  op += 4;
570  opleft -= 4;
571  }
572  } else if (*dp == '"' ||
573  *dp == '\'' ||
574  *dp == '$' ||
575  *dp == '`' ||
576  *dp == '\\') {
577  *op++ = '\\';
578  *op++ = *dp;
579  opleft -= 2;
580  } else {
581  *op++ = *dp;
582  opleft--;
583  }
584  }
585  if (emit_quotes) {
586  *op++ = '"';
587  opleft--;
588  }
589 
590  *op = 0;
591  break;
592  case 'I':
593  foo.s_addr = htonl(getULong(dp));
594  strncpy(op, inet_ntoa(foo), opleft - 1);
595  op[opleft - 1] = ANSI_NULL;
596  opcount = strlen(op);
597  if (opcount >= opleft)
598  goto toobig;
599  opleft -= opcount;
600  dp += 4;
601  break;
602  case 'l':
603  opcount = _snprintf(op, opleft, "%ld",
604  (long)getLong(dp));
605  if (opcount >= opleft || opcount == -1)
606  goto toobig;
607  opleft -= opcount;
608  dp += 4;
609  break;
610  case 'L':
611  opcount = _snprintf(op, opleft, "%ld",
612  (unsigned long)getULong(dp));
613  if (opcount >= opleft || opcount == -1)
614  goto toobig;
615  opleft -= opcount;
616  dp += 4;
617  break;
618  case 's':
619  opcount = _snprintf(op, opleft, "%d",
620  getShort(dp));
621  if (opcount >= opleft || opcount == -1)
622  goto toobig;
623  opleft -= opcount;
624  dp += 2;
625  break;
626  case 'S':
627  opcount = _snprintf(op, opleft, "%d",
628  getUShort(dp));
629  if (opcount >= opleft || opcount == -1)
630  goto toobig;
631  opleft -= opcount;
632  dp += 2;
633  break;
634  case 'b':
635  opcount = _snprintf(op, opleft, "%d",
636  *(char *)dp++);
637  if (opcount >= opleft || opcount == -1)
638  goto toobig;
639  opleft -= opcount;
640  break;
641  case 'B':
642  opcount = _snprintf(op, opleft, "%d", *dp++);
643  if (opcount >= opleft || opcount == -1)
644  goto toobig;
645  opleft -= opcount;
646  break;
647  case 'x':
648  opcount = _snprintf(op, opleft, "%x", *dp++);
649  if (opcount >= opleft || opcount == -1)
650  goto toobig;
651  opleft -= opcount;
652  break;
653  case 'f':
654  opcount = (size_t) strncpy(op, *dp++ ? "true" : "false", opleft - 1);
655  op[opleft - 1] = ANSI_NULL;
656  if (opcount >= opleft)
657  goto toobig;
658  opleft -= opcount;
659  break;
660  default:
661  warning("Unexpected format code %c", fmtbuf[j]);
662  }
663  op += strlen(op);
664  opleft -= strlen(op);
665  if (opleft < 1)
666  goto toobig;
667  if (j + 1 < numelem && comma != ':') {
668  *op++ = ' ';
669  opleft--;
670  }
671  }
672  if (i + 1 < numhunk) {
673  *op++ = comma;
674  opleft--;
675  }
676  if (opleft < 1)
677  goto toobig;
678 
679  }
680  return (optbuf);
681  toobig:
682  warning("dhcp option too large");
683  return ("<error>");
684 }
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble const GLfloat const GLdouble const GLfloat GLenum GLint GLint GLint GLint GLint GLint j
Definition: glfuncs.h:98
int16_t getShort(unsigned char *data)
Definition: util.c:84
#define error(str)
Definition: mkdosfs.c:1605
#define htonl(x)
Definition: module.h:212
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
u_int16_t getUShort(unsigned char *data)
Definition: util.c:88
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
struct dhcp_option dhcp_options[256]
Definition: tables.c:68
#define _snprintf
Definition: xmlstorage.h:200
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#define ANSI_NULL
UINT op
Definition: effect.c:223
#define inet_ntoa(addr)
Definition: inet.h:100
__kernel_size_t size_t
Definition: linux.h:237
int32_t getLong(unsigned char *data)
Definition: util.c:92
Definition: tcpip.h:125
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLenum GLsizei len
Definition: glext.h:6722
int code
Definition: i386-dis.c:3591
#define isascii
Definition: ctype.h:742
u_int32_t getULong(unsigned char *data)
Definition: util.c:96
#define isprint(c)
Definition: acclib.h:73
Definition: name.c:36
int k
Definition: mpi.c:3369
#define warning(s)
Definition: debug.h:71

◆ store_options()

int store_options ( unsigned char buffer,
int  buflen,
struct tree_cache **  options,
unsigned char priority_list,
int  priority_len,
int  first_cutoff,
int  second_cutoff,
int  terminate 
)

Definition at line 343 of file options.c.

Referenced by cons_options().

346 {
347  int bufix = 0, option_stored[256], i, ix, tto;
348 
349  /* Zero out the stored-lengths array. */
350  memset(option_stored, 0, sizeof(option_stored));
351 
352  /*
353  * Copy out the options in the order that they appear in the
354  * priority list...
355  */
356  for (i = 0; i < priority_len; i++) {
357  /* Code for next option to try to store. */
358  int code = priority_list[i];
359  int optstart;
360 
361  /*
362  * Number of bytes left to store (some may already have
363  * been stored by a previous pass).
364  */
365  int length;
366 
367  /* If no data is available for this option, skip it. */
368  if (!options[code]) {
369  continue;
370  }
371 
372  /*
373  * The client could ask for things that are mandatory,
374  * in which case we should avoid storing them twice...
375  */
376  if (option_stored[code])
377  continue;
378  option_stored[code] = 1;
379 
380  /* We should now have a constant length for the option. */
381  length = options[code]->len;
382 
383  /* Do we add a NUL? */
384  if (terminate && dhcp_options[code].format[0] == 't') {
385  length++;
386  tto = 1;
387  } else
388  tto = 0;
389 
390  /* Try to store the option. */
391 
392  /*
393  * If the option's length is more than 255, we must
394  * store it in multiple hunks. Store 255-byte hunks
395  * first. However, in any case, if the option data will
396  * cross a buffer boundary, split it across that
397  * boundary.
398  */
399  ix = 0;
400 
401  optstart = bufix;
402  while (length) {
403  unsigned char incr = length > 255 ? 255 : length;
404 
405  /*
406  * If this hunk of the buffer will cross a
407  * boundary, only go up to the boundary in this
408  * pass.
409  */
410  if (bufix < first_cutoff &&
411  bufix + incr > first_cutoff)
412  incr = first_cutoff - bufix;
413  else if (bufix < second_cutoff &&
414  bufix + incr > second_cutoff)
415  incr = second_cutoff - bufix;
416 
417  /*
418  * If this option is going to overflow the
419  * buffer, skip it.
420  */
421  if (bufix + 2 + incr > buflen) {
422  bufix = optstart;
423  break;
424  }
425 
426  /* Everything looks good - copy it in! */
427  buffer[bufix] = code;
428  buffer[bufix + 1] = incr;
429  if (tto && incr == length) {
430  memcpy(buffer + bufix + 2,
431  options[code]->value + ix, incr - 1);
432  buffer[bufix + 2 + incr - 1] = 0;
433  } else
434  memcpy(buffer + bufix + 2,
435  options[code]->value + ix, incr);
436  length -= incr;
437  ix += incr;
438  bufix += 2 + incr;
439  }
440  }
441  return (bufix);
442 }
Definition: get.c:139
GLuint buffer
Definition: glext.h:5915
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
int len
Definition: tree.h:50
struct dhcp_option dhcp_options[256]
Definition: tables.c:68
GLenum GLclampf GLint i
Definition: glfuncs.h:14
void MSVCRT() terminate()
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
int code
Definition: i386-dis.c:3591
#define memset(x, y, z)
Definition: compat.h:39

Variable Documentation

◆ bad_options

int bad_options = 0

Definition at line 46 of file options.c.

Referenced by parse_option_buffer().

◆ bad_options_max

int bad_options_max = 5

Definition at line 47 of file options.c.

Referenced by parse_option_buffer().