note

 

这里他们一共占据的空间并不是4+1+4=9,这里涉及到”对齐原则”,编译器为提供内存访问速度,要保证结构地址满足4字节的对齐要求,所以系统用了4个字节来存放char类型,也即浪费了3个字节的空间,因此,这里总共占据空间为12字节.

main()
{
    int IntValue;
       struct student
       {
             
              int num;
              char sex;
              int score;
             
             
       };
       struct student jesse={2316124029,'M',98};

    struct student *p;
       p=&jesse;
    IntValue=*((int *)p+2);//说明2
}

http://hi.baidu.com/yichuanshan1986/blog/item/7262ec5e6a52d348fbf2c0a4.html

如果你的结构体如下定义:
 user a;
强制转换:
unsigned int *PITemp;
PITemp = ( unsigned int *)&a;

如果需要将数据unsinged int ArrayITemp[ ];转换成结构体类型,
user *PUserA;
PUserA = ( user *)ArrayITemp;

typedef unsigned char  BOOLEAN;
typedef unsigned char  INT8U;                    /* Unsigned  8 bit quantity                           */
typedef signed   char  INT8S;                    /* Signed    8 bit quantity                           */
typedef unsigned int   INT16U;                   /* Unsigned 16 bit quantity                           */
typedef signed   int   INT16S;                   /* Signed   16 bit quantity                           */
typedef unsigned long  INT32U;                   /* Unsigned 32 bit quantity                           */
typedef signed   long  INT32S;

 

typedef struct
{
char name[16];
char passwd[16];
char CMS[3];
}Data;

Data *cli_data = new Data;
strcpy(cli_data->CMS,"REG");
cin >> cli_data->name;
cin >> cli_data->passwd;

char *buf = new char[4096];

buf = (char *)cli_data;

sendto(server_fd,buf,sizeof(buf),....);


char* buf = new char[4];
s_test* p = (s_test*)buf;
s_test a = *(s_test*)&buf;

 


#include <stdio.h>
#include<iostream>
int main(void)
{
 int options[20];
int n=0;
//printf ("N M = "); scanf("%d%d", &n, &m);
//for (i=2; i<=n; i++) s=(s+m)%i;
//printf ("The winner is %d\n", s+1);
options[n++]=0;
options[n++]=1;
options[n++]=2;
options[n++]=3;
for(int m=n;m<10;m++)
{
  options[m]=m;
  n=m;
}
//n=m;
options[n++]=0xfffff;
options[n++]=0x12;
options[n++]=0x34;
options[n++]=0x56;
options[n++]=0x78;
options[n++]=0x5d;
//options[2]=5;
for(int i=0;i<20;i++)
printf("%d\n",options[i]);
printf("options字段大小为:%d\n",n+1);
system("pause");
}

The options field enables DHCP messages to carry additional information. According to DHCP, the options field starts with a “magic cookie” value of “99.130.83.99” and consists of one or more subfields, each of which has a type-length-value (TLV) encoded substructure. In particular, specific options are identified by an 8-bit options tag field, an 8-bit length field, and a data field whose length is specified by the length field. DHCP messages are identified by option 53 . A listing of widely accepted options is identified by the IETF in the document entitled “DHCP Options and BOOTP Vendor Extensions,” RFC 2132, March 1997, which is incorporated by reference herein.

定义了一个函数:
void package29ID(UINT8 main, UINT8 slavep, UINT8 funcIDS, UINT8 sourID, UINT8 *data INT8 acks)


使用时调用:  package29ID(0x00,0x03,0x0E,0x20,SDate[],2,1); 报错: Error:  #29: expected an expression.


原来: 传入的SDate[]数组必须用 SDate表示才正确: package29ID(0x00,0x03,0x0E,0x20,SDate,2,1);

 

 

目标MAC为全1
原IP规定填为全0
目标IP填为子网广播IP——全1
终端发出的DHCP请求报文的UDP层中的原端口为68,目标端口DstPort为67。即DHCP SERVER通过知名端口号67来判断一个报文是否是DHCP报文。
Boot record type为1时表示是Client的请求,为2时表示是Server的应答。

HOPS跳数,表示当前的DHCP报文经过的DHCP RELAY(中级)的数目,每经过一个DHCP中继,此字段就会加1,当“hops”大于4(现在也有规定为16)时,这个DHCP报文就不能再进行处理,而是丢弃。

检查DHCP SERVER分配给自己的IP地址是否能够使用,如在以太网类型的网络中,CLIENT会发出一个ARP请求来确定DHCP SERVER分配的IP地址是否已经被别人使用,如果可以使用,则CLIENT成功获得IP地址


DHCP客户机初始化TCP/IP,通过UDP端口67向网络中发送一个DHCPDISCOVER广播包,请求租用IP地址。该广播包中的源IP地址为0.0.0.0,目标IP地址为255.255.255.255;包中还包含客户机的MAC地址和计算机名。
任何接收到DHCPDISCOVER广播包并且能够提供IP地址的DHCP服务器,都会通过UDP端口68给客户机回应一个DHCPOFFER广播包,提供一个IP地址。

会向网络发送一个DHCP request广播封包,告诉所有 DHCP 服务器它将指定接受哪一台服务器提供的 IP 地址。 同时,客户端还会向网络发送一个 ARP 封包,查询网络上面有没有其它机器使用该 IP 地址;如果发现该 IP 已经被占用,客户端则会送出一个 DHCPDECLIENT 封包给 DHCP 服务器,拒绝接受其 DHCP offer ,并重新发送 DHCP discover 信息。

所挑选的地址由DHCP客户机利用ARP 广播来确定自己所挑选的 IP 地址是否已被网络上的其它设备使用,如果该 IP 地址已被使用,那么客户机会再挑选另一个IP地址重新进行测试,而且最多可以重试十个IP 地址,直到成功获取配置。

DHCP原理
客户发出的IP租用请求报文

DHCP客户机初始化TCP/IP,通过UDP端口67向网络中发送一个DHCPDISCOVER广播包,请求租用IP地址。该 广播包中的源IP地址为0.0.0.0,目标IP地址为255.255.255.255;包中还包含客户机的MAC地址和计算机名。

DHCP回应的IP租用提供报文

任何接收到DHCPDISCOVER广播包并且能够提供IP地址的DHCP服务器,都会通过UDP端口68给客户机回应一个DHCPOFFER广播包,提供一个IP地址。该广播包的源IP地址为DCHP服务器IP,目标IP地址为255.255.255.255;包中还包含提供的IP地址、子网掩码及租期等信息。

客户选择IP租用报文

客户机从不止一台DHCP服务器接收到提供之后,会选择第一个收到的DHCPOFFER包,并向网络中广播一个 DHCPREQUEST消息包,表明自己已经接受了一个DHCP服务器提供的IP地址。该广播包中包含所接受的IP地址和服务器的IP地址。 所有其他的DHCP服务器撤消它们的提供以便将IP地址提供给下一次IP租用请求。

DHCP服务器发出IP租用确认报文

被客户机选择的DHCP服务器在收到DHCPREQUEST广播后,会广播返回给客户机一个DHCPACK消息包,表明已经接受客户机的选择,并将这一IP地址的合法租用以及其他的配置信息都放入该广播包发给客户机。

客户配置成功后发出的公告报文

客户机在收到DHCPACK包,会使用该广播包中的信息来配置自己的TCP/IP,则租用过程完成,客户机可以在网络中通信。

至此一个客户获取IP的DHCP服务过程基本结束,不过客户获取的IP一般是用租期,到期前需要更新租期,这个过程是通过租用更新数据包来完成的。

客户IP租用更新报文

 


任何接收到DHCPDISCOVER广播包并且能够提供IP地址的DHCP服务器,都会通过UDP端口68给客户机回应一个DHCPOFFER广播包,提供一个IP地址。该广播包的源IP地址为DCHP服务器IP,目标IP地址为255.255.255.255;包中还包含提供的IP地址、子网掩码及租期等信息。

 

 

 

http://en.wikipedia.org/wiki/DHCP

socket  udp  tcp 实现


名字解析器    gethostbyname()  对输入的名字进行查询,返回的结果包括IP地址和FQDN。

名字解析函数  gethostbyaddr()  将接收一个IP地址并返回对应主机的有关信息。反转这些字节和添加in-addr.arpa域均由该函数自动完成。


OP
  若是 client 送给 server 的封包,设为 1 ,反向为 2 。
  HTYPE
  硬体类别,Ethernet 为 1 。
  HLEN
  硬体位址长度, Ethernet 为 6 。
  HOPS
  若封包需经过 router 传送,每站加 1 ,若在同一网内,为 0 。
  TRANSACTION ID
  DHCPREQUEST 时产生的数值,以作 DHCPREPLY 时的依据。
  SECONDS
  Client 端启动时间(秒)。
  FLAGS
  从 0 到 15 共 16 bits ,最左一 bit 为 1 时表示 server 将以广播方式传送封包给 client ,其余尚未使用。
  ciaddr
  要是 client 端想继续使用之前取得之 IP 位址,则列于这里。
  yiaddr
  从 server 送回 client 之 DHCPOFFER 与 DHCPACK 封包中,此栏填写分配给 client 的 IP 位址。
  siaddr
  若 client 需要透过网路开机,从 server 送出之 DHCPOFFER、DHCPACK、DHCPNACK 封包中,此栏填写开机程式码所在 se


        op                         1     Message   op   code   /   message   type. 
                                          1   =   BOOTREQUEST,   2   =   BOOTREPLY 
        htype                   1     Hardware   address   type,   see   ARP   section   in   "Assigned 
                                          Numbers"   RFC;   e.g.,   '1'   =   10mb   ethernet. 
        hlen                     1     Hardware   address   length   (e.g.     '6'   for   10mb 
                                          ethernet). 
        hops                     1     Client   sets   to   zero,   optionally   used   by   relay   agents 
                                          when   booting   via   a   relay   agent. 
        xid                       4     Transaction   ID,   a   random   number   chosen   by   the 
                                          client,   used   by   the   client   and   server   to   associate 
                                          messages   and   responses   between   a   client   and   a 
                                          server. 
        secs                     2     Filled   in   by   client,   seconds   elapsed   since   client 
                                          began   address   acquisition   or   renewal   process. 
        flags                   2     Flags   (see   figure   2). 
        ciaddr                 4     Client   IP   address;   only   filled   in   if   client   is   in 
                                          BOUND,   RENEW   or   REBINDING   state   and   can   respond 
                                          to   ARP   requests. 
        yiaddr                 4     'your'   (client)   IP   address. 
        siaddr                 4     IP   address   of   next   server   to   use   in   bootstrap; 
                                          returned   in   DHCPOFFER,   DHCPACK   by   server. 
        giaddr                 4     Relay   agent   IP   address,   used   in   booting   via   a 
                                          relay   agent. 
        chaddr               16     Client   hardware   address. 
        sname                 64     Optional   server   host   name,   null   terminated   string. 
        file                 128     Boot   file   name,   null   terminated   string;   "generic" 
                                          name   or   null   in   DHCPDISCOVER,   fully   qualified 
                                          directory-path   name   in   DHCPOFFER. 
        options           var     Optional   parameters   field.     See   the   options 
                                          documents   for   a   list   of   defined   options. 
  
                            Description   of   fields   in   a   DHCP   message 
DHCP报文的各个字段的具体说明如下:

l              op:报文的操作类型,分为请求报文和响应报文,1为请求报文;2为响应报文。具体的报文类型在option字段中标识。

l              htype:硬件地址类型。

l              hlen:硬件地址长度。系统目前只对以太网支持,硬件地址长度固定为6。

l              hops:DHCP报文经过的DHCP中继的数目。DHCP请求报文每经过一个DHCP中继,该字段就会增加1。

l              xid:由客户端软件产生的随机数,用于匹配请求和应答报文。

l              secs:客户端进入IP地址申请进程的时间或者更新IP地址进程的时间;由客户端软件根据情况设定。目前没有使用,固定为0。

l              flags:标志字段。第一个比特为广播响应标识位,用来标识DHCP服务器响应报文是采用单播还是广播方式发送,0表示采用单播方式,1表示采用广播方式。其余比特保留不用。

l              ciaddr:DHCP客户端的IP地址。

l              yiaddr:DHCP服务器分配给客户端的IP地址。

l              siaddr:DHCP客户端获取IP地址等信息的服务器IP地址。

l              giaddr:DHCP客户端发出请求报文后经过的第一个DHCP中继的IP地址。

l              chaddr:DHCP客户端的硬件地址。

l              sname:DHCP客户端获取IP地址等信息的服务器名称。

l              file:DHCP服务器为DHCP客户端指定的启动配置文件名称及路径信息。

l              options:可选变长选项字段,包含报文的类型、有效租期、DNS服务器的IP地址、WINS服务器的IP地址等配置信息。

 

 

Ack

Bootstrap Protocol

    Message type: Boot Reply (2)消息类型:引导回复(2)

    Hardware type: Ethernet

    Hardware address length: 6

    Hops: 0

    Transaction ID: 0x8407dd3e

    Seconds elapsed: 0

    Bootp flags: 0x0000 (Unicast)

        0... .... .... .... = Broadcast flag: Unicast

        .000 0000 0000 0000 = Reserved flags: 0x0000

    Client IP address: 0.0.0.0 (0.0.0.0)

    Your (client) IP address: 172.16.77.246 (172.16.77.246)你的IP

    Next server IP address: 172.16.77.213 (172.16.77.213)服务器IP

    Relay agent IP address: 0.0.0.0 (0.0.0.0)

    Client MAC address: AsustekC_97:2a:ee (00:13:d4:97:2a:ee)

    Server host name not given

    Boot file name not given

    Magic cookie: (OK)

    Option: (t=53,l=1) DHCP Message Type = DHCP ACK DHCP消息类型=DHCP确认

        Option: (53) DHCP Message Type

        Length: 1

        Value: 05

    Option: (t=54,l=4) Server Identifier = 172.16.77.213服务器识别地址

        Option: (54) Server Identifier

       Length: 4

        Value: AC104DD5

    Option: (t=51,l=4) IP Address Lease Time = 6 hours 租用时间:6小时

        Option: (51) IP Address Lease Time

        Length: 4

        Value: 00005460

    Option: (t=1,l=4) Subnet Mask = 255.255.255.0子多掩码

        Option: (1) Subnet Mask

        Length: 4

        Value: FFFFFF00

    Option: (t=15,l=8) Domain Name = "Amber.cn"域名

        Option: (15) Domain Name

        Length: 8

        Value: 416D6265722E636E

    Option: (t=3,l=4) Router = 172.16.77.254路由器地址

        Option: (3) Router

        Length: 4

        Value: AC104DFE

    Option: (t=6,l=4) Domain Name Server = 172.16.77.213域名服务器

        Option: (6) Domain Name Server

        Length: 4

        Value: AC104DD5

    End Option

    Padding

 

linux用指令来设置IP,MASK,GATEWAY:

//终端指令实现

//ifconfig eth0 192.168.0.0 netmask 255.255.0.0

//route add default gw 10.240.0.0

//C代码实现

char IP[24] = "192.168.1.0";

char Mask[24] = "255.255.0.0“;

char gateway[24] = "10.240.0.0";

char cmd_IP_Mask[64] = {0};

char cmd_GW[64] = {0};

sprintf(cmd_IP_Mask, "ifconfig eth0 %s netmask %s", IP, Mask);

sprintf(cmd_GW, "route add default gw %s netmask %s", gateway);


unsigned int IP_Address = inet_addr(IP),将点间隔的IP地址转换成长整形的数据

将长整形的IP地址以点阵形式输出:

printf("GetHostIp:IP...%s\n",inet_ntoa( IP_Address ));

 

 

//如果应用传入的是长整形的ip ,mask ,gw,用以下C代码来实现转换---可以直接拿来用的,已经测试通过

#define SIN_ADDR(x) (((struct sockaddr_in *) (&(x)))->sin_addr.s_addr)
#define SET_SA_FAMILY(addr, family) \
    memset((char*)&(addr), '\0',   sizeof(addr)); \
    addr.sa_family = (family)

char ipaddr[20];
char netmask[20];
char gateway[20];

sprintf(ipaddr, "%d.%d.%d.%d", (ip&0xff000000)>>24, (ip&0xff0000)>>16, (ip&0xff00)>>8, (ip&0xff));
sprintf(netmask, "%d.%d.%d.%d", (mask&0xff000000)>>24, (mask&0xff0000)>>16, (mask&0xff00)>>8,   (mask&0xff));
sprintf(gateway, "%d.%d.%d.%d", (gw&0xff000000)>>24, (gw&0xff0000)>>16, (gw&0xff00)>>8,   (gw&0xff));

static int set_ipaddr(char *ipaddr)
{
    int s;

    if((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    {
       return FAIL;
    }

    struct ifreq ifr;
    bzero((char *)&ifr, sizeof(ifr));
    strcpy(ifr.ifr_name,"eth0");

    struct sockaddr_in addr;
    bzero(&addr, sizeof(struct sockaddr_in));
    addr.sin_family = AF_INET;
    inet_aton(ipaddr,&addr.sin_addr);//将输入字符转成网络地址

    memcpy((char*)&ifr.ifr_ifru.ifru_addr, (char*)&addr, sizeof(struct sockaddr_in));
    if(ioctl(s, SIOCSIFADDR, &ifr) < 0)
    {
       close(s);
       return FAIL;
    }
    close(s);
    return OK;
}

static int set_netmask(char *netmask)
{
    int s;
    if((s = socket(AF_INET,SOCK_DGRAM, 0)) < 0)
    {
        KK_ERROR("[set_netmask]create socket failed:line:%d\n",__LINE__);
        return FAIL;
    }

    struct ifreq ifr;
    bzero((char *)&ifr, sizeof(ifr));
    strcpy(ifr.ifr_name,"eth0");

    struct sockaddr_in netmask_addr;
    bzero(&netmask_addr, sizeof(struct sockaddr_in));
    netmask_addr.sin_family = AF_INET;
    inet_aton(netmask, &netmask_addr.sin_addr);

    memcpy((char*)&ifr.ifr_ifru.ifru_netmask, (char*)&netmask_addr, sizeof(struct sockaddr_in));
    if(ioctl(s,SIOCSIFNETMASK,&ifr) < 0)
    {
        close(s);
        KK_ERROR("[set_netmask]ioctl failed:line:%d\n",__LINE__);
        return FAIL;
    }
    close(s);
    return OK;
}

static int set_gateway(char *gateway)
{
    static int sock_fd = -1;
    struct rtentry rt;
    U32 dstaddr, gwaddr;

    dstaddr = inet_addr("0.0.0.0");
    gwaddr = inet_addr(gateway);

    /* Get an internet socket for doing socket ioctls. */
    sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
    memset(&rt, 0, sizeof(rt));

    /*set Destination addr*/
    SET_SA_FAMILY (rt.rt_dst, AF_INET);
    SIN_ADDR(rt.rt_dst) = dstaddr;

    /*set gw addr*/
    SET_SA_FAMILY (rt.rt_gateway, AF_INET);
    SIN_ADDR(rt.rt_gateway) = gwaddr;

    /*set genmask addr*/
    SET_SA_FAMILY (rt.rt_genmask, AF_INET);
    SIN_ADDR(rt.rt_genmask) = 0L;
    rt.rt_dev = "eth0";
    rt.rt_flags = RTF_GATEWAY;
    if(ioctl(sock_fd, SIOCADDRT, &rt) < 0)
    {
       close(sock_fd);
       KK_ERROR("[set_gateway]ioctl failed:line:%d\n",__LINE__);       
       return FAIL;
    }
    return OK;
}

 

 

 

 

Offer

Bootstrap Protocol

    Message type: Boot Reply (2)消息类型:引导回复(2)

    Hardware type: Ethernet

    Hardware address length: 6

    Hops: 0

    Transaction ID: 0x8407dd3e

    Seconds elapsed: 0

    Bootp flags: 0x0000 (Unicast)

        0... .... .... .... = Broadcast flag: Unicast

        .000 0000 0000 0000 = Reserved flags: 0x0000

    Client IP address: 0.0.0.0 (0.0.0.0) 你的IP

    Your (client) IP address: 172.16.77.246 (172.16.77.246)客户端被提供的IP

    Next server IP address: 172.16.77.213 (172.16.77.213)服务器IP

    Relay agent IP address: 0.0.0.0 (0.0.0.0)

    Client MAC address: AsustekC_97:2a:ee (00:13:d4:97:2a:ee)

    Server host name not given

    Boot file name not given

    Magic cookie: (OK)

    Option: (t=53,l=1) DHCP Message Type = DHCP Offer 选项:DHCP消息类型=DHCP提供

        Option: (53) DHCP Message Type

        Length: 1

        Value: 02

    Option: (t=54,l=4) Server Identifier = 172.16.77.213

        Option: (54) Server Identifier

        Length: 4

        Value: AC104DD5

    Option: (t=51,l=4) IP Address Lease Time = 6 hours

        Option: (51) IP Address Lease Time

        Length: 4

        Value: 00005460

    Option: (t=1,l=4) Subnet Mask = 255.255.255.0

        Option: (1) Subnet Mask

        Length: 4

        Value: FFFFFF00

    Option: (t=15,l=8) Domain Name = "Amber.cn"

        Option: (15) Domain Name

        Length: 8

        Value: 416D6265722E636E

    Option: (t=3,l=4) Router = 172.16.77.254

        Option: (3) Router

        Length: 4

        Value: AC104DFE

    Option: (t=6,l=4) Domain Name Server = 172.16.77.213

        Option: (6) Domain Name Server

        Length: 4

        Value: AC104DD5

    End Option

    Padding

 


 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值