⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dhcp-option-convert.c

📁 this is sample about DHCP-agent
💻 C
📖 第 1 页 / 共 4 页
字号:
/* $Header: /cvsroot/dhcp-agent/dhcp-agent/src/dhcp-option-convert.c,v 1.6 2003/06/27 03:16:27 actmodern Exp $ *  * Copyright 2002, 2003 Thamer Alharbash <tmh@whitefang.com> *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: *  * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * 3. The names of the authors may not be used to endorse or promote * products derived from this software without specific prior * written permission. *  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. *  *//* FIXME: still a tad messy and a bit over redundant. but it * works for now until release time.  document and prune anything * that needs pruning. */#define MODULE_NAME "dhcp-option-convert"#include "dhcp-local.h"#include "dhcp-libutil.h"#include "dhcp-librawnet.h"#include "dhcp-option.h"#include "dhcp-option-convert.h"#include "dhcp-limits.h"/* *  *  *  *  *  *  * *  * utility routines.   * * * * * * * * * * * * *//* count internal string atoms, and mark with sentinals. this * wrecks the string so it should only be used on a copy. * FIXME: this works but really should be a stringbuffer thing. */static size_t count_internal_string_atoms_and_mark(char *input){    char *ptr;    size_t num = 0;    ptr = input;    while(*ptr)  {        switch(*ptr)  {        case ';':            num++;            *ptr = 0;            ptr++;        case '\\':            if((*ptr + 1) == ';')  {                ptr += 2; /* skip. */            }         default: /* fall through. */            ptr++;            break;        }    }    if(num == 0 && *input != 0)        num++; /* we have at least one. */    return num;}/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * From internal to network format:                              * *                                                               * *                                                               * * uint8, int8 are just copied verbatim since they're octets     * * which need no marshalling.                                    * *                                                               * * uint16, int16 are htons as they are copied over.              * *                                                               * * uint32, int32 are htonl as they are copied over.              * *                                                               * * signed are wrapped around unsigned conversions since          * * marshalling should not interfere with signedness.             * *                                                               * * copying from a list is a bit more ugly. here we redo          * * everything only we're copying from a list to contigenous      * * memory.                                                       * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//* make a copy of an unsigned byte. */static uint8_t *uint8_copy_to_network(const void *data, size_t num){    uint8_t *uint8_copy;    uint8_copy = xmalloc((sizeof(uint8_t) * num));    memcpy(uint8_copy, data, (sizeof(uint8_t) * num));    return uint8_copy;}/* make a copy of an signed byte. */static int8_t *int8_copy_to_network(const void *data, size_t num){    return (int8_t *)uint8_copy_to_network(data, num); /* just cast. since it doesn't matter. */}/* make a copy of an unsigned 16-bit integer to network. */static uint16_t *uint16_copy_to_network(const void *data, size_t num){    const uint16_t *uint16_data;    uint16_t *uint16_copy;    size_t i;    uint16_data = data;    uint16_copy = xmalloc((sizeof(uint16_t) * num));    for(i = 0;i < num;i ++) {        uint16_copy[i] = htons(uint16_data[i]);    }    return uint16_copy;}/* make a copy of an signed 16-bit integer. */static int16_t *int16_copy_to_network(const void *data, size_t num){    /* just cast. since it doesn't matter as long as we're just copying. */    return (int16_t *)uint16_copy_to_network(data, num);}/* make a copy of an unsigned 32-bit integer. */static uint32_t *uint32_copy_to_network(const void *data, size_t num){    const uint32_t *uint32_data;    uint32_t *uint32_copy;    size_t i;    uint32_data = data;    uint32_copy = xmalloc((sizeof(uint32_t) * num));    for(i = 0;i < num;i ++) {        uint32_copy[i] = htonl(uint32_data[i]);    }    return uint32_copy;}/* make a copy of an signed 16-bit integer. */static int32_t *int32_copy_to_network(const void *data, size_t num){    /* just cast. since it doesn't matter as long as we're just copying. */    return (int32_t *)uint32_copy_to_network(data, num); }static void *int_list_copy_to_network(list_t *list, size_t size, uint8_t sign){    void *datum;    void *ret_data;    size_t num;    /* get rid of compiler warnings. these will be initialized but the compiler may not see it .*/    uint8_t  *uint8_data = NULL;    uint16_t *uint16_data = NULL;    uint32_t *uint32_data = NULL;    int8_t  *int8_data = NULL;    int16_t *int16_data = NULL;    int32_t *int32_data = NULL;    uint8_t  *uint8_ptr = NULL;    uint16_t *uint16_ptr = NULL;    uint32_t *uint32_ptr = NULL;    int8_t  *int8_ptr = NULL;    int16_t *int16_ptr = NULL;    int32_t *int32_ptr = NULL;    num = list_get_len(list);    /* create datum. it's size * num, but we need to assign it to the right pointer. */    if(sign)  {        switch(size)  {        case sizeof(int8_t):            int8_data = xmalloc(sizeof(int8_data) * num);            int8_ptr = int8_data;            ret_data = int8_data;            break;        case sizeof(int16_t):            int16_data = xmalloc(sizeof(int16_data) * num);            int16_ptr = int16_data;            ret_data = int16_data;            break;        case sizeof(int32_t):            int32_data = xmalloc(sizeof(int32_data) * num);            int32_ptr = int32_data;            ret_data = int32_data;            break;        default:            FATAL_MESSAGE("illegal size passed for conversion. this is a bug report me.");            exit(1);        }    } else {        switch(size)  {        case sizeof(uint8_t):            uint8_data = xmalloc(sizeof(uint8_t) * num);            uint8_ptr = uint8_data;            ret_data = uint8_data;            break;        case sizeof(uint16_t):            uint16_data = xmalloc(sizeof(uint16_t) * num);            uint16_ptr = uint16_data;            ret_data = uint16_data;            break;        case sizeof(uint32_t):            uint32_data = xmalloc(sizeof(uint32_t) * num);            uint32_ptr = uint32_data;            ret_data = uint32_data;            break;        default:            FATAL_MESSAGE("illegal size passed for conversion. this is a bug report me.");            exit(1);        }    }    while((datum = list_next(list)) != NULL)  {        if(sign)  {            switch(size)  {            case sizeof(int8_t):                *int8_ptr = *(int8_t *)datum;                int8_ptr++;                break;            case sizeof(int16_t):                *int16_ptr = htons(*(int16_t *)datum);                int16_ptr++;                break;            case sizeof(int32_t):                memcpy(int32_ptr, datum, sizeof(int32_t));                *int32_ptr = htons(*(int32_t *)datum);                int32_ptr++;                break;            default:                FATAL_MESSAGE("illegal size passed for conversion. this is a bug report me.");                exit(1);            }        }  else  {            switch(size)  {            case sizeof(uint8_t):                memcpy(uint8_ptr, datum, sizeof(uint8_t));                uint8_ptr++;                break;            case sizeof(uint16_t):                *uint16_ptr = htons(*(uint16_t *)datum);                uint16_ptr++;                break;            case sizeof(uint32_t):                *uint32_ptr = htons(*(uint32_t *)datum);                uint32_ptr++;                break;            default:                FATAL_MESSAGE("illegal size passed for conversion. this is a bug report me.");                exit(1);            }        }    }    return ret_data;}/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * From network to internal format:                              * *                                                               * * uint8, int8 are just copied verbatim since they're octets     * * which need no marshalling. we can call the uint8              * * copy to network routines since they do the same thing.        * *                                                               * * uint16, int16 are ntohs as they are copied over.              * *                                                               * * uint32, int32 are ntohl as they are copied over.              * *                                                               * * signed conversions are wrapped around unsigned conversions    * * since marshalling should not interfere with signedness.       * *                                                               * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//* make a copy of an unsigned byte from network. */static uint8_t *uint8_copy_from_network(const uint8_t *data, size_t num){    /* no marshalling needs to be done on individual bytes. */    return uint8_copy_to_network(data, num);}/* make a copy of an signed byte from network. */static int8_t *int8_copy_from_network(const uint8_t *data, size_t num){    /* no marshalling needs to be done on individual bytes. */    return int8_copy_to_network(data, num);}/* make a copy of an unsigned 16-bit integer from network. */static uint16_t *uint16_copy_from_network(const void *data, size_t num){    const uint16_t *uint16_data;    uint16_t *uint16_copy;    size_t i;    uint16_copy = xmalloc((sizeof(uint16_t) * num));    uint16_data = data;    for(i = 0;i < num;i ++) {        uint16_copy[i] = ntohs(uint16_data[i]);    }    return uint16_copy;}/* make a copy of an signed 16-bit integer. */static int16_t *int16_copy_from_network(const void *data, size_t num){    /* just cast. since it doesn't matter as long as we're just copying. */    return (int16_t *)uint16_copy_from_network(data, num);}/* make a copy of an unsigned 32-bit integer. */static uint32_t *uint32_copy_from_network(const void *data, size_t num){    const uint32_t *uint32_data = data;    uint32_t *uint32_copy;    size_t i;    uint32_copy = xmalloc((sizeof(uint32_t) * num));    uint32_data = data;    for(i = 0;i < num;i ++) {        uint32_copy[i] = ntohl(uint32_data[i]);    }    return uint32_copy;}/* make a copy of an signed 16-bit integer. */static int32_t *int32_copy_from_network(const void *data, size_t num){    /* just cast. since it doesn't matter as long as we're just copying. */    return (int32_t *)uint32_copy_to_network(data, num); }/* convenience routine. take any size/typ eand convert to a list. */static list_t *int_list_from_network_proc(const uint8_t *data, size_t len, size_t size, uint8_t sign){    list_t *data_list;    void *datum;    /* check for at least one atom. */    if(len < size)        return NULL;    /* check to make sure it's divisible by exactly the size of the atom. */    if(len%size)        return NULL;    data_list = list_create();    while(len)  {        if(sign) {            switch(size) {            case sizeof(int8_t):                datum = int8_copy_from_network(data, 1);                break;            case sizeof(int16_t):                datum = int16_copy_from_network(data, 1);                break;            case sizeof(int32_t):                datum = int32_copy_from_network(data, 1);                break;            default:                FATAL_MESSAGE("illegal size passed for conversion. this is a bug report me.");                exit(1);            }        } else {            switch(size) {            case sizeof(uint8_t):                datum = uint8_copy_from_network(data, 1);                break;            case sizeof(uint16_t):                datum = uint16_copy_from_network(data, 1);                break;            case sizeof(uint32_t):                datum = uint32_copy_from_network(data, 1);                break;            default:                FATAL_MESSAGE("illegal size passed for conversion. this is a bug report me.");                exit(1);            }        }        if(datum == NULL) {            list_destroy(data_list, xfree);            return NULL;        }        /* add datum to list. */        list_add(data_list, datum);        /* decrement length, and push pointer forward. */        len -= size;        data += size;    }    return data_list;}/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * From internal string to internal format.                      * *                                                               * * All input is passed via a string. The string is re-read from  * * a file we've already created (usually), or rewritten to be    * * handled internally. This means we can trust it.               * *                                                               * * scanfs throughout with the necessary C99 macro to read        * * in the value.                                                 * *                                                               * * The only special case happens when we want to read into a     * * list or an array. Here we expect a string with null           * * characters to terminate the individual datums. This is done   * * by marking the special delimiter ';'.                         *                  *                                                               * *                                                               * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//* internal string to internal unsigned byte value. */static uint8_t *internal_string_uint8_to_internal(const char *input){    uint8_t *uint8_val;    uint8_val = xmalloc(sizeof(uint8_t));    sscanf(input, "%"SCNu8, uint8_val);    return uint8_val;}/* internal string to internal unsigned byte value. */static uint16_t *internal_string_uint16_to_internal(const char *input){    uint16_t *uint16_data;    uint16_data = xmalloc(sizeof(uint16_t));    sscanf(input, "%"SCNu16, uint16_data);    return uint16_data;}/* internal string to internal unsigned byte value. */static uint32_t *internal_string_uint32_to_internal(const char *input){    uint32_t *uint32_data;    uint32_data = xmalloc(sizeof(uint32_t));    sscanf(input, "%"SCNu32, uint32_data);    return uint32_data;}/* internal string to internal signed 8-bit value. */static int8_t *internal_string_int8_to_internal(const char *input){    int8_t *int8_val;    int8_val = xmalloc(sizeof(int8_t));    sscanf(input, "%"SCNi8, int8_val);    return int8_val;}/* internal string to internal byte value. */static int16_t *internal_string_int16_to_internal(const char *input){    int16_t *int16_val;    int16_val = xmalloc(sizeof(int16_t));    sscanf(input, "%"SCNi16, int16_val);    return int16_val;}/* internal string to internal byte value. */static int32_t *internal_string_int32_to_internal(const char *input){    int32_t *int32_val;    int32_val = xmalloc(sizeof(int32_t));    sscanf(input, "%"SCNi32, int32_val);    return int32_val;}/* * * * * * * * * * * * * * * * * * * * internal string to integer array. * * * * * * * * * * * * * * * * * * * */static void *internal_string_to_array_int_proc(const char *input, size_t count, size_t size, uint8_t sign){    void *data;    size_t i;    const char *ptr;    uint8_t  *uint8_ptr;    uint16_t *uint16_ptr;    uint32_t *uint32_ptr;    int8_t  *int8_ptr;    int16_t *int16_ptr;    int32_t *int32_ptr;    data = xmalloc(count * size);    ptr = input;    i = 0;    while(i < count)  {        if(sign) {            switch(size) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -