|
Functions | |
| __STATIC __VOID | __dhcpSetState (__PDHCP dhcp, u8 state) |
| Sets a new state for the internal DHCP state machine. | |
| __STATIC __BOOL | __dhcpOpenSocket (__PDHCP dhcp) |
| Creates a socket for communicating with the the DHCP server. | |
| __STATIC __VOID | __dhcpCloseSocket (__PDHCP dhcp) |
| Closes the DHCP socket. | |
| __STATIC i32 | __dhcpSendBootp (__PSOCKET sock, u32 addr, __PDHCP_BOOTP bootp, u16 opt_len) |
Sends a BOOTP packet through UDP socket sock. | |
| __STATIC u16 | __dhcpPrepareBootp (__PDHCP_BOOTP bootp, u8 msgtype, u32 xid, u8 *mac, u32 ciaddr, u16 sec) |
| Prepares a __DHCP_BOOTP structure for transmission. | |
| __STATIC i32 | __dhcpSendDiscover (__PNETIF netif) |
Broadcasts a discover packet from the Network Interface netif. | |
| __STATIC __VOID | __dhcpWait (__PDHCP dhcp, u8 next_state, u8 wait) |
| Moves the DHCP state machine to the wait state and waits there for a timeout. | |
| __STATIC i32 | __dhcpRecvBootp (__PDHCP dhcp) |
Reads a BOOTP packet from the dhcp structure socket. | |
| __STATIC u8 | __dhcpGetMsgIdFromBootp (__PDHCP_BOOTP bootp) |
| Retrieves the message ID from a received BOOTP structure. | |
| __STATIC __BOOL | __dhcpProcessAck (__PNETIF netif, __PDHCP dhcp) |
| Processes an incoming ACK message. | |
| __STATIC __BOOL | __dhcpProcessOffer (__PNETIF netif, __PDHCP dhcp) |
| Process an incoming DHCP offer message. | |
| __STATIC __BOOL | __dhcpRenew (__PNETIF netif, __PDHCP dhcp, u32 serv_addr) |
| Sends a request message intended to renew the DHCP leasing. | |
| __STATIC __VOID | __dhcpReceiveAck (__PNETIF netif, __PDHCP dhcp, u8 success_state, u8 fail_state) |
| Receives for an ACK response from the DHCP server. | |
| __STATIC __VOID __dhcpSetState | ( | __PDHCP | dhcp, |
| u8 | state | ||
| ) |
Sets a new state for the internal DHCP state machine.
Other than setting the new state, this function can output the new state to the debug terminal. Depends on the debug constants in the net.h file.
| dhcp | Pointer to a __DHCP structure. |
| state | The new state. A list can be found at States. |
Definition at line 234 of file dhcp.c.
{
dhcp->state = state;
#if __NET_DEBUG_DHCP
NETOUT(__NET_DEBUG_DHCP, ("[DHCP] new state: "));
switch (state)
{
case __DHCP_STATE_IDLE:
NETMSG(__NET_DEBUG_DHCP, ("IDLE"));
break;
case __DHCP_STATE_INIT:
NETMSG(__NET_DEBUG_DHCP, ("INIT"));
break;
case __DHCP_STATE_SELECTING:
NETMSG(__NET_DEBUG_DHCP, ("SELECTING"));
break;
case __DHCP_STATE_REQUESTING:
NETMSG(__NET_DEBUG_DHCP, ("REQUESTING"));
break;
case __DHCP_STATE_INIT_REBOOT:
NETMSG(__NET_DEBUG_DHCP, ("REBOOT"));
break;
case __DHCP_STATE_REBOOTING:
NETMSG(__NET_DEBUG_DHCP, ("REBOOTING"));
break;
case __DHCP_STATE_BOUND:
NETMSG(__NET_DEBUG_DHCP, ("BOUND"));
break;
case __DHCP_STATE_RENEWING:
NETMSG(__NET_DEBUG_DHCP, ("RENEWING"));
break;
case __DHCP_STATE_REBINDING:
NETMSG(__NET_DEBUG_DHCP, ("REBINDING"));
break;
case __DHCP_STATE_WAIT:
NETMSG(__NET_DEBUG_DHCP, ("WAIT"));
break;
}
#endif /* __NET_DEBUG_DHCP */
}
| __STATIC __BOOL __dhcpOpenSocket | ( | __PDHCP | dhcp | ) |
Creates a socket for communicating with the the DHCP server.
The socket will only be created if the sock member of the __DHCP structure is __NULL.
| dhcp | Pointer to a __DHCP structure. |
Definition at line 289 of file dhcp.c.
{
if (!dhcp->sock)
{
dhcp->sock = __socketCreate(__SOCK_TYPE_UDP, __DHCP_CLIENT_PORT);
if (!dhcp->sock) return __FALSE;
}
return __TRUE;
}

| __STATIC __VOID __dhcpCloseSocket | ( | __PDHCP | dhcp | ) |
Closes the DHCP socket.
This function will also destroy the socket.
| dhcp | Pointer to a __DHCP structure. |
Definition at line 310 of file dhcp.c.
{
__socketClose(dhcp->sock);
__socketDestroy(dhcp->sock);
dhcp->sock = __NULL;
}

| __STATIC i32 __dhcpSendBootp | ( | __PSOCKET | sock, |
| u32 | addr, | ||
| __PDHCP_BOOTP | bootp, | ||
| u16 | opt_len | ||
| ) |
Sends a BOOTP packet through UDP socket sock.
| sock | Socket used for the transmission. |
| addr | DHCP server address (in NBO). |
| bootp | Pointer to a __DHCP_BOOTP structure to be sent. |
| opt_len | The length of the options field of the bootp structure. |
Definition at line 328 of file dhcp.c.
{
u16 len;
bootp->options[opt_len++] = 0xFF;
len = sizeof(__DHCP_BOOTP) - sizeof(bootp->options) + opt_len;
if (len < 300) len = 300;
if (__socketSendTo(sock, addr, __DHCP_SERVER_PORT, bootp, len) == len)
{
return 0;
}
return -1;
}

| __STATIC u16 __dhcpPrepareBootp | ( | __PDHCP_BOOTP | bootp, |
| u8 | msgtype, | ||
| u32 | xid, | ||
| u8 * | mac, | ||
| u32 | ciaddr, | ||
| u16 | sec | ||
| ) |
Prepares a __DHCP_BOOTP structure for transmission.
| bootp | Pointer to a __DHCP_BOOTP structure to be filled. |
| msgtype | Type of message (parameter in the options field). |
| xid | Transaction ID to be used. |
| mac | 6 bytes length MAC address of the source (local network interface MAC address). |
| ciaddr | Client address (local address) in NBO. |
| sec | Seconds from the start of the leasing. |
options field of the __DHCP_BOOTP structure. Definition at line 358 of file dhcp.c.
{
u8 values[3] = {1,3,6};
u8* options;
u16 len = 0;
u16 val;
bootp->op = 1;
bootp->hw_addr_type = 1;
bootp->hw_addr_len = 6;
bootp->hops = 0;
bootp->xid = xid;
bootp->secs = sec;
bootp->flags = __htons(0x8000); /* TODO check if needed */
__memCpy(bootp->chaddr, mac, 6);
options = bootp->options;
/* Magic cookie */
*(options++) = 0x63;
*(options++) = 0x82;
*(options++) = 0x53;
*(options++) = 0x63;
len = 4;
/* Message type */
__dhcpAdd8bitOption(options, __DHCP_OPT_MSGTYPE, msgtype, len);
/* Data requested from DHCP server */
__dhcpAddOption(options, __DHCP_OPT_PARAMSREQUEST, 3, values, len);
/* Hostname TODO take the value from somewhere else */
__dhcpAddOption(options, __DHCP_OPT_HOSTNAME, 5, (u8*) "milos", len);
/* Max. DHCP message size we will accept */
val = 576;
__dhcpAdd16bitOption(options, __DHCP_OPT_MAXMSGSIZE, val, len);
return len;
}

| __STATIC i32 __dhcpSendDiscover | ( | __PNETIF | netif | ) |
Broadcasts a discover packet from the Network Interface netif.
| netif | Pointer to a Network Interface. |
Definition at line 407 of file dhcp.c.
{
__PDHCP dhcp = (__PDHCP) netif->dhcp;
__PDHCP_BOOTP bootp;
u16 len = 0;
if (!__dhcpOpenSocket(dhcp)) return -1;
if (dhcp->bootp == __NULL)
{
dhcp->bootp = __heapAlloc(sizeof(__DHCP_BOOTP));
if (!dhcp->bootp)
{
__dhcpCloseSocket(dhcp);
return -1;
}
}
__memSet(dhcp->bootp, 0, sizeof(__DHCP_BOOTP));
__dhcpRenewXid(dhcp);
bootp = dhcp->bootp;
len = __dhcpPrepareBootp(bootp, __DHCP_MSGTYPE_DISCOVER, dhcp->xid, netif->addr.type.mac, 0, 0);
return __dhcpSendBootp(dhcp->sock, 0xFFFFFFFF, bootp, len);
}

| __STATIC __VOID __dhcpWait | ( | __PDHCP | dhcp, |
| u8 | next_state, | ||
| u8 | wait | ||
| ) |
Moves the DHCP state machine to the wait state and waits there for a timeout.
| dhcp | Pointer to a __DHCP structure. |
| next_state | State to transit after the waiting time expires. |
| wait | Time to wait (in seconds). |
Definition at line 445 of file dhcp.c.
{
__dhcpSetState(dhcp, __DHCP_STATE_WAIT);
dhcp->next_state = next_state;
dhcp->timer = __systemGetSecondsCount();
dhcp->wait = wait;
}

| __STATIC i32 __dhcpRecvBootp | ( | __PDHCP | dhcp | ) |
Reads a BOOTP packet from the dhcp structure socket.
| dhcp | Pointer to a dhcp structure containing a socket to read the BOOTP packet from. |
Definition at line 462 of file dhcp.c.
{
u32 addr;
u16 port;
i32 ret;
if (!__dhcpOpenSocket(dhcp)) return -1;
if (dhcp->bootp == __NULL)
{
dhcp->bootp = __heapAlloc(sizeof(__DHCP_BOOTP));
if (!dhcp->bootp) return -1;
}
__memSet(dhcp->bootp, 0, sizeof(__DHCP_BOOTP));
ret = __socketRecvFrom(dhcp->sock, &addr, &port, dhcp->bootp, sizeof(__DHCP_BOOTP));
if (ret > 0)
{
/* Check for (at least) the size of a BOOTP structure plus 4 byte for
* the magic cookie plus 1 byte for the termination 0xFF */
if (ret > sizeof(__DHCP_BOOTP) - sizeof(dhcp->bootp->options) + 4 + 1)
{
/* Packet should be OK */
return 0;
}
}
return -1;
}

| __STATIC u8 __dhcpGetMsgIdFromBootp | ( | __PDHCP_BOOTP | bootp | ) |
Retrieves the message ID from a received BOOTP structure.
| bootp | Pointer to a __DHCP_BOOTP structure. |
options field. Definition at line 501 of file dhcp.c.
{
u8* options;
u32 len;
options = bootp->options;
options += 4;
len = sizeof(bootp->options);
while (*options != __DHCP_OPT_END && len--)
{
if (*(options+1) > len) return __FALSE;
switch (*options)
{
/* Message type */
case __DHCP_OPT_MSGTYPE:
/* Check size */
if (*(++options) != 1) return __FALSE;
return (*(++options));
}
}
return 0;
}
| __STATIC __BOOL __dhcpProcessAck | ( | __PNETIF | netif, |
| __PDHCP | dhcp | ||
| ) |
Processes an incoming ACK message.
| netif | Pointer to a Network Interface. |
| dhcp | Pointer to a __DHCP structure. |
Definition at line 535 of file dhcp.c.
{
u32 ip = dhcp->bootp->yiaddr;
u32 gw;
u32 dns;
u32 mask;
u8* options;
u32 len;
dns = gw = mask = 0;
options = dhcp->bootp->options;
options += 4;
len = sizeof(dhcp->bootp->options);
__memSet(&dhcp->lease, 0, sizeof(__DHCP_LEASE));
while (*options != __DHCP_OPT_END && len--)
{
if (*(options+1) > len) return __FALSE;
switch (*options)
{
/* DNS */
case __DHCP_OPT_DNS:
/* Check size */
if (*(++options) != 4) return __FALSE;
__memCpy(&dns, ++options, 4);
options += 4;
break;
/* Gateway */
case __DHCP_OPT_GATEWAY:
/* Check size */
if (*(++options) != 4) return __FALSE;
__memCpy(&gw, ++options, 4);
options += 4;
break;
/* Network mask */
case __DHCP_OPT_NETMASK:
/* Check size */
if (*(++options) != 4) return __FALSE;
__memCpy(&mask, ++options, 4);
options += 4;
break;
case __DHCP_OPT_LEASETIME:
/* Check size */
if (*(++options) != 4) return __FALSE;
__memCpy(&dhcp->lease.lease, ++options, 4);
options += 4;
dhcp->lease.lease = __ntohl(dhcp->lease.lease);
break;
case __DHCP_OPT_RENEWALTIME:
if (*(++options) != 4) return __FALSE;
__memCpy(&dhcp->lease.renewal, ++options, 4);
options += 4;
dhcp->lease.renewal = __ntohl(dhcp->lease.renewal);
break;
case __DHCP_OPT_REBINDTIME:
if (*(++options) != 4) return __FALSE;
__memCpy(&dhcp->lease.rebind, ++options, 4);
options += 4;
dhcp->lease.rebind = __ntohl(dhcp->lease.rebind);
break;
default:
++options;
options += *options;
++options;
break;
}
}
if (dhcp->lease.lease == 0)
dhcp->lease.lease = __DHCP_DEFAULT_LEASE_TIME;
if (dhcp->lease.renewal == 0)
dhcp->lease.renewal = dhcp->lease.lease / 2;
if (dhcp->lease.rebind == 0)
dhcp->lease.rebind = (dhcp->lease.lease - ((dhcp->lease.renewal / 2) / 2));
dhcp->lease.curr_timer = __systemGetSecondsCount();
netif->ip = ip;
netif->mask = mask;
netif->dns1 = dns;
netif->gateway = gw;
__routeAdd(netif, 0, 0, netif->gateway);
__routeAdd(netif, netif->ip, netif->mask, 0);
__dhcpCloseSocket(dhcp);
__heapFree(dhcp->bootp);
dhcp->bootp = __NULL;
return __TRUE;
}

| __STATIC __BOOL __dhcpProcessOffer | ( | __PNETIF | netif, |
| __PDHCP | dhcp | ||
| ) |
Process an incoming DHCP offer message.
This function will send a request packet to the DHCP server if the offer is valid.
| netif | Pointer to a Network Interface. |
| dhcp | Pointer to a __DHCP structure. |
Definition at line 652 of file dhcp.c.
{
u32 ouraddr = __ntohl(dhcp->bootp->yiaddr);
u32 servaddr = __ntohl(dhcp->bootp->siaddr);
u32 len;
i32 ret;
u8* options;
/* Don't get too greedy. By now just accept the first offer. */
__memSet(dhcp->bootp, 0, sizeof(__DHCP_BOOTP));
len = __dhcpPrepareBootp(dhcp->bootp, __DHCP_MSGTYPE_REQUEST, dhcp->xid, netif->addr.type.mac, 0, 0);
options = dhcp->bootp->options + len;
__dhcpAdd32bitOption(options, __DHCP_OPT_SID, servaddr, len);
__dhcpAdd32bitOption(options, __DHCP_OPT_REQIP, ouraddr, len);
ret = __dhcpSendBootp(dhcp->sock, 0xFFFFFFFF, dhcp->bootp, len);
return (ret == 0) ? __TRUE : __FALSE;
}

| __STATIC __BOOL __dhcpRenew | ( | __PNETIF | netif, |
| __PDHCP | dhcp, | ||
| u32 | serv_addr | ||
| ) |
Sends a request message intended to renew the DHCP leasing.
| netif | Pointer to a network interface. |
| dhcp | Pointer to a __DHCP structure. |
| serv_addr | Address of the DHCP server (in NBO). |
Definition at line 684 of file dhcp.c.
{
u32 ouraddr = netif->ip;
u32 servaddr = serv_addr;
u32 len;
i32 ret;
if (!__dhcpOpenSocket(dhcp)) return __FALSE;
if (dhcp->bootp == __NULL)
{
dhcp->bootp = __heapAllocZero(sizeof(__DHCP_BOOTP));
if (!dhcp->bootp) return __FALSE;
}
__dhcpRenewXid(dhcp);
len = __dhcpPrepareBootp(dhcp->bootp, __DHCP_MSGTYPE_REQUEST, dhcp->xid, netif->addr.type.mac, 0, 0);
dhcp->bootp->ciaddr = ouraddr;
ret = __dhcpSendBootp(dhcp->sock, servaddr, dhcp->bootp, len);
return (ret == 0) ? __TRUE : __FALSE;
}

| __STATIC __VOID __dhcpReceiveAck | ( | __PNETIF | netif, |
| __PDHCP | dhcp, | ||
| u8 | success_state, | ||
| u8 | fail_state | ||
| ) |
Receives for an ACK response from the DHCP server.
| netif | Pointer to a network interface. |
| dhcp | Pointer to a __DHCP structure. |
| success_state | On ACK, the state to transit after validation. |
| fail_state | On NAK, the state to transit. |
Definition at line 720 of file dhcp.c.
{
/* Read bootp from socket */
if (__dhcpRecvBootp(dhcp) == 0)
{
/* Check for BOOTP == REPLY and same XID */
if (dhcp->bootp->op == 2 && dhcp->bootp->xid == dhcp->xid)
{
/* If msg id == ACK */
if (__dhcpGetMsgIdFromBootp(dhcp->bootp) == __DHCP_MSGTYPE_ACK)
{
NETMSG(__NET_DEBUG_DHCP, ("[DHCP] ACK received"));
if (__dhcpProcessAck(netif, dhcp))
{
__dhcpSetState(dhcp, success_state);
}
} else if (__dhcpGetMsgIdFromBootp(dhcp->bootp) == __DHCP_MSGTYPE_NAK)
{
NETMSG(__NET_DEBUG_DHCP, ("[DHCP] NAK received"));
__dhcpWait(dhcp, fail_state, 1);
}
}
}
}
