mirror of
https://github.com/reactos/reactos.git
synced 2025-05-31 23:18:39 +00:00
[lwIP]
- Upgrade to the latest version of lwIP (1.40) svn path=/branches/GSoC_2011/TcpIpDriver/; revision=52655
This commit is contained in:
parent
b5a8722b5e
commit
11a025ade9
62 changed files with 3028 additions and 2728 deletions
|
@ -240,6 +240,7 @@ netconn_disconnect(struct netconn *conn)
|
|||
err_t
|
||||
netconn_listen_with_backlog(struct netconn *conn, u8_t backlog)
|
||||
{
|
||||
#if LWIP_TCP
|
||||
struct api_msg msg;
|
||||
err_t err;
|
||||
|
||||
|
@ -257,6 +258,11 @@ netconn_listen_with_backlog(struct netconn *conn, u8_t backlog)
|
|||
|
||||
NETCONN_SET_SAFE_ERR(conn, err);
|
||||
return err;
|
||||
#else /* LWIP_TCP */
|
||||
LWIP_UNUSED_ARG(conn);
|
||||
LWIP_UNUSED_ARG(backlog);
|
||||
return ERR_ARG;
|
||||
#endif /* LWIP_TCP */
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -301,9 +307,9 @@ netconn_accept(struct netconn *conn, struct netconn **new_conn)
|
|||
API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0);
|
||||
|
||||
if (newconn == NULL) {
|
||||
/* connection has been closed */
|
||||
NETCONN_SET_SAFE_ERR(conn, ERR_CLSD);
|
||||
return ERR_CLSD;
|
||||
/* connection has been aborted */
|
||||
NETCONN_SET_SAFE_ERR(conn, ERR_ABRT);
|
||||
return ERR_ABRT;
|
||||
}
|
||||
#if TCP_LISTEN_BACKLOG
|
||||
/* Let the stack know that we have accepted the connection. */
|
||||
|
@ -402,7 +408,9 @@ netconn_recv_data(struct netconn *conn, void **new_buf)
|
|||
}
|
||||
#endif /* (LWIP_UDP || LWIP_RAW) */
|
||||
|
||||
#if LWIP_SO_RCVBUF
|
||||
SYS_ARCH_DEC(conn->recv_avail, len);
|
||||
#endif /* LWIP_SO_RCVBUF */
|
||||
/* Register event with callback */
|
||||
API_EVENT(conn, NETCONN_EVT_RCVMINUS, len);
|
||||
|
||||
|
@ -499,6 +507,7 @@ netconn_recv(struct netconn *conn, struct netbuf **new_buf)
|
|||
void
|
||||
netconn_recved(struct netconn *conn, u32_t length)
|
||||
{
|
||||
#if LWIP_TCP
|
||||
if ((conn != NULL) && (conn->type == NETCONN_TCP) &&
|
||||
(netconn_get_noautorecved(conn))) {
|
||||
struct api_msg msg;
|
||||
|
@ -511,6 +520,10 @@ netconn_recved(struct netconn *conn, u32_t length)
|
|||
/* don't care for the return value of do_recv */
|
||||
TCPIP_APIMSG(&msg);
|
||||
}
|
||||
#else /* LWIP_TCP */
|
||||
LWIP_UNUSED_ARG(conn);
|
||||
LWIP_UNUSED_ARG(length);
|
||||
#endif /* LWIP_TCP */
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -120,7 +120,9 @@ recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p,
|
|||
netbuf_delete(buf);
|
||||
return 0;
|
||||
} else {
|
||||
#if LWIP_SO_RCVBUF
|
||||
SYS_ARCH_INC(conn->recv_avail, len);
|
||||
#endif /* LWIP_SO_RCVBUF */
|
||||
/* Register event with callback */
|
||||
API_EVENT(conn, NETCONN_EVT_RCVPLUS, len);
|
||||
}
|
||||
|
@ -194,7 +196,9 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
|
|||
netbuf_delete(buf);
|
||||
return;
|
||||
} else {
|
||||
#if LWIP_SO_RCVBUF
|
||||
SYS_ARCH_INC(conn->recv_avail, len);
|
||||
#endif /* LWIP_SO_RCVBUF */
|
||||
/* Register event with callback */
|
||||
API_EVENT(conn, NETCONN_EVT_RCVPLUS, len);
|
||||
}
|
||||
|
@ -248,7 +252,9 @@ recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
|
|||
/* don't deallocate p: it is presented to us later again from tcp_fasttmr! */
|
||||
return ERR_MEM;
|
||||
} else {
|
||||
#if LWIP_SO_RCVBUF
|
||||
SYS_ARCH_INC(conn->recv_avail, len);
|
||||
#endif /* LWIP_SO_RCVBUF */
|
||||
/* Register event with callback */
|
||||
API_EVENT(conn, NETCONN_EVT_RCVPLUS, len);
|
||||
}
|
||||
|
@ -614,7 +620,6 @@ netconn_alloc(enum netconn_type t, netconn_callback callback)
|
|||
conn->socket = -1;
|
||||
#endif /* LWIP_SOCKET */
|
||||
conn->callback = callback;
|
||||
conn->recv_avail = 0;
|
||||
#if LWIP_TCP
|
||||
conn->current_msg = NULL;
|
||||
conn->write_offset = 0;
|
||||
|
@ -624,6 +629,7 @@ netconn_alloc(enum netconn_type t, netconn_callback callback)
|
|||
#endif /* LWIP_SO_RCVTIMEO */
|
||||
#if LWIP_SO_RCVBUF
|
||||
conn->recv_bufsize = RECV_BUFSIZE_DEFAULT;
|
||||
conn->recv_avail = 0;
|
||||
#endif /* LWIP_SO_RCVBUF */
|
||||
conn->flags = 0;
|
||||
return conn;
|
||||
|
@ -944,12 +950,7 @@ do_connected(void *arg, struct tcp_pcb *pcb, err_t err)
|
|||
conn->current_msg = NULL;
|
||||
conn->state = NETCONN_NONE;
|
||||
if (!was_blocking) {
|
||||
SYS_ARCH_DECL_PROTECT(lev);
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
if (conn->last_err == ERR_INPROGRESS) {
|
||||
conn->last_err = ERR_OK;
|
||||
}
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
NETCONN_SET_SAFE_ERR(conn, ERR_OK);
|
||||
}
|
||||
API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
|
||||
|
||||
|
@ -1040,6 +1041,7 @@ do_disconnect(struct api_msg_msg *msg)
|
|||
TCPIP_APIMSG_ACK(msg);
|
||||
}
|
||||
|
||||
#if LWIP_TCP
|
||||
/**
|
||||
* Set a TCP pcb contained in a netconn into listen mode
|
||||
* Called from netconn_listen.
|
||||
|
@ -1049,7 +1051,6 @@ do_disconnect(struct api_msg_msg *msg)
|
|||
void
|
||||
do_listen(struct api_msg_msg *msg)
|
||||
{
|
||||
#if LWIP_TCP
|
||||
if (ERR_IS_FATAL(msg->conn->last_err)) {
|
||||
msg->err = msg->conn->last_err;
|
||||
} else {
|
||||
|
@ -1091,9 +1092,9 @@ do_listen(struct api_msg_msg *msg)
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif /* LWIP_TCP */
|
||||
TCPIP_APIMSG_ACK(msg);
|
||||
}
|
||||
#endif /* LWIP_TCP */
|
||||
|
||||
/**
|
||||
* Send some data on a RAW or UDP pcb contained in a netconn
|
||||
|
@ -1147,6 +1148,7 @@ do_send(struct api_msg_msg *msg)
|
|||
TCPIP_APIMSG_ACK(msg);
|
||||
}
|
||||
|
||||
#if LWIP_TCP
|
||||
/**
|
||||
* Indicate data has been received from a TCP pcb contained in a netconn
|
||||
* Called from netconn_recv
|
||||
|
@ -1156,7 +1158,6 @@ do_send(struct api_msg_msg *msg)
|
|||
void
|
||||
do_recv(struct api_msg_msg *msg)
|
||||
{
|
||||
#if LWIP_TCP
|
||||
msg->err = ERR_OK;
|
||||
if (msg->conn->pcb.tcp != NULL) {
|
||||
if (msg->conn->type == NETCONN_TCP) {
|
||||
|
@ -1175,11 +1176,9 @@ do_recv(struct api_msg_msg *msg)
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif /* LWIP_TCP */
|
||||
TCPIP_APIMSG_ACK(msg);
|
||||
}
|
||||
|
||||
#if LWIP_TCP
|
||||
/**
|
||||
* See if more data needs to be written from a previous call to netconn_write.
|
||||
* Called initially from do_write. If the first call can't send all data
|
||||
|
|
|
@ -49,14 +49,14 @@ static const char *err_strerr[] = {
|
|||
"Operation in progress.", /* ERR_INPROGRESS -5 */
|
||||
"Illegal value.", /* ERR_VAL -6 */
|
||||
"Operation would block.", /* ERR_WOULDBLOCK -7 */
|
||||
"Connection aborted.", /* ERR_ABRT -8 */
|
||||
"Connection reset.", /* ERR_RST -9 */
|
||||
"Connection closed.", /* ERR_CLSD -10 */
|
||||
"Not connected.", /* ERR_CONN -11 */
|
||||
"Illegal argument.", /* ERR_ARG -12 */
|
||||
"Address in use.", /* ERR_USE -13 */
|
||||
"Low-level netif error.", /* ERR_IF -14 */
|
||||
"Already connected.", /* ERR_ISCONN -15 */
|
||||
"Address in use.", /* ERR_USE -8 */
|
||||
"Already connected.", /* ERR_ISCONN -9 */
|
||||
"Connection aborted.", /* ERR_ABRT -10 */
|
||||
"Connection reset.", /* ERR_RST -11 */
|
||||
"Connection closed.", /* ERR_CLSD -12 */
|
||||
"Not connected.", /* ERR_CONN -13 */
|
||||
"Illegal argument.", /* ERR_ARG -14 */
|
||||
"Low-level netif error.", /* ERR_IF -15 */
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -105,8 +105,10 @@ struct lwip_select_cb {
|
|||
struct lwip_setgetsockopt_data {
|
||||
/** socket struct for which to change options */
|
||||
struct lwip_sock *sock;
|
||||
#ifdef LWIP_DEBUG
|
||||
/** socket index for which to change options */
|
||||
int s;
|
||||
#endif /* LWIP_DEBUG */
|
||||
/** level of the option to process */
|
||||
int level;
|
||||
/** name of the option to process */
|
||||
|
@ -139,14 +141,14 @@ static const int err_to_errno_table[] = {
|
|||
EINPROGRESS, /* ERR_INPROGRESS -5 Operation in progress */
|
||||
EINVAL, /* ERR_VAL -6 Illegal value. */
|
||||
EWOULDBLOCK, /* ERR_WOULDBLOCK -7 Operation would block. */
|
||||
ECONNABORTED, /* ERR_ABRT -8 Connection aborted. */
|
||||
ECONNRESET, /* ERR_RST -9 Connection reset. */
|
||||
ESHUTDOWN, /* ERR_CLSD -10 Connection closed. */
|
||||
ENOTCONN, /* ERR_CONN -11 Not connected. */
|
||||
EIO, /* ERR_ARG -12 Illegal argument. */
|
||||
EADDRINUSE, /* ERR_USE -13 Address in use. */
|
||||
-1, /* ERR_IF -14 Low-level netif error */
|
||||
-1, /* ERR_ISCONN -15 Already connected. */
|
||||
EADDRINUSE, /* ERR_USE -8 Address in use. */
|
||||
EALREADY, /* ERR_ISCONN -9 Already connected. */
|
||||
ECONNABORTED, /* ERR_ABRT -10 Connection aborted. */
|
||||
ECONNRESET, /* ERR_RST -11 Connection reset. */
|
||||
ENOTCONN, /* ERR_CLSD -12 Connection closed. */
|
||||
ENOTCONN, /* ERR_CONN -13 Not connected. */
|
||||
EIO, /* ERR_ARG -14 Illegal argument. */
|
||||
-1, /* ERR_IF -15 Low-level netif error */
|
||||
};
|
||||
|
||||
#define ERR_TO_ERRNO_TABLE_SIZE \
|
||||
|
@ -804,6 +806,7 @@ lwip_sendto(int s, const void *data, size_t size, int flags,
|
|||
#if LWIP_TCP
|
||||
return lwip_send(s, data, size, flags);
|
||||
#else /* LWIP_TCP */
|
||||
LWIP_UNUSED_ARG(flags);
|
||||
sock_set_errno(sock, err_to_errno(ERR_ARG));
|
||||
return -1;
|
||||
#endif /* LWIP_TCP */
|
||||
|
@ -844,14 +847,19 @@ lwip_sendto(int s, const void *data, size_t size, int flags,
|
|||
inet_addr_to_ipaddr_p(remote_addr, &to_in->sin_addr);
|
||||
remote_port = ntohs(to_in->sin_port);
|
||||
} else {
|
||||
remote_addr = IP_ADDR_ANY;
|
||||
remote_port = 0;
|
||||
remote_addr = &sock->conn->pcb.raw->remote_ip;
|
||||
if (sock->conn->type == NETCONN_RAW) {
|
||||
remote_port = 0;
|
||||
} else {
|
||||
remote_port = sock->conn->pcb.udp->remote_port;
|
||||
}
|
||||
}
|
||||
|
||||
LOCK_TCPIP_CORE();
|
||||
if (sock->conn->type == NETCONN_RAW) {
|
||||
err = sock->conn->last_err = raw_sendto(sock->conn->pcb.raw, p, remote_addr);
|
||||
} else {
|
||||
#if LWIP_UDP
|
||||
#if LWIP_CHECKSUM_ON_COPY && LWIP_NETIF_TX_SINGLE_PBUF
|
||||
err = sock->conn->last_err = udp_sendto_chksum(sock->conn->pcb.udp, p,
|
||||
remote_addr, remote_port, 1, chksum);
|
||||
|
@ -859,6 +867,9 @@ lwip_sendto(int s, const void *data, size_t size, int flags,
|
|||
err = sock->conn->last_err = udp_sendto(sock->conn->pcb.udp, p,
|
||||
remote_addr, remote_port);
|
||||
#endif /* LWIP_CHECKSUM_ON_COPY && LWIP_NETIF_TX_SINGLE_PBUF */
|
||||
#else /* LWIP_UDP */
|
||||
err = ERR_ARG;
|
||||
#endif /* LWIP_UDP */
|
||||
}
|
||||
UNLOCK_TCPIP_CORE();
|
||||
|
||||
|
@ -883,7 +894,7 @@ lwip_sendto(int s, const void *data, size_t size, int flags,
|
|||
netbuf_fromport(&buf) = 0;
|
||||
}
|
||||
|
||||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_sendto(%d, data=%p, short_size=%d"U16_F", flags=0x%x to=",
|
||||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_sendto(%d, data=%p, short_size=%"U16_F", flags=0x%x to=",
|
||||
s, data, short_size, flags));
|
||||
ip_addr_debug_print(SOCKETS_DEBUG, &buf.addr);
|
||||
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F"\n", remote_port));
|
||||
|
@ -1181,6 +1192,8 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
|
|||
LWIP_ASSERT("select_cb.prev != NULL", select_cb.prev != NULL);
|
||||
select_cb.prev->next = select_cb.next;
|
||||
}
|
||||
/* Increasing this counter tells even_callback that the list has changed. */
|
||||
select_cb_ctr++;
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
|
||||
sys_sem_free(&select_cb.sem);
|
||||
|
@ -1223,6 +1236,7 @@ event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)
|
|||
int s;
|
||||
struct lwip_sock *sock;
|
||||
struct lwip_select_cb *scb;
|
||||
int last_select_cb_ctr;
|
||||
SYS_ARCH_DECL_PROTECT(lev);
|
||||
|
||||
LWIP_UNUSED_ARG(len);
|
||||
|
@ -1285,56 +1299,51 @@ event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)
|
|||
return;
|
||||
}
|
||||
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
|
||||
/* Now decide if anyone is waiting for this socket */
|
||||
/* NOTE: This code is written this way to protect the select link list
|
||||
but to avoid a deadlock situation by releasing select_lock before
|
||||
signalling for the select. This means we need to go through the list
|
||||
multiple times ONLY IF a select was actually waiting. We go through
|
||||
the list the number of waiting select calls + 1. This list is
|
||||
expected to be small. */
|
||||
while (1) {
|
||||
int last_select_cb_ctr;
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
for (scb = select_cb_list; scb; scb = scb->next) {
|
||||
/* @todo: unprotect with each loop and check for changes? */
|
||||
if (scb->sem_signalled == 0) {
|
||||
/* Test this select call for our socket */
|
||||
/* NOTE: This code goes through the select_cb_list list multiple times
|
||||
ONLY IF a select was actually waiting. We go through the list the number
|
||||
of waiting select calls + 1. This list is expected to be small. */
|
||||
|
||||
/* At this point, SYS_ARCH is still protected! */
|
||||
again:
|
||||
for (scb = select_cb_list; scb != NULL; scb = scb->next) {
|
||||
if (scb->sem_signalled == 0) {
|
||||
/* semaphore not signalled yet */
|
||||
int do_signal = 0;
|
||||
/* Test this select call for our socket */
|
||||
if (sock->rcvevent > 0) {
|
||||
if (scb->readset && FD_ISSET(s, scb->readset)) {
|
||||
if (sock->rcvevent > 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (scb->writeset && FD_ISSET(s, scb->writeset)) {
|
||||
if (sock->sendevent != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (scb->exceptset && FD_ISSET(s, scb->exceptset)) {
|
||||
if (sock->errevent != 0) {
|
||||
break;
|
||||
}
|
||||
do_signal = 1;
|
||||
}
|
||||
}
|
||||
/* unlock interrupts with each step */
|
||||
last_select_cb_ctr = select_cb_ctr;
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
if (last_select_cb_ctr != select_cb_ctr) {
|
||||
/* someone has changed select_cb_list, restart at the beginning */
|
||||
scb = select_cb_list;
|
||||
if (sock->sendevent != 0) {
|
||||
if (!do_signal && scb->writeset && FD_ISSET(s, scb->writeset)) {
|
||||
do_signal = 1;
|
||||
}
|
||||
}
|
||||
if (sock->errevent != 0) {
|
||||
if (!do_signal && scb->exceptset && FD_ISSET(s, scb->exceptset)) {
|
||||
do_signal = 1;
|
||||
}
|
||||
}
|
||||
if (do_signal) {
|
||||
scb->sem_signalled = 1;
|
||||
/* Don't call SYS_ARCH_UNPROTECT() before signaling the semaphore, as this might
|
||||
lead to the select thread taking itself off the list, invalidagin the semaphore. */
|
||||
sys_sem_signal(&scb->sem);
|
||||
}
|
||||
}
|
||||
if (scb) {
|
||||
scb->sem_signalled = 1;
|
||||
sys_sem_signal(&scb->sem);
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
} else {
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
break;
|
||||
/* unlock interrupts with each step */
|
||||
last_select_cb_ctr = select_cb_ctr;
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
/* this makes sure interrupt protection time is short */
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
if (last_select_cb_ctr != select_cb_ctr) {
|
||||
/* someone has changed select_cb_list, restart at the beginning */
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1610,6 +1619,9 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
|
|||
|
||||
/* Now do the actual option processing */
|
||||
data.sock = sock;
|
||||
#ifdef LWIP_DEBUG
|
||||
data.s = s;
|
||||
#endif /* LWIP_DEBUG */
|
||||
data.level = level;
|
||||
data.optname = optname;
|
||||
data.optval = optval;
|
||||
|
@ -1691,8 +1703,8 @@ lwip_getsockopt_internal(void *arg)
|
|||
break;
|
||||
|
||||
case SO_ERROR:
|
||||
/* only overwrite if ERR_OK before */
|
||||
if (sock->err == 0) {
|
||||
/* only overwrite ERR_OK or tempoary errors */
|
||||
if ((sock->err == 0) || (sock->err == EINPROGRESS)) {
|
||||
sock_set_errno(sock, err_to_errno(sock->conn->last_err));
|
||||
}
|
||||
*(int *)optval = sock->err;
|
||||
|
@ -2017,6 +2029,9 @@ lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t opt
|
|||
|
||||
/* Now do the actual option processing */
|
||||
data.sock = sock;
|
||||
#ifdef LWIP_DEBUG
|
||||
data.s = s;
|
||||
#endif /* LWIP_DEBUG */
|
||||
data.level = level;
|
||||
data.optname = optname;
|
||||
data.optval = (void*)optval;
|
||||
|
@ -2239,15 +2254,18 @@ int
|
|||
lwip_ioctl(int s, long cmd, void *argp)
|
||||
{
|
||||
struct lwip_sock *sock = get_socket(s);
|
||||
u8_t val;
|
||||
#if LWIP_SO_RCVBUF
|
||||
u16_t buflen = 0;
|
||||
s16_t recv_avail;
|
||||
u8_t val;
|
||||
#endif /* LWIP_SO_RCVBUF */
|
||||
|
||||
if (!sock) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
#if LWIP_SO_RCVBUF
|
||||
case FIONREAD:
|
||||
if (!argp) {
|
||||
sock_set_errno(sock, EINVAL);
|
||||
|
@ -2275,6 +2293,7 @@ lwip_ioctl(int s, long cmd, void *argp)
|
|||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONREAD, %p) = %"U16_F"\n", s, argp, *((u16_t*)argp)));
|
||||
sock_set_errno(sock, 0);
|
||||
return 0;
|
||||
#endif /* LWIP_SO_RCVBUF */
|
||||
|
||||
case FIONBIO:
|
||||
val = 0;
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
#include "lwip/pbuf.h"
|
||||
#include "lwip/tcpip.h"
|
||||
#include "lwip/init.h"
|
||||
#include "lwip/ip.h"
|
||||
#include "netif/etharp.h"
|
||||
#include "netif/ppp_oe.h"
|
||||
|
||||
|
|
|
@ -592,6 +592,23 @@ dhcp_set_struct(struct netif *netif, struct dhcp *dhcp)
|
|||
netif->dhcp = dhcp;
|
||||
}
|
||||
|
||||
/** Removes a struct dhcp from a netif.
|
||||
*
|
||||
* ATTENTION: Only use this when not using dhcp_set_struct() to allocate the
|
||||
* struct dhcp since the memory is passed back to the heap.
|
||||
*
|
||||
* @param netif the netif from which to remove the struct dhcp
|
||||
*/
|
||||
void dhcp_cleanup(struct netif *netif)
|
||||
{
|
||||
LWIP_ASSERT("netif != NULL", netif != NULL);
|
||||
|
||||
if (netif->dhcp != NULL) {
|
||||
mem_free(netif->dhcp);
|
||||
netif->dhcp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Start DHCP negotiation for a network interface.
|
||||
*
|
||||
|
@ -762,7 +779,10 @@ dhcp_network_changed(struct netif *netif)
|
|||
default:
|
||||
dhcp->tries = 0;
|
||||
#if LWIP_DHCP_AUTOIP_COOP
|
||||
dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF;
|
||||
if(dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) {
|
||||
autoip_stop(netif);
|
||||
dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF;
|
||||
}
|
||||
#endif /* LWIP_DHCP_AUTOIP_COOP */
|
||||
dhcp_discover(netif);
|
||||
break;
|
||||
|
@ -945,11 +965,11 @@ dhcp_bind(struct netif *netif)
|
|||
/* subnet mask not given, choose a safe subnet mask given the network class */
|
||||
u8_t first_octet = ip4_addr1(&dhcp->offered_ip_addr);
|
||||
if (first_octet <= 127) {
|
||||
ip4_addr_set_u32(&sn_mask, PP_HTONL(0xff000000));
|
||||
ip4_addr_set_u32(&sn_mask, PP_HTONL(0xff000000UL));
|
||||
} else if (first_octet >= 192) {
|
||||
ip4_addr_set_u32(&sn_mask, PP_HTONL(0xffffff00));
|
||||
ip4_addr_set_u32(&sn_mask, PP_HTONL(0xffffff00UL));
|
||||
} else {
|
||||
ip4_addr_set_u32(&sn_mask, PP_HTONL(0xffff0000));
|
||||
ip4_addr_set_u32(&sn_mask, PP_HTONL(0xffff0000UL));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -959,7 +979,7 @@ dhcp_bind(struct netif *netif)
|
|||
/* copy network address */
|
||||
ip_addr_get_network(&gw_addr, &dhcp->offered_ip_addr, &sn_mask);
|
||||
/* use first host address on network as gateway */
|
||||
ip4_addr_set_u32(&gw_addr, ip4_addr_get_u32(&gw_addr) | PP_HTONL(0x00000001));
|
||||
ip4_addr_set_u32(&gw_addr, ip4_addr_get_u32(&gw_addr) | PP_HTONL(0x00000001UL));
|
||||
}
|
||||
|
||||
#if LWIP_DHCP_AUTOIP_COOP
|
||||
|
|
|
@ -922,6 +922,7 @@ dns_enqueue(const char *name, dns_found_callback found, void *callback_arg)
|
|||
* name is already in the local names table.
|
||||
* - ERR_INPROGRESS enqueue a request to be sent to the DNS server
|
||||
* for resolution if no errors are present.
|
||||
* - ERR_ARG: dns client not initialized or invalid hostname
|
||||
*
|
||||
* @param hostname the hostname that is to be queried
|
||||
* @param addr pointer to a ip_addr_t where to store the address if it is already
|
||||
|
@ -941,7 +942,7 @@ dns_gethostbyname(const char *hostname, ip_addr_t *addr, dns_found_callback foun
|
|||
if ((dns_pcb == NULL) || (addr == NULL) ||
|
||||
(!hostname) || (!hostname[0]) ||
|
||||
(strlen(hostname) >= DNS_MAX_NAME_LENGTH)) {
|
||||
return ERR_VAL;
|
||||
return ERR_ARG;
|
||||
}
|
||||
|
||||
#if LWIP_HAVE_LOOPIF
|
||||
|
|
|
@ -105,6 +105,9 @@
|
|||
#if (LWIP_TCP && (TCP_SND_QUEUELEN > 0xffff))
|
||||
#error "If you want to use TCP, TCP_SND_QUEUELEN must fit in an u16_t, so, you have to reduce it in your lwipopts.h"
|
||||
#endif
|
||||
#if (LWIP_TCP && (TCP_SND_QUEUELEN < 2))
|
||||
#error "TCP_SND_QUEUELEN must be at least 2 for no-copy TCP writes to work"
|
||||
#endif
|
||||
#if (LWIP_TCP && ((TCP_MAXRTX > 12) || (TCP_SYNMAXRTX > 12)))
|
||||
#error "If you want to use TCP, TCP_MAXRTX and TCP_SYNMAXRTX must less or equal to 12 (due to tcp_backoff table), so, you have to reduce them in your lwipopts.h"
|
||||
#endif
|
||||
|
|
|
@ -494,12 +494,7 @@ autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr)
|
|||
*/
|
||||
ip_addr_t sipaddr, dipaddr;
|
||||
struct eth_addr netifaddr;
|
||||
netifaddr.addr[0] = netif->hwaddr[0];
|
||||
netifaddr.addr[1] = netif->hwaddr[1];
|
||||
netifaddr.addr[2] = netif->hwaddr[2];
|
||||
netifaddr.addr[3] = netif->hwaddr[3];
|
||||
netifaddr.addr[4] = netif->hwaddr[4];
|
||||
netifaddr.addr[5] = netif->hwaddr[5];
|
||||
ETHADDR16_COPY(netifaddr.addr, netif->hwaddr);
|
||||
|
||||
/* Copy struct ip_addr2 to aligned ip_addr, to support compilers without
|
||||
* structure packing (not using structure copy which breaks strict-aliasing rules).
|
||||
|
|
|
@ -191,7 +191,7 @@ icmp_input(struct pbuf *p, struct netif *inp)
|
|||
ip_addr_copy(iphdr->dest, *ip_current_src_addr());
|
||||
ICMPH_TYPE_SET(iecho, ICMP_ER);
|
||||
/* adjust the checksum */
|
||||
if (iecho->chksum >= PP_HTONS(0xffff - (ICMP_ECHO << 8))) {
|
||||
if (iecho->chksum >= PP_HTONS(0xffffU - (ICMP_ECHO << 8))) {
|
||||
iecho->chksum += PP_HTONS(ICMP_ECHO << 8) + 1;
|
||||
} else {
|
||||
iecho->chksum += PP_HTONS(ICMP_ECHO << 8);
|
||||
|
|
|
@ -100,7 +100,7 @@ Steve Reynolds
|
|||
*/
|
||||
#define IGMP_TTL 1
|
||||
#define IGMP_MINLEN 8
|
||||
#define ROUTER_ALERT 0x9404
|
||||
#define ROUTER_ALERT 0x9404U
|
||||
#define ROUTER_ALERTLEN 4
|
||||
|
||||
/*
|
||||
|
|
|
@ -201,7 +201,7 @@ ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
|
|||
}
|
||||
|
||||
/* Incrementally update the IP checksum. */
|
||||
if (IPH_CHKSUM(iphdr) >= PP_HTONS(0xffff - 0x100)) {
|
||||
if (IPH_CHKSUM(iphdr) >= PP_HTONS(0xffffU - 0x100)) {
|
||||
IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + PP_HTONS(0x100) + 1);
|
||||
} else {
|
||||
IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + PP_HTONS(0x100));
|
||||
|
@ -252,8 +252,6 @@ ip_input(struct pbuf *p, struct netif *inp)
|
|||
IP_STATS_INC(ip.recv);
|
||||
snmp_inc_ipinreceives();
|
||||
|
||||
DbgPrint("ip_input: called\n");
|
||||
|
||||
/* identify the IP header */
|
||||
iphdr = (struct ip_hdr *)p->payload;
|
||||
if (IPH_V(iphdr) != 4) {
|
||||
|
@ -490,7 +488,7 @@ ip_input(struct pbuf *p, struct netif *inp)
|
|||
if (raw_input(p, inp) == 0)
|
||||
#endif /* LWIP_RAW */
|
||||
{
|
||||
DbgPrint("ip_input: choosing protocol\n");
|
||||
|
||||
switch (IPH_PROTO(iphdr)) {
|
||||
#if LWIP_UDP
|
||||
case IP_PROTO_UDP:
|
||||
|
@ -504,7 +502,6 @@ ip_input(struct pbuf *p, struct netif *inp)
|
|||
#if LWIP_TCP
|
||||
case IP_PROTO_TCP:
|
||||
snmp_inc_ipindelivers();
|
||||
DbgPrint("ip_input: sending data to tcp_input\n");
|
||||
tcp_input(p, inp);
|
||||
break;
|
||||
#endif /* LWIP_TCP */
|
||||
|
@ -628,7 +625,7 @@ err_t ip_output_if_opt(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,
|
|||
memset(((char*)p->payload) + optlen, 0, optlen_aligned - optlen);
|
||||
}
|
||||
#if CHECKSUM_GEN_IP_INLINE
|
||||
for (i = 0; i < optlen_aligned; i += sizeof(u16_t)) {
|
||||
for (i = 0; i < optlen_aligned/2; i++) {
|
||||
chk_sum += ((u16_t*)p->payload)[i];
|
||||
}
|
||||
#endif /* CHECKSUM_GEN_IP_INLINE */
|
||||
|
|
|
@ -93,7 +93,7 @@ ip4_addr_netmask_valid(u32_t netmask)
|
|||
u32_t nm_hostorder = lwip_htonl(netmask);
|
||||
|
||||
/* first, check for the first zero */
|
||||
for (mask = 1U << 31 ; mask != 0; mask >>= 1) {
|
||||
for (mask = 1UL << 31 ; mask != 0; mask >>= 1) {
|
||||
if ((nm_hostorder & mask) == 0) {
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -218,8 +218,10 @@ raw_sendto(struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr)
|
|||
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("raw_sendto: could not allocate header\n"));
|
||||
return ERR_MEM;
|
||||
}
|
||||
/* chain header q in front of given pbuf p */
|
||||
pbuf_chain(q, p);
|
||||
if (p->tot_len != 0) {
|
||||
/* chain header q in front of given pbuf p */
|
||||
pbuf_chain(q, p);
|
||||
}
|
||||
/* { first pbuf q points to header pbuf } */
|
||||
LWIP_DEBUGF(RAW_DEBUG, ("raw_sendto: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p));
|
||||
} else {
|
||||
|
|
|
@ -43,10 +43,12 @@
|
|||
#include "lwip/netif.h"
|
||||
#include "lwip/ip.h"
|
||||
#include "lwip/ip_frag.h"
|
||||
#include "lwip/mem.h"
|
||||
#include "lwip/tcp_impl.h"
|
||||
#include "lwip/udp.h"
|
||||
#include "lwip/snmp_asn1.h"
|
||||
#include "lwip/snmp_structs.h"
|
||||
#include "lwip/sys.h"
|
||||
#include "netif/etharp.h"
|
||||
|
||||
/**
|
||||
|
|
|
@ -91,7 +91,7 @@ struct tcp_pcb *tcp_tw_pcbs;
|
|||
#define NUM_TCP_PCB_LISTS 4
|
||||
#define NUM_TCP_PCB_LISTS_NO_TIME_WAIT 3
|
||||
/** An array with all (non-temporary) PCB lists, mainly used for smaller code size */
|
||||
struct tcp_pcb **tcp_pcb_lists[] = {&tcp_listen_pcbs.pcbs, &tcp_bound_pcbs,
|
||||
struct tcp_pcb ** const tcp_pcb_lists[] = {&tcp_listen_pcbs.pcbs, &tcp_bound_pcbs,
|
||||
&tcp_active_pcbs, &tcp_tw_pcbs};
|
||||
|
||||
/** Only used for temporary storage. */
|
||||
|
@ -139,8 +139,6 @@ tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data)
|
|||
{
|
||||
err_t err;
|
||||
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_close_shutdown: called on pcb 0x%x\n", pcb));
|
||||
|
||||
if (rst_on_unacked_data && (pcb->state != LISTEN)) {
|
||||
if ((pcb->refused_data != NULL) || (pcb->rcv_wnd != TCP_WND)) {
|
||||
/* Not all data received by application, send RST to tell the remote
|
||||
|
@ -175,13 +173,14 @@ tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data)
|
|||
* is erroneous, but this should never happen as the pcb has in those cases
|
||||
* been freed, and so any remaining handles are bogus. */
|
||||
err = ERR_OK;
|
||||
TCP_RMV(&tcp_bound_pcbs, pcb);
|
||||
if (pcb->local_port != 0) {
|
||||
TCP_RMV(&tcp_bound_pcbs, pcb);
|
||||
}
|
||||
memp_free(MEMP_TCP_PCB, pcb);
|
||||
pcb = NULL;
|
||||
break;
|
||||
case LISTEN:
|
||||
err = ERR_OK;
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_close_shutdown: Remove pcb from listen list and free\n"));
|
||||
tcp_pcb_remove(&tcp_listen_pcbs.pcbs, pcb);
|
||||
memp_free(MEMP_TCP_PCB_LISTEN, pcb);
|
||||
pcb = NULL;
|
||||
|
@ -394,6 +393,7 @@ tcp_abort(struct tcp_pcb *pcb)
|
|||
* to any local address
|
||||
* @param port the local port to bind to
|
||||
* @return ERR_USE if the port is already in use
|
||||
* ERR_VAL if bind failed because the PCB is not in a valid state
|
||||
* ERR_OK if bound
|
||||
*/
|
||||
err_t
|
||||
|
@ -403,7 +403,7 @@ tcp_bind(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port)
|
|||
int max_pcb_list = NUM_TCP_PCB_LISTS;
|
||||
struct tcp_pcb *cpcb;
|
||||
|
||||
LWIP_ERROR("tcp_bind: can only bind in state CLOSED", pcb->state == CLOSED, return ERR_ISCONN);
|
||||
LWIP_ERROR("tcp_bind: can only bind in state CLOSED", pcb->state == CLOSED, return ERR_VAL);
|
||||
|
||||
#if SO_REUSE
|
||||
/* Unless the REUSEADDR flag is set,
|
||||
|
@ -411,11 +411,9 @@ tcp_bind(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port)
|
|||
We do not dump TIME_WAIT pcb's; they can still be matched by incoming
|
||||
packets using both local and remote IP addresses and ports to distinguish.
|
||||
*/
|
||||
#if SO_REUSE
|
||||
if ((pcb->so_options & SOF_REUSEADDR) != 0) {
|
||||
max_pcb_list = NUM_TCP_PCB_LISTS_NO_TIME_WAIT;
|
||||
}
|
||||
#endif /* SO_REUSE */
|
||||
#endif /* SO_REUSE */
|
||||
|
||||
if (port == 0) {
|
||||
|
@ -488,8 +486,6 @@ tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog)
|
|||
|
||||
LWIP_UNUSED_ARG(backlog);
|
||||
LWIP_ERROR("tcp_listen: pcb already connected", pcb->state == CLOSED, return NULL);
|
||||
DbgPrint("tcp_listen_with_backlog: sizeof(tcp_pcb_listen) = %d, %d\n",
|
||||
sizeof(struct tcp_pcb_listen), (((sizeof(struct tcp_pcb_listen)) + MEM_ALIGNMENT - 1) & ~(MEM_ALIGNMENT-1)));
|
||||
|
||||
/* already listening? */
|
||||
if (pcb->state == LISTEN) {
|
||||
|
@ -523,7 +519,9 @@ tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog)
|
|||
lpcb->ttl = pcb->ttl;
|
||||
lpcb->tos = pcb->tos;
|
||||
ip_addr_copy(lpcb->local_ip, pcb->local_ip);
|
||||
TCP_RMV(&tcp_bound_pcbs, pcb);
|
||||
if (pcb->local_port != 0) {
|
||||
TCP_RMV(&tcp_bound_pcbs, pcb);
|
||||
}
|
||||
memp_free(MEMP_TCP_PCB, pcb);
|
||||
#if LWIP_CALLBACK_API
|
||||
lpcb->accept = tcp_accept_null;
|
||||
|
@ -613,17 +611,19 @@ tcp_new_port(void)
|
|||
int i;
|
||||
struct tcp_pcb *pcb;
|
||||
#ifndef TCP_LOCAL_PORT_RANGE_START
|
||||
#define TCP_LOCAL_PORT_RANGE_START 4096
|
||||
#define TCP_LOCAL_PORT_RANGE_END 0x7fff
|
||||
/* From http://www.iana.org/assignments/port-numbers:
|
||||
"The Dynamic and/or Private Ports are those from 49152 through 65535" */
|
||||
#define TCP_LOCAL_PORT_RANGE_START 0xc000
|
||||
#define TCP_LOCAL_PORT_RANGE_END 0xffff
|
||||
#endif
|
||||
static u16_t port = TCP_LOCAL_PORT_RANGE_START;
|
||||
|
||||
again:
|
||||
if (++port > TCP_LOCAL_PORT_RANGE_END) {
|
||||
if (port++ >= TCP_LOCAL_PORT_RANGE_END) {
|
||||
port = TCP_LOCAL_PORT_RANGE_START;
|
||||
}
|
||||
/* Check all PCB lists. */
|
||||
for (i = 1; i < NUM_TCP_PCB_LISTS; i++) {
|
||||
for (i = 0; i < NUM_TCP_PCB_LISTS; i++) {
|
||||
for(pcb = *tcp_pcb_lists[i]; pcb != NULL; pcb = pcb->next) {
|
||||
if (pcb->local_port == port) {
|
||||
goto again;
|
||||
|
@ -651,8 +651,9 @@ tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port,
|
|||
{
|
||||
err_t ret;
|
||||
u32_t iss;
|
||||
u16_t old_local_port;
|
||||
|
||||
LWIP_ERROR("tcp_connect: can only connected from state CLOSED", pcb->state == CLOSED, return ERR_ISCONN);
|
||||
LWIP_ERROR("tcp_connect: can only connect from state CLOSED", pcb->state == CLOSED, return ERR_ISCONN);
|
||||
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_connect to port %"U16_F"\n", port));
|
||||
if (ipaddr != NULL) {
|
||||
|
@ -675,6 +676,7 @@ tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port,
|
|||
ip_addr_copy(pcb->local_ip, netif->ip_addr);
|
||||
}
|
||||
|
||||
old_local_port = pcb->local_port;
|
||||
if (pcb->local_port == 0) {
|
||||
pcb->local_port = tcp_new_port();
|
||||
}
|
||||
|
@ -684,8 +686,8 @@ tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port,
|
|||
now that the 5-tuple is unique. */
|
||||
struct tcp_pcb *cpcb;
|
||||
int i;
|
||||
/* Don't check listen PCBs, check bound-, active- and TIME-WAIT PCBs. */
|
||||
for (i = 1; i < NUM_TCP_PCB_LISTS; i++) {
|
||||
/* Don't check listen- and bound-PCBs, check active- and TIME-WAIT PCBs. */
|
||||
for (i = 2; i < NUM_TCP_PCB_LISTS; i++) {
|
||||
for(cpcb = *tcp_pcb_lists[i]; cpcb != NULL; cpcb = cpcb->next) {
|
||||
if ((cpcb->local_port == pcb->local_port) &&
|
||||
(cpcb->remote_port == port) &&
|
||||
|
@ -726,7 +728,9 @@ tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port,
|
|||
if (ret == ERR_OK) {
|
||||
/* SYN segment was enqueued, changed the pcbs state now */
|
||||
pcb->state = SYN_SENT;
|
||||
TCP_RMV(&tcp_bound_pcbs, pcb);
|
||||
if (old_local_port != 0) {
|
||||
TCP_RMV(&tcp_bound_pcbs, pcb);
|
||||
}
|
||||
TCP_REG(&tcp_active_pcbs, pcb);
|
||||
snmp_inc_tcpactiveopens();
|
||||
|
||||
|
@ -745,7 +749,7 @@ tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port,
|
|||
void
|
||||
tcp_slowtmr(void)
|
||||
{
|
||||
struct tcp_pcb *pcb, *pcb2, *prev;
|
||||
struct tcp_pcb *pcb, *prev;
|
||||
u16_t eff_wnd;
|
||||
u8_t pcb_remove; /* flag if a PCB should be removed */
|
||||
u8_t pcb_reset; /* flag if a RST should be sent when removing */
|
||||
|
@ -758,33 +762,26 @@ tcp_slowtmr(void)
|
|||
/* Steps through all of the active PCBs. */
|
||||
prev = NULL;
|
||||
pcb = tcp_active_pcbs;
|
||||
if (pcb == NULL)
|
||||
{
|
||||
if (pcb == NULL) {
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: no active pcbs\n"));
|
||||
}
|
||||
while (pcb != NULL)
|
||||
{
|
||||
while (pcb != NULL) {
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: processing active pcb\n"));
|
||||
LWIP_ASSERT("tcp_slowtmr: active pcb->state != CLOSED\n", pcb->state != CLOSED);
|
||||
LWIP_ASSERT("tcp_slowtmr: active pcb->state != LISTEN\n", pcb->state != LISTEN);
|
||||
LWIP_ASSERT("tcp_slowtmr: active pcb->state != TIME-WAIT\n", pcb->state != TIME_WAIT);
|
||||
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: active pcb = 0x%x ports (%d -> %d)\n", pcb, pcb->local_port, pcb->remote_port));
|
||||
|
||||
pcb_remove = 0;
|
||||
pcb_reset = 0;
|
||||
|
||||
if (pcb->state == SYN_SENT && pcb->nrtx == TCP_SYNMAXRTX)
|
||||
{
|
||||
if (pcb->state == SYN_SENT && pcb->nrtx == TCP_SYNMAXRTX) {
|
||||
++pcb_remove;
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max SYN retries reached\n"));
|
||||
}
|
||||
else if (pcb->nrtx == TCP_MAXRTX)
|
||||
{
|
||||
else if (pcb->nrtx == TCP_MAXRTX) {
|
||||
++pcb_remove;
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max DATA retries reached\n"));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (pcb->persist_backoff > 0) {
|
||||
/* If snd_wnd is zero, use persist timer to send 1 byte probes
|
||||
* instead of using the standard retransmission mechanism. */
|
||||
|
@ -907,16 +904,14 @@ tcp_slowtmr(void)
|
|||
}
|
||||
|
||||
/* If the PCB should be removed, do it. */
|
||||
if (pcb_remove)
|
||||
{
|
||||
if (pcb_remove) {
|
||||
struct tcp_pcb *pcb2;
|
||||
tcp_pcb_purge(pcb);
|
||||
/* Remove PCB from tcp_active_pcbs list. */
|
||||
if (prev != NULL) {
|
||||
LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_active_pcbs", pcb != tcp_active_pcbs);
|
||||
prev->next = pcb->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/* This PCB was the first. */
|
||||
LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_active_pcbs", tcp_active_pcbs == pcb);
|
||||
tcp_active_pcbs = pcb->next;
|
||||
|
@ -928,27 +923,22 @@ tcp_slowtmr(void)
|
|||
pcb->local_port, pcb->remote_port);
|
||||
}
|
||||
|
||||
pcb2 = pcb->next;
|
||||
memp_free(MEMP_TCP_PCB, pcb);
|
||||
pcb = pcb2;
|
||||
}
|
||||
else
|
||||
{
|
||||
pcb2 = pcb;
|
||||
pcb = pcb->next;
|
||||
memp_free(MEMP_TCP_PCB, pcb2);
|
||||
} else {
|
||||
/* get the 'next' element now and work with 'prev' below (in case of abort) */
|
||||
prev = pcb;
|
||||
pcb = pcb->next;
|
||||
|
||||
/* We check if we should poll the connection. */
|
||||
++prev->polltmr;
|
||||
if (prev->polltmr >= prev->pollinterval)
|
||||
{
|
||||
if (prev->polltmr >= prev->pollinterval) {
|
||||
prev->polltmr = 0;
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: polling application\n"));
|
||||
//LWIP_ASSERT("tcp_slowtmr: active pcb->poll != 0\n", pcb->poll != 0);
|
||||
TCP_EVENT_POLL(prev, err);
|
||||
/* if err == ERR_ABRT, 'prev' is already deallocated */
|
||||
if (err == ERR_OK)
|
||||
{
|
||||
if (err == ERR_OK) {
|
||||
tcp_output(prev);
|
||||
}
|
||||
}
|
||||
|
@ -957,7 +947,7 @@ tcp_slowtmr(void)
|
|||
|
||||
|
||||
/* Steps through all of the TIME-WAIT PCBs. */
|
||||
prev = NULL;
|
||||
prev = NULL;
|
||||
pcb = tcp_tw_pcbs;
|
||||
while (pcb != NULL) {
|
||||
LWIP_ASSERT("tcp_slowtmr: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
|
||||
|
@ -972,6 +962,7 @@ tcp_slowtmr(void)
|
|||
|
||||
/* If the PCB should be removed, do it. */
|
||||
if (pcb_remove) {
|
||||
struct tcp_pcb *pcb2;
|
||||
tcp_pcb_purge(pcb);
|
||||
/* Remove PCB from tcp_tw_pcbs list. */
|
||||
if (prev != NULL) {
|
||||
|
@ -982,9 +973,9 @@ tcp_slowtmr(void)
|
|||
LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_tw_pcbs", tcp_tw_pcbs == pcb);
|
||||
tcp_tw_pcbs = pcb->next;
|
||||
}
|
||||
pcb2 = pcb->next;
|
||||
memp_free(MEMP_TCP_PCB, pcb);
|
||||
pcb = pcb2;
|
||||
pcb2 = pcb;
|
||||
pcb = pcb->next;
|
||||
memp_free(MEMP_TCP_PCB, pcb2);
|
||||
} else {
|
||||
prev = pcb;
|
||||
pcb = pcb->next;
|
||||
|
@ -1019,7 +1010,7 @@ tcp_fasttmr(void)
|
|||
}
|
||||
}
|
||||
|
||||
/* send delayed ACKs */
|
||||
/* send delayed ACKs */
|
||||
if (pcb && (pcb->flags & TF_ACK_DELAY)) {
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: delayed ACK\n"));
|
||||
tcp_ack_now(pcb);
|
||||
|
|
|
@ -113,8 +113,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||
#endif
|
||||
|
||||
/* remove header from payload */
|
||||
if (pbuf_header(p, -((s16_t)(IPH_HL(iphdr) * 4))) || (p->tot_len < sizeof(struct tcp_hdr)))
|
||||
{
|
||||
if (pbuf_header(p, -((s16_t)(IPH_HL(iphdr) * 4))) || (p->tot_len < sizeof(struct tcp_hdr))) {
|
||||
/* drop short packets */
|
||||
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet (%"U16_F" bytes) discarded\n", p->tot_len));
|
||||
TCP_STATS_INC(tcp.lenerr);
|
||||
|
@ -175,31 +174,25 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||
flags = TCPH_FLAGS(tcphdr);
|
||||
tcplen = p->tot_len + ((flags & (TCP_FIN | TCP_SYN)) ? 1 : 0);
|
||||
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_input: called %"U16_F" -> %"U16_F"\n", tcphdr->src, tcphdr->dest));
|
||||
|
||||
/* Demultiplex an incoming segment. First, we check if it is destined
|
||||
for an active connection. */
|
||||
prev = NULL;
|
||||
|
||||
|
||||
for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next)
|
||||
{
|
||||
for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) {
|
||||
LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED);
|
||||
LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT);
|
||||
LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN);
|
||||
|
||||
if (pcb->remote_port == tcphdr->src &&
|
||||
pcb->local_port == tcphdr->dest &&
|
||||
ip_addr_cmp(&(pcb->remote_ip), ¤t_iphdr_src) &&
|
||||
ip_addr_cmp(&(pcb->local_ip), ¤t_iphdr_dest))
|
||||
{
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_input: active pcb -> (localport, remoteport) = %"U16_F" -> %"U16_F"\n", pcb->local_port, pcb->remote_port));
|
||||
DbgPrint("tcp_input: pcb = 0x%x\n", pcb);
|
||||
ip_addr_cmp(&(pcb->local_ip), ¤t_iphdr_dest)) {
|
||||
|
||||
/* Move this PCB to the front of the list so that subsequent
|
||||
lookups will be faster (we exploit locality in TCP segment
|
||||
arrivals). */
|
||||
LWIP_ASSERT("tcp_input: pcb->next != pcb (before cache)", pcb->next != pcb);
|
||||
if (prev != NULL)
|
||||
{
|
||||
if (prev != NULL) {
|
||||
prev->next = pcb->next;
|
||||
pcb->next = tcp_active_pcbs;
|
||||
tcp_active_pcbs = pcb;
|
||||
|
@ -210,18 +203,15 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||
prev = pcb;
|
||||
}
|
||||
|
||||
if (pcb == NULL)
|
||||
{
|
||||
if (pcb == NULL) {
|
||||
/* If it did not go to an active connection, we check the connections
|
||||
in the TIME-WAIT state. */
|
||||
for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next)
|
||||
{
|
||||
for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) {
|
||||
LWIP_ASSERT("tcp_input: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
|
||||
if (pcb->remote_port == tcphdr->src &&
|
||||
pcb->local_port == tcphdr->dest &&
|
||||
ip_addr_cmp(&(pcb->remote_ip), ¤t_iphdr_src) &&
|
||||
ip_addr_cmp(&(pcb->local_ip), ¤t_iphdr_dest))
|
||||
{
|
||||
ip_addr_cmp(&(pcb->local_ip), ¤t_iphdr_dest)) {
|
||||
/* We don't really care enough to move this PCB to the front
|
||||
of the list since we are not very likely to receive that
|
||||
many segments for connections in TIME-WAIT. */
|
||||
|
@ -235,10 +225,8 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||
/* Finally, if we still did not get a match, we check all PCBs that
|
||||
are LISTENing for incoming connections. */
|
||||
prev = NULL;
|
||||
for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next)
|
||||
{
|
||||
if (lpcb->local_port == tcphdr->dest)
|
||||
{
|
||||
for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
|
||||
if (lpcb->local_port == tcphdr->dest) {
|
||||
#if SO_REUSE
|
||||
if (ip_addr_cmp(&(lpcb->local_ip), ¤t_iphdr_dest)) {
|
||||
/* found an exact match */
|
||||
|
@ -250,8 +238,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||
}
|
||||
#else /* SO_REUSE */
|
||||
if (ip_addr_cmp(&(lpcb->local_ip), ¤t_iphdr_dest) ||
|
||||
ip_addr_isany(&(lpcb->local_ip)))
|
||||
{
|
||||
ip_addr_isany(&(lpcb->local_ip))) {
|
||||
/* found a match */
|
||||
break;
|
||||
}
|
||||
|
@ -267,13 +254,11 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||
prev = lpcb_prev;
|
||||
}
|
||||
#endif /* SO_REUSE */
|
||||
if (lpcb != NULL)
|
||||
{
|
||||
if (lpcb != NULL) {
|
||||
/* Move this PCB to the front of the list so that subsequent
|
||||
lookups will be faster (we exploit locality in TCP segment
|
||||
arrivals). */
|
||||
if (prev != NULL)
|
||||
{
|
||||
if (prev != NULL) {
|
||||
((struct tcp_pcb_listen *)prev)->next = lpcb->next;
|
||||
/* our successor is the remainder of the listening list */
|
||||
lpcb->next = tcp_listen_pcbs.listen_pcbs;
|
||||
|
@ -281,8 +266,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||
tcp_listen_pcbs.listen_pcbs = lpcb;
|
||||
}
|
||||
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_input: packed for LISTENing connection\n"));
|
||||
|
||||
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for LISTENing connection.\n"));
|
||||
tcp_listen_input(lpcb);
|
||||
pbuf_free(p);
|
||||
return;
|
||||
|
@ -296,9 +280,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||
#endif /* TCP_INPUT_DEBUG */
|
||||
|
||||
|
||||
if (pcb != NULL)
|
||||
{
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_input: pcb = 0x%x is for active connection\n", pcb));
|
||||
if (pcb != NULL) {
|
||||
/* The incoming segment belongs to a connection. */
|
||||
#if TCP_INPUT_DEBUG
|
||||
#if TCP_DEBUG
|
||||
|
@ -309,7 +291,6 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||
/* Set up a tcp_seg structure. */
|
||||
inseg.next = NULL;
|
||||
inseg.len = p->tot_len;
|
||||
inseg.dataptr = p->payload;
|
||||
inseg.p = p;
|
||||
inseg.tcphdr = tcphdr;
|
||||
|
||||
|
@ -317,18 +298,16 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||
recv_flags = 0;
|
||||
|
||||
/* If there is data which was previously "refused" by upper layer */
|
||||
if (pcb->refused_data != NULL)
|
||||
{
|
||||
if (pcb->refused_data != NULL) {
|
||||
/* Notify again application with data previously received. */
|
||||
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: notify kept packet\n"));
|
||||
TCP_EVENT_RECV(pcb, pcb->refused_data, ERR_OK, err);
|
||||
if (err == ERR_OK) {
|
||||
pcb->refused_data = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else if ((err == ERR_ABRT) || (tcplen > 0)) {
|
||||
/* if err == ERR_ABRT, 'pcb' is already deallocated */
|
||||
/* drop incoming packets, because pcb is "full" */
|
||||
/* Drop incoming packets because pcb is "full" (only if the incoming
|
||||
segment contains data). */
|
||||
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: drop incoming packets, because pcb is \"full\"\n"));
|
||||
TCP_STATS_INC(tcp.drop);
|
||||
snmp_inc_tcpinerrs();
|
||||
|
@ -340,10 +319,8 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||
err = tcp_process(pcb);
|
||||
/* A return value of ERR_ABRT means that tcp_abort() was called
|
||||
and that the pcb has been freed. If so, we don't do anything. */
|
||||
if (err != ERR_ABRT)
|
||||
{
|
||||
if (recv_flags & TF_RESET)
|
||||
{
|
||||
if (err != ERR_ABRT) {
|
||||
if (recv_flags & TF_RESET) {
|
||||
/* TF_RESET means that the connection was reset by the other
|
||||
end. We then call the error callback to inform the
|
||||
application that the connection is dead before we
|
||||
|
@ -351,54 +328,44 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||
TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_RST);
|
||||
tcp_pcb_remove(&tcp_active_pcbs, pcb);
|
||||
memp_free(MEMP_TCP_PCB, pcb);
|
||||
}
|
||||
else if (recv_flags & TF_CLOSED)
|
||||
{
|
||||
} else if (recv_flags & TF_CLOSED) {
|
||||
/* The connection has been closed and we will deallocate the
|
||||
PCB. */
|
||||
tcp_pcb_remove(&tcp_active_pcbs, pcb);
|
||||
memp_free(MEMP_TCP_PCB, pcb);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
err = ERR_OK;
|
||||
/* If the application has registered a "sent" function to be
|
||||
called when new send buffer space is available, we call it
|
||||
now. */
|
||||
if (pcb->acked > 0)
|
||||
{
|
||||
if (pcb->acked > 0) {
|
||||
TCP_EVENT_SENT(pcb, pcb->acked, err);
|
||||
if (err == ERR_ABRT)
|
||||
{
|
||||
if (err == ERR_ABRT) {
|
||||
goto aborted;
|
||||
}
|
||||
}
|
||||
|
||||
if (recv_data != NULL)
|
||||
{
|
||||
if (pcb->flags & TF_RXCLOSED)
|
||||
{
|
||||
if (recv_data != NULL) {
|
||||
LWIP_ASSERT("pcb->refused_data == NULL", pcb->refused_data == NULL);
|
||||
if (pcb->flags & TF_RXCLOSED) {
|
||||
/* received data although already closed -> abort (send RST) to
|
||||
notify the remote host that not all data has been processed */
|
||||
pbuf_free(recv_data);
|
||||
tcp_abort(pcb);
|
||||
goto aborted;
|
||||
}
|
||||
if (flags & TCP_PSH)
|
||||
{
|
||||
if (flags & TCP_PSH) {
|
||||
recv_data->flags |= PBUF_FLAG_PUSH;
|
||||
}
|
||||
|
||||
/* Notify application that data has been received. */
|
||||
TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err);
|
||||
if (err == ERR_ABRT)
|
||||
{
|
||||
if (err == ERR_ABRT) {
|
||||
goto aborted;
|
||||
}
|
||||
|
||||
/* If the upper layer can't receive this data, store it */
|
||||
if (err != ERR_OK)
|
||||
{
|
||||
if (err != ERR_OK) {
|
||||
pcb->refused_data = recv_data;
|
||||
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: keep incoming packet, because pcb is \"full\"\n"));
|
||||
}
|
||||
|
@ -406,19 +373,14 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
|||
|
||||
/* If a FIN segment was received, we call the callback
|
||||
function with a NULL buffer to indicate EOF. */
|
||||
if (recv_flags & TF_GOT_FIN)
|
||||
{
|
||||
if (recv_flags & TF_GOT_FIN) {
|
||||
/* correct rcv_wnd as the application won't call tcp_recved()
|
||||
for the FIN's seqno */
|
||||
if (pcb->rcv_wnd != TCP_WND)
|
||||
{
|
||||
if (pcb->rcv_wnd != TCP_WND) {
|
||||
pcb->rcv_wnd++;
|
||||
}
|
||||
|
||||
TCP_EVENT_CLOSED(pcb, err);
|
||||
|
||||
if (err == ERR_ABRT)
|
||||
{
|
||||
if (err == ERR_ABRT) {
|
||||
goto aborted;
|
||||
}
|
||||
}
|
||||
|
@ -445,9 +407,7 @@ aborted:
|
|||
pbuf_free(inseg.p);
|
||||
inseg.p = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
|
||||
/* If no matching PCB was found, send a TCP RST (reset) to the
|
||||
sender. */
|
||||
|
@ -530,13 +490,10 @@ tcp_listen_input(struct tcp_pcb_listen *pcb)
|
|||
#endif /* LWIP_CALLBACK_API */
|
||||
/* inherit socket options */
|
||||
npcb->so_options = pcb->so_options & SOF_INHERITED;
|
||||
|
||||
/* Register the new PCB so that we can begin receiving segments
|
||||
for it. */
|
||||
TCP_REG(&tcp_active_pcbs, npcb);
|
||||
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("TCP new pcb created with %"U16_F" -> %"U16_F".\n", npcb->local_port, npcb->remote_port));
|
||||
|
||||
/* Parse any options in the SYN. */
|
||||
tcp_parseopt(npcb);
|
||||
#if TCP_CALCULATE_EFF_SEND_MSS
|
||||
|
@ -620,8 +577,6 @@ tcp_process(struct tcp_pcb *pcb)
|
|||
|
||||
err = ERR_OK;
|
||||
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("[tcp_process] called\n"));
|
||||
|
||||
/* Process incoming RST segments. */
|
||||
if (flags & TCP_RST) {
|
||||
/* First, determine if the reset is acceptable. */
|
||||
|
@ -681,10 +636,6 @@ tcp_process(struct tcp_pcb *pcb)
|
|||
pcb->snd_wl1 = seqno - 1; /* initialise to seqno - 1 to force window update */
|
||||
pcb->state = ESTABLISHED;
|
||||
|
||||
LWIP_DEBUGF(TCP_DEBUG,
|
||||
("[tcp_process] (SYN_SENT) TCP connection established %"U16_F" -> %"U16_F"\n",
|
||||
pcb->local_port , pcb->remote_port));
|
||||
|
||||
#if TCP_CALCULATE_EFF_SEND_MSS
|
||||
pcb->mss = tcp_eff_send_mss(pcb->mss, &(pcb->remote_ip));
|
||||
#endif /* TCP_CALCULATE_EFF_SEND_MSS */
|
||||
|
@ -732,13 +683,7 @@ tcp_process(struct tcp_pcb *pcb)
|
|||
if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) {
|
||||
u16_t old_cwnd;
|
||||
pcb->state = ESTABLISHED;
|
||||
LWIP_DEBUGF(TCP_DEBUG,
|
||||
("[tcp_process] (SYN_RCVD) TCP connection established %"U16_F" -> %"U16_F"\n",
|
||||
inseg.tcphdr->src, inseg.tcphdr->dest));
|
||||
LWIP_DEBUGF(TCP_DEBUG,
|
||||
("[tcp_process] (SYN_RCVD) TCP local port = %"U16_F"\n",
|
||||
pcb->local_port));
|
||||
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest));
|
||||
#if LWIP_CALLBACK_API
|
||||
LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL);
|
||||
#endif
|
||||
|
@ -909,8 +854,6 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||
u16_t new_tot_len;
|
||||
int found_dupack = 0;
|
||||
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_receive: called\n"));
|
||||
|
||||
if (flags & TCP_ACK) {
|
||||
right_wnd_edge = pcb->snd_wnd + pcb->snd_wl2;
|
||||
|
||||
|
@ -1223,9 +1166,6 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||
LWIP_ASSERT("pbuf_header failed", 0);
|
||||
}
|
||||
}
|
||||
/* KJM following line changed to use p->payload rather than inseg->p->payload
|
||||
to fix bug #9076 */
|
||||
inseg.dataptr = p->payload;
|
||||
inseg.len -= (u16_t)(pcb->rcv_nxt - seqno);
|
||||
inseg.tcphdr->seqno = seqno = pcb->rcv_nxt;
|
||||
}
|
||||
|
@ -1536,8 +1476,6 @@ tcp_receive(struct tcp_pcb *pcb)
|
|||
tcp_ack_now(pcb);
|
||||
}
|
||||
}
|
||||
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_receive: done\n"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -166,7 +166,6 @@ tcp_create_segment(struct tcp_pcb *pcb, struct pbuf *p, u8_t flags, u32_t seqno,
|
|||
seg->flags = optflags;
|
||||
seg->next = NULL;
|
||||
seg->p = p;
|
||||
seg->dataptr = p->payload;
|
||||
seg->len = p->tot_len - optlen;
|
||||
#if TCP_OVERSIZE_DBGCHECK
|
||||
seg->oversize_left = 0;
|
||||
|
@ -590,10 +589,6 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags)
|
|||
seg->chksum_swapped = chksum_swapped;
|
||||
seg->flags |= TF_SEG_DATA_CHECKSUMMED;
|
||||
#endif /* TCP_CHECKSUM_ON_COPY */
|
||||
/* Fix dataptr for the nocopy case */
|
||||
if ((apiflags & TCP_WRITE_FLAG_COPY) == 0) {
|
||||
seg->dataptr = (u8_t*)arg + pos;
|
||||
}
|
||||
|
||||
/* first segment of to-be-queued data? */
|
||||
if (queue == NULL) {
|
||||
|
@ -773,6 +768,7 @@ tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags)
|
|||
TCP_STATS_INC(tcp.memerr);
|
||||
return ERR_MEM;
|
||||
}
|
||||
LWIP_ASSERT("seg->tcphdr not aligned", ((mem_ptr_t)seg->tcphdr % MEM_ALIGNMENT) == 0);
|
||||
LWIP_ASSERT("tcp_enqueue_flags: invalid segment length", seg->len == 0);
|
||||
|
||||
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE,
|
||||
|
@ -1067,7 +1063,7 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb)
|
|||
|
||||
/* Add any requested options. NB MSS option is only set on SYN
|
||||
packets, so ignore it here */
|
||||
LWIP_ASSERT("seg->tcphdr not aligned", ((mem_ptr_t)(seg->tcphdr + 1) % 4) == 0);
|
||||
LWIP_ASSERT("seg->tcphdr not aligned", ((mem_ptr_t)seg->tcphdr % MEM_ALIGNMENT) == 0);
|
||||
opts = (u32_t *)(void *)(seg->tcphdr + 1);
|
||||
if (seg->flags & TF_SEG_OPTS_MSS) {
|
||||
TCP_BUILD_MSS_OPTION(*opts);
|
||||
|
@ -1082,6 +1078,12 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* Set retransmission timer running if it is not currently enabled
|
||||
This must be set before checking the route. */
|
||||
if (pcb->rtime == -1) {
|
||||
pcb->rtime = 0;
|
||||
}
|
||||
|
||||
/* If we don't have a local IP address, we get one by
|
||||
calling ip_route(). */
|
||||
if (ip_addr_isany(&(pcb->local_ip))) {
|
||||
|
@ -1092,11 +1094,6 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb)
|
|||
ip_addr_copy(pcb->local_ip, netif->ip_addr);
|
||||
}
|
||||
|
||||
/* Set retransmission timer running if it is not currently enabled */
|
||||
if(pcb->rtime == -1) {
|
||||
pcb->rtime = 0;
|
||||
}
|
||||
|
||||
if (pcb->rttest == 0) {
|
||||
pcb->rttest = tcp_ticks;
|
||||
pcb->rtseq = ntohl(seg->tcphdr->seqno);
|
||||
|
@ -1443,7 +1440,9 @@ tcp_zero_window_probe(struct tcp_pcb *pcb)
|
|||
TCPH_FLAGS_SET(tcphdr, TCP_ACK | TCP_FIN);
|
||||
} else {
|
||||
/* Data segment, copy in one byte from the head of the unacked queue */
|
||||
*((char *)p->payload + TCP_HLEN) = *(char *)seg->dataptr;
|
||||
struct tcp_hdr *thdr = (struct tcp_hdr *)seg->p->payload;
|
||||
char *d = ((char *)p->payload + TCP_HLEN);
|
||||
pbuf_copy_partial(seg->p, d, 1, TCPH_HDRLEN(thdr) * 4);
|
||||
}
|
||||
|
||||
#if CHECKSUM_GEN_TCP
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "lwip/opt.h"
|
||||
|
||||
#include "lwip/timers.h"
|
||||
#include "lwip/tcp_impl.h"
|
||||
|
||||
#if LWIP_TIMERS
|
||||
|
||||
|
@ -49,7 +50,6 @@
|
|||
#include "lwip/memp.h"
|
||||
#include "lwip/tcpip.h"
|
||||
|
||||
#include "lwip/tcp_impl.h"
|
||||
#include "lwip/ip_frag.h"
|
||||
#include "netif/etharp.h"
|
||||
#include "lwip/dhcp.h"
|
||||
|
|
|
@ -520,8 +520,10 @@ udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip,
|
|||
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: could not allocate header\n"));
|
||||
return ERR_MEM;
|
||||
}
|
||||
/* chain header q in front of given pbuf p */
|
||||
pbuf_chain(q, p);
|
||||
if (p->tot_len != 0) {
|
||||
/* chain header q in front of given pbuf p (only if p contains data) */
|
||||
pbuf_chain(q, p);
|
||||
}
|
||||
/* first pbuf q points to header pbuf */
|
||||
LWIP_DEBUGF(UDP_DEBUG,
|
||||
("udp_send: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p));
|
||||
|
@ -744,8 +746,10 @@ udp_bind(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port)
|
|||
/* no port specified? */
|
||||
if (port == 0) {
|
||||
#ifndef UDP_LOCAL_PORT_RANGE_START
|
||||
#define UDP_LOCAL_PORT_RANGE_START 4096
|
||||
#define UDP_LOCAL_PORT_RANGE_END 0x7fff
|
||||
/* From http://www.iana.org/assignments/port-numbers:
|
||||
"The Dynamic and/or Private Ports are those from 49152 through 65535" */
|
||||
#define UDP_LOCAL_PORT_RANGE_START 0xc000
|
||||
#define UDP_LOCAL_PORT_RANGE_END 0xffff
|
||||
#endif
|
||||
port = UDP_LOCAL_PORT_RANGE_START;
|
||||
ipcb = udp_pcbs;
|
||||
|
|
|
@ -41,29 +41,29 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ICMP_ER 0 /* echo reply */
|
||||
#define ICMP_DUR 3 /* destination unreachable */
|
||||
#define ICMP_SQ 4 /* source quench */
|
||||
#define ICMP_RD 5 /* redirect */
|
||||
#define ICMP_ER 0 /* echo reply */
|
||||
#define ICMP_DUR 3 /* destination unreachable */
|
||||
#define ICMP_SQ 4 /* source quench */
|
||||
#define ICMP_RD 5 /* redirect */
|
||||
#define ICMP_ECHO 8 /* echo */
|
||||
#define ICMP_TE 11 /* time exceeded */
|
||||
#define ICMP_PP 12 /* parameter problem */
|
||||
#define ICMP_TS 13 /* timestamp */
|
||||
#define ICMP_TE 11 /* time exceeded */
|
||||
#define ICMP_PP 12 /* parameter problem */
|
||||
#define ICMP_TS 13 /* timestamp */
|
||||
#define ICMP_TSR 14 /* timestamp reply */
|
||||
#define ICMP_IRQ 15 /* information request */
|
||||
#define ICMP_IR 16 /* information reply */
|
||||
#define ICMP_IR 16 /* information reply */
|
||||
|
||||
enum icmp_dur_type {
|
||||
ICMP_DUR_NET = 0, /* net unreachable */
|
||||
ICMP_DUR_HOST = 1, /* host unreachable */
|
||||
ICMP_DUR_NET = 0, /* net unreachable */
|
||||
ICMP_DUR_HOST = 1, /* host unreachable */
|
||||
ICMP_DUR_PROTO = 2, /* protocol unreachable */
|
||||
ICMP_DUR_PORT = 3, /* port unreachable */
|
||||
ICMP_DUR_FRAG = 4, /* fragmentation needed and DF set */
|
||||
ICMP_DUR_SR = 5 /* source route failed */
|
||||
ICMP_DUR_PORT = 3, /* port unreachable */
|
||||
ICMP_DUR_FRAG = 4, /* fragmentation needed and DF set */
|
||||
ICMP_DUR_SR = 5 /* source route failed */
|
||||
};
|
||||
|
||||
enum icmp_te_type {
|
||||
ICMP_TE_TTL = 0, /* time to live exceeded in transit */
|
||||
ICMP_TE_TTL = 0, /* time to live exceeded in transit */
|
||||
ICMP_TE_FRAG = 1 /* fragment reassembly time exceeded */
|
||||
};
|
||||
|
||||
|
|
|
@ -122,10 +122,10 @@ struct ip_hdr {
|
|||
PACK_STRUCT_FIELD(u16_t _id);
|
||||
/* fragment offset field */
|
||||
PACK_STRUCT_FIELD(u16_t _offset);
|
||||
#define IP_RF 0x8000 /* reserved fragment flag */
|
||||
#define IP_DF 0x4000 /* dont fragment flag */
|
||||
#define IP_MF 0x2000 /* more fragments flag */
|
||||
#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
|
||||
#define IP_RF 0x8000U /* reserved fragment flag */
|
||||
#define IP_DF 0x4000U /* dont fragment flag */
|
||||
#define IP_MF 0x2000U /* more fragments flag */
|
||||
#define IP_OFFMASK 0x1fffU /* mask for fragmenting bits */
|
||||
/* time to live */
|
||||
PACK_STRUCT_FIELD(u8_t _ttl);
|
||||
/* protocol*/
|
||||
|
|
|
@ -168,12 +168,11 @@ struct netconn {
|
|||
/** maximum amount of bytes queued in recvmbox
|
||||
not used for TCP: adjust TCP_WND instead! */
|
||||
int recv_bufsize;
|
||||
#endif /* LWIP_SO_RCVBUF */
|
||||
/** number of bytes currently in recvmbox to be received,
|
||||
tested against recv_bufsize to limit bytes on recvmbox
|
||||
for UDP and RAW
|
||||
@todo: should only be necessary with LWIP_SO_RCVBUF==1 */
|
||||
for UDP and RAW, used for FIONREAD */
|
||||
s16_t recv_avail;
|
||||
#endif /* LWIP_SO_RCVBUF */
|
||||
/** flags holding more netconn-internal state, see NETCONN_FLAG_* defines */
|
||||
u8_t flags;
|
||||
#if LWIP_TCP
|
||||
|
|
|
@ -48,9 +48,10 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* For the netconn API, these values are use as a bitmask! */
|
||||
#define NETCONN_SHUT_RD 1
|
||||
#define NETCONN_SHUT_WR 2
|
||||
#define NETCONN_SHUT_RDWR 3
|
||||
#define NETCONN_SHUT_RDWR (NETCONN_SHUT_RD | NETCONN_SHUT_WR)
|
||||
|
||||
/* IP addresses and port numbers are expected to be in
|
||||
* the same byte order as in the corresponding pcb.
|
||||
|
|
|
@ -74,8 +74,6 @@
|
|||
LWIP_PLATFORM_ASSERT(message); handler;}} while(0)
|
||||
#endif /* LWIP_ERROR */
|
||||
|
||||
#define LWIP_DEBUG
|
||||
|
||||
#ifdef LWIP_DEBUG
|
||||
/** print debug message only if debug message type is enabled...
|
||||
* AND is of correct type AND is at least LWIP_DBG_LEVEL
|
||||
|
|
|
@ -106,6 +106,9 @@ PACK_STRUCT_END
|
|||
#endif
|
||||
|
||||
void dhcp_set_struct(struct netif *netif, struct dhcp *dhcp);
|
||||
/** Remove a struct dhcp previously set to the netif using dhcp_set_struct() */
|
||||
#define dhcp_remove_struct(netif) do { (netif)->dhcp = NULL; } while(0)
|
||||
void dhcp_cleanup(struct netif *netif);
|
||||
/** start DHCP configuration */
|
||||
err_t dhcp_start(struct netif *netif);
|
||||
/** enforce early lease renewal (not needed normally)*/
|
||||
|
|
|
@ -38,6 +38,10 @@
|
|||
|
||||
#if LWIP_DNS /* don't build if not configured for use in lwipopts.h */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** DNS timer period */
|
||||
#define DNS_TMR_INTERVAL 1000
|
||||
|
||||
|
@ -111,6 +115,10 @@ int dns_local_removehost(const char *hostname, const ip_addr_t *addr)
|
|||
err_t dns_local_addhost(const char *hostname, const ip_addr_t *addr);
|
||||
#endif /* DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LWIP_DNS */
|
||||
|
||||
#endif /* __LWIP_DNS_H__ */
|
||||
|
|
|
@ -57,20 +57,19 @@ typedef s8_t err_t;
|
|||
#define ERR_INPROGRESS -5 /* Operation in progress */
|
||||
#define ERR_VAL -6 /* Illegal value. */
|
||||
#define ERR_WOULDBLOCK -7 /* Operation would block. */
|
||||
#define ERR_USE -8 /* Address in use. */
|
||||
#define ERR_ISCONN -9 /* Already connected. */
|
||||
|
||||
#define ERR_IS_FATAL(e) ((e) < ERR_VAL)
|
||||
#define ERR_IS_FATAL(e) ((e) < ERR_ISCONN)
|
||||
|
||||
#define ERR_ABRT -8 /* Connection aborted. */
|
||||
#define ERR_RST -9 /* Connection reset. */
|
||||
#define ERR_CLSD -10 /* Connection closed. */
|
||||
#define ERR_CONN -11 /* Not connected. */
|
||||
#define ERR_ABRT -10 /* Connection aborted. */
|
||||
#define ERR_RST -11 /* Connection reset. */
|
||||
#define ERR_CLSD -12 /* Connection closed. */
|
||||
#define ERR_CONN -13 /* Not connected. */
|
||||
|
||||
#define ERR_ARG -12 /* Illegal argument. */
|
||||
#define ERR_ARG -14 /* Illegal argument. */
|
||||
|
||||
#define ERR_USE -13 /* Address in use. */
|
||||
|
||||
#define ERR_IF -14 /* Low-level netif error */
|
||||
#define ERR_ISCONN -15 /* Already connected. */
|
||||
#define ERR_IF -15 /* Low-level netif error */
|
||||
|
||||
|
||||
#ifdef LWIP_DEBUG
|
||||
|
|
|
@ -47,7 +47,7 @@ extern "C" {
|
|||
/** For release candidates, this is set to 1..254
|
||||
* For official releases, this is set to 255 (LWIP_RC_RELEASE)
|
||||
* For development versions (CVS), this is set to 0 (LWIP_RC_DEVELOPMENT) */
|
||||
#define LWIP_VERSION_RC 1U
|
||||
#define LWIP_VERSION_RC 255U
|
||||
|
||||
/** LWIP_VERSION_RC is set to LWIP_RC_RELEASE for official releases */
|
||||
#define LWIP_RC_RELEASE 255U
|
||||
|
|
|
@ -68,7 +68,7 @@ typedef size_t mem_size_t;
|
|||
/* MEM_SIZE would have to be aligned, but using 64000 here instead of
|
||||
* 65535 leaves some room for alignment...
|
||||
*/
|
||||
#if MEM_SIZE > 64000l
|
||||
#if MEM_SIZE > 64000L
|
||||
typedef u32_t mem_size_t;
|
||||
#define MEM_SIZE_F U32_F
|
||||
#else
|
||||
|
|
|
@ -38,6 +38,10 @@
|
|||
#include "lwip/inet.h"
|
||||
#include "lwip/sockets.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* some rarely used options */
|
||||
#ifndef LWIP_DNS_API_DECLARE_H_ERRNO
|
||||
#define LWIP_DNS_API_DECLARE_H_ERRNO 1
|
||||
|
@ -111,6 +115,10 @@ int lwip_getaddrinfo(const char *nodename,
|
|||
lwip_getaddrinfo(nodname, servname, hints, res)
|
||||
#endif /* LWIP_COMPAT_SOCKETS */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LWIP_DNS && LWIP_SOCKET */
|
||||
|
||||
#endif /* __LWIP_NETDB_H__ */
|
||||
|
|
|
@ -432,11 +432,14 @@
|
|||
#endif
|
||||
|
||||
/**
|
||||
* ARP_QUEUEING==1: Outgoing packets are queued during hardware address
|
||||
* resolution.
|
||||
* ARP_QUEUEING==1: Multiple outgoing packets are queued during hardware address
|
||||
* resolution. By default, only the most recent packet is queued per IP address.
|
||||
* This is sufficient for most protocols and mainly reduces TCP connection
|
||||
* startup time. Set this to 1 if you know your application sends more than one
|
||||
* packet in a row to an IP address that is not in the ARP cache.
|
||||
*/
|
||||
#ifndef ARP_QUEUEING
|
||||
#define ARP_QUEUEING 1
|
||||
#define ARP_QUEUEING 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -954,7 +957,7 @@
|
|||
* as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work.
|
||||
*/
|
||||
#ifndef TCP_SND_QUEUELEN
|
||||
#define TCP_SND_QUEUELEN (4 * (TCP_SND_BUF)/(TCP_MSS))
|
||||
#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS))
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
|
|
@ -59,7 +59,7 @@ struct sockaddr_in {
|
|||
struct sockaddr {
|
||||
u8_t sa_len;
|
||||
u8_t sa_family;
|
||||
u16_t sa_data[14];
|
||||
char sa_data[14];
|
||||
};
|
||||
|
||||
#ifndef socklen_t
|
||||
|
@ -280,9 +280,9 @@ typedef struct ip_mreq {
|
|||
#endif
|
||||
|
||||
#ifndef SHUT_RD
|
||||
#define SHUT_RD 1
|
||||
#define SHUT_WR 2
|
||||
#define SHUT_RDWR 3
|
||||
#define SHUT_RD 0
|
||||
#define SHUT_WR 1
|
||||
#define SHUT_RDWR 2
|
||||
#endif
|
||||
|
||||
/* FD_SET used for lwip_select */
|
||||
|
|
|
@ -228,7 +228,7 @@ struct tcp_pcb {
|
|||
u16_t acked;
|
||||
|
||||
u16_t snd_buf; /* Available buffer space for sending (in bytes). */
|
||||
#define TCP_SNDQUEUELEN_OVERFLOW (0xffff-3)
|
||||
#define TCP_SNDQUEUELEN_OVERFLOW (0xffffU-3)
|
||||
u16_t snd_queuelen; /* Available buffer space for sending (in tcp_segs). */
|
||||
|
||||
#if TCP_OVERSIZE
|
||||
|
|
|
@ -278,7 +278,6 @@ PACK_STRUCT_END
|
|||
struct tcp_seg {
|
||||
struct tcp_seg *next; /* used when putting segements on a queue */
|
||||
struct pbuf *p; /* buffer containing data + TCP header */
|
||||
void *dataptr; /* pointer to the TCP data in the pbuf */
|
||||
u16_t len; /* the TCP length of this segment */
|
||||
#if TCP_OVERSIZE_DBGCHECK
|
||||
u16_t oversize_left; /* Extra bytes available at the end of the last
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
#define ARP_QUEUEING 0
|
||||
|
||||
#define ETH_PAD_SIZE 2
|
||||
|
||||
#define IP_FORWARD 0
|
||||
|
||||
#define IP_REASS_MAX_PBUFS 0xFFFFFFFF
|
||||
|
|
|
@ -94,8 +94,8 @@ PACK_STRUCT_BEGIN
|
|||
* if 'type' in ethernet header is ETHTYPE_VLAN.
|
||||
* See IEEE802.Q */
|
||||
struct eth_vlan_hdr {
|
||||
PACK_STRUCT_FIELD(u16_t tpid);
|
||||
PACK_STRUCT_FIELD(u16_t prio_vid);
|
||||
PACK_STRUCT_FIELD(u16_t tpid);
|
||||
} PACK_STRUCT_STRUCT;
|
||||
PACK_STRUCT_END
|
||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||
|
@ -134,11 +134,11 @@ PACK_STRUCT_END
|
|||
/** 5 seconds period */
|
||||
#define ARP_TMR_INTERVAL 5000
|
||||
|
||||
#define ETHTYPE_ARP 0x0806
|
||||
#define ETHTYPE_IP 0x0800
|
||||
#define ETHTYPE_VLAN 0x8100
|
||||
#define ETHTYPE_PPPOEDISC 0x8863 /* PPP Over Ethernet Discovery Stage */
|
||||
#define ETHTYPE_PPPOE 0x8864 /* PPP Over Ethernet Session Stage */
|
||||
#define ETHTYPE_ARP 0x0806U
|
||||
#define ETHTYPE_IP 0x0800U
|
||||
#define ETHTYPE_VLAN 0x8100U
|
||||
#define ETHTYPE_PPPOEDISC 0x8863U /* PPP Over Ethernet Discovery Stage */
|
||||
#define ETHTYPE_PPPOE 0x8864U /* PPP Over Ethernet Session Stage */
|
||||
|
||||
/** MEMCPY-like macro to copy to/from struct eth_addr's that are local variables
|
||||
* or known to be 32-bit aligned within the protocol header. */
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -97,7 +97,7 @@ void auth_check_options (void);
|
|||
void auth_reset (int);
|
||||
|
||||
/* Check peer-supplied username/password */
|
||||
int check_passwd (int, char *, int, char *, int, char **, int *);
|
||||
u_char check_passwd (int, char *, int, char *, int, char **, int *);
|
||||
|
||||
/* get "secret" for chap */
|
||||
int get_secret (int, char *, char *, char *, int *, int);
|
||||
|
|
|
@ -84,19 +84,25 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
/*************************/
|
||||
/*** LOCAL DEFINITIONS ***/
|
||||
/*************************/
|
||||
#if 0 /* UNUSED */
|
||||
/*
|
||||
* Command-line options.
|
||||
*/
|
||||
static option_t chap_option_list[] = {
|
||||
{ "chap-restart", o_int, &chap[0].timeouttime,
|
||||
"Set timeout for CHAP" },
|
||||
{ "chap-max-challenge", o_int, &chap[0].max_transmits,
|
||||
"Set max #xmits for challenge" },
|
||||
{ "chap-interval", o_int, &chap[0].chal_interval,
|
||||
"Set interval for rechallenge" },
|
||||
#ifdef MSLANMAN
|
||||
{ "ms-lanman", o_bool, &ms_lanman,
|
||||
"Use LanMan passwd when using MS-CHAP", 1 },
|
||||
#endif
|
||||
{ NULL }
|
||||
};
|
||||
#endif /* UNUSED */
|
||||
|
||||
|
||||
/************************/
|
||||
/*** LOCAL DATA TYPES ***/
|
||||
/************************/
|
||||
|
||||
|
||||
/***********************************/
|
||||
/*** LOCAL FUNCTION DECLARATIONS ***/
|
||||
/***********************************/
|
||||
/*
|
||||
* Protocol entry points.
|
||||
*/
|
||||
|
@ -105,28 +111,10 @@ static void ChapLowerUp (int);
|
|||
static void ChapLowerDown (int);
|
||||
static void ChapInput (int, u_char *, int);
|
||||
static void ChapProtocolReject (int);
|
||||
#if 0
|
||||
#if PPP_ADDITIONAL_CALLBACKS
|
||||
static int ChapPrintPkt (u_char *, int, void (*) (void *, char *, ...), void *);
|
||||
#endif
|
||||
|
||||
static void ChapChallengeTimeout (void *);
|
||||
static void ChapResponseTimeout (void *);
|
||||
static void ChapReceiveChallenge (chap_state *, u_char *, int, int);
|
||||
static void ChapRechallenge (void *);
|
||||
static void ChapReceiveResponse (chap_state *, u_char *, int, int);
|
||||
static void ChapReceiveSuccess(chap_state *cstate, u_char *inp, u_char id, int len);
|
||||
static void ChapReceiveFailure(chap_state *cstate, u_char *inp, u_char id, int len);
|
||||
static void ChapSendStatus (chap_state *, int);
|
||||
static void ChapSendChallenge (chap_state *);
|
||||
static void ChapSendResponse (chap_state *);
|
||||
static void ChapGenChallenge (chap_state *);
|
||||
|
||||
|
||||
/******************************/
|
||||
/*** PUBLIC DATA STRUCTURES ***/
|
||||
/******************************/
|
||||
chap_state chap[NUM_PPP]; /* CHAP state; one for each unit */
|
||||
|
||||
struct protent chap_protent = {
|
||||
PPP_CHAP,
|
||||
ChapInit,
|
||||
|
@ -136,29 +124,57 @@ struct protent chap_protent = {
|
|||
ChapLowerDown,
|
||||
NULL,
|
||||
NULL,
|
||||
#if 0
|
||||
#if PPP_ADDITIONAL_CALLBACKS
|
||||
ChapPrintPkt,
|
||||
NULL,
|
||||
#endif
|
||||
#endif /* PPP_ADDITIONAL_CALLBACKS */
|
||||
1,
|
||||
"CHAP",
|
||||
#if 0
|
||||
#if PPP_ADDITIONAL_CALLBACKS
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
#endif
|
||||
#endif /* PPP_ADDITIONAL_CALLBACKS */
|
||||
};
|
||||
|
||||
chap_state chap[NUM_PPP]; /* CHAP state; one for each unit */
|
||||
|
||||
static void ChapChallengeTimeout (void *);
|
||||
static void ChapResponseTimeout (void *);
|
||||
static void ChapReceiveChallenge (chap_state *, u_char *, u_char, int);
|
||||
static void ChapRechallenge (void *);
|
||||
static void ChapReceiveResponse (chap_state *, u_char *, int, int);
|
||||
static void ChapReceiveSuccess(chap_state *cstate, u_char *inp, u_char id, int len);
|
||||
static void ChapReceiveFailure(chap_state *cstate, u_char *inp, u_char id, int len);
|
||||
static void ChapSendStatus (chap_state *, int);
|
||||
static void ChapSendChallenge (chap_state *);
|
||||
static void ChapSendResponse (chap_state *);
|
||||
static void ChapGenChallenge (chap_state *);
|
||||
|
||||
/*
|
||||
* ChapInit - Initialize a CHAP unit.
|
||||
*/
|
||||
static void
|
||||
ChapInit(int unit)
|
||||
{
|
||||
chap_state *cstate = &chap[unit];
|
||||
|
||||
BZERO(cstate, sizeof(*cstate));
|
||||
cstate->unit = unit;
|
||||
cstate->clientstate = CHAPCS_INITIAL;
|
||||
cstate->serverstate = CHAPSS_INITIAL;
|
||||
cstate->timeouttime = CHAP_DEFTIMEOUT;
|
||||
cstate->max_transmits = CHAP_DEFTRANSMITS;
|
||||
/* random number generator is initialized in magic_init */
|
||||
}
|
||||
|
||||
|
||||
/***********************************/
|
||||
/*** PUBLIC FUNCTION DEFINITIONS ***/
|
||||
/***********************************/
|
||||
/*
|
||||
* ChapAuthWithPeer - Authenticate us with our peer (start client).
|
||||
*
|
||||
*/
|
||||
void
|
||||
ChapAuthWithPeer(int unit, char *our_name, int digest)
|
||||
ChapAuthWithPeer(int unit, char *our_name, u_char digest)
|
||||
{
|
||||
chap_state *cstate = &chap[unit];
|
||||
|
||||
|
@ -185,7 +201,7 @@ ChapAuthWithPeer(int unit, char *our_name, int digest)
|
|||
* ChapAuthPeer - Authenticate our peer (start server).
|
||||
*/
|
||||
void
|
||||
ChapAuthPeer(int unit, char *our_name, int digest)
|
||||
ChapAuthPeer(int unit, char *our_name, u_char digest)
|
||||
{
|
||||
chap_state *cstate = &chap[unit];
|
||||
|
||||
|
@ -205,27 +221,6 @@ ChapAuthPeer(int unit, char *our_name, int digest)
|
|||
}
|
||||
|
||||
|
||||
/**********************************/
|
||||
/*** LOCAL FUNCTION DEFINITIONS ***/
|
||||
/**********************************/
|
||||
/*
|
||||
* ChapInit - Initialize a CHAP unit.
|
||||
*/
|
||||
static void
|
||||
ChapInit(int unit)
|
||||
{
|
||||
chap_state *cstate = &chap[unit];
|
||||
|
||||
BZERO(cstate, sizeof(*cstate));
|
||||
cstate->unit = unit;
|
||||
cstate->clientstate = CHAPCS_INITIAL;
|
||||
cstate->serverstate = CHAPSS_INITIAL;
|
||||
cstate->timeouttime = CHAP_DEFTIMEOUT;
|
||||
cstate->max_transmits = CHAP_DEFTRANSMITS;
|
||||
/* random number generator is initialized in magic_init */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ChapChallengeTimeout - Timeout expired on sending challenge.
|
||||
*/
|
||||
|
@ -243,7 +238,7 @@ ChapChallengeTimeout(void *arg)
|
|||
|
||||
if (cstate->chal_transmits >= cstate->max_transmits) {
|
||||
/* give up on peer */
|
||||
CHAPDEBUG((LOG_ERR, "Peer failed to respond to CHAP challenge\n"));
|
||||
CHAPDEBUG(LOG_ERR, ("Peer failed to respond to CHAP challenge\n"));
|
||||
cstate->serverstate = CHAPSS_BADAUTH;
|
||||
auth_peer_fail(cstate->unit, PPP_CHAP);
|
||||
return;
|
||||
|
@ -355,7 +350,7 @@ ChapProtocolReject(int unit)
|
|||
}
|
||||
if (cstate->clientstate != CHAPCS_INITIAL &&
|
||||
cstate->clientstate != CHAPCS_CLOSED) {
|
||||
auth_withpeer_fail(unit, PPP_CHAP);
|
||||
auth_withpeer_fail(unit, PPP_CHAP); /* lwip: just sets the PPP error code on this unit to PPPERR_AUTHFAIL */
|
||||
}
|
||||
ChapLowerDown(unit); /* shutdown chap */
|
||||
}
|
||||
|
@ -378,18 +373,18 @@ ChapInput(int unit, u_char *inpacket, int packet_len)
|
|||
*/
|
||||
inp = inpacket;
|
||||
if (packet_len < CHAP_HEADERLEN) {
|
||||
CHAPDEBUG((LOG_INFO, "ChapInput: rcvd short header.\n"));
|
||||
CHAPDEBUG(LOG_INFO, ("ChapInput: rcvd short header.\n"));
|
||||
return;
|
||||
}
|
||||
GETCHAR(code, inp);
|
||||
GETCHAR(id, inp);
|
||||
GETSHORT(len, inp);
|
||||
if (len < CHAP_HEADERLEN) {
|
||||
CHAPDEBUG((LOG_INFO, "ChapInput: rcvd illegal length.\n"));
|
||||
CHAPDEBUG(LOG_INFO, ("ChapInput: rcvd illegal length.\n"));
|
||||
return;
|
||||
}
|
||||
if (len > packet_len) {
|
||||
CHAPDEBUG((LOG_INFO, "ChapInput: rcvd short packet.\n"));
|
||||
CHAPDEBUG(LOG_INFO, ("ChapInput: rcvd short packet.\n"));
|
||||
return;
|
||||
}
|
||||
len -= CHAP_HEADERLEN;
|
||||
|
@ -415,7 +410,7 @@ ChapInput(int unit, u_char *inpacket, int packet_len)
|
|||
break;
|
||||
|
||||
default: /* Need code reject? */
|
||||
CHAPDEBUG((LOG_WARNING, "Unknown CHAP code (%d) received.\n", code));
|
||||
CHAPDEBUG(LOG_WARNING, ("Unknown CHAP code (%d) received.\n", code));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -425,7 +420,7 @@ ChapInput(int unit, u_char *inpacket, int packet_len)
|
|||
* ChapReceiveChallenge - Receive Challenge and send Response.
|
||||
*/
|
||||
static void
|
||||
ChapReceiveChallenge(chap_state *cstate, u_char *inp, int id, int len)
|
||||
ChapReceiveChallenge(chap_state *cstate, u_char *inp, u_char id, int len)
|
||||
{
|
||||
int rchallenge_len;
|
||||
u_char *rchallenge;
|
||||
|
@ -434,48 +429,52 @@ ChapReceiveChallenge(chap_state *cstate, u_char *inp, int id, int len)
|
|||
char rhostname[256];
|
||||
MD5_CTX mdContext;
|
||||
u_char hash[MD5_SIGNATURE_SIZE];
|
||||
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: Rcvd id %d.\n", id));
|
||||
|
||||
CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: Rcvd id %d.\n", id));
|
||||
if (cstate->clientstate == CHAPCS_CLOSED ||
|
||||
cstate->clientstate == CHAPCS_PENDING) {
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: in state %d\n",
|
||||
CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: in state %d\n",
|
||||
cstate->clientstate));
|
||||
return;
|
||||
}
|
||||
|
||||
if (len < 2) {
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: rcvd short packet.\n"));
|
||||
CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: rcvd short packet.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
GETCHAR(rchallenge_len, inp);
|
||||
len -= sizeof (u_char) + rchallenge_len; /* now name field length */
|
||||
if (len < 0) {
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: rcvd short packet.\n"));
|
||||
CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: rcvd short packet.\n"));
|
||||
return;
|
||||
}
|
||||
rchallenge = inp;
|
||||
INCPTR(rchallenge_len, inp);
|
||||
|
||||
if (len >= sizeof(rhostname)) {
|
||||
if (len >= (int)sizeof(rhostname)) {
|
||||
len = sizeof(rhostname) - 1;
|
||||
}
|
||||
BCOPY(inp, rhostname, len);
|
||||
rhostname[len] = '\000';
|
||||
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: received name field '%s'\n", rhostname));
|
||||
CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: received name field '%s'\n",
|
||||
rhostname));
|
||||
|
||||
/* Microsoft doesn't send their name back in the PPP packet */
|
||||
if (ppp_settings.remote_name[0] != 0 && (ppp_settings.explicit_remote || rhostname[0] == 0)) {
|
||||
strncpy(rhostname, ppp_settings.remote_name, sizeof(rhostname));
|
||||
rhostname[sizeof(rhostname) - 1] = 0;
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: using '%s' as remote name\n", rhostname));
|
||||
CHAPDEBUG(LOG_INFO, ("ChapReceiveChallenge: using '%s' as remote name\n",
|
||||
rhostname));
|
||||
}
|
||||
|
||||
/* get secret for authenticating ourselves with the specified host */
|
||||
if (!get_secret(cstate->unit, cstate->resp_name, rhostname, secret, &secret_len, 0)) {
|
||||
if (!get_secret(cstate->unit, cstate->resp_name, rhostname,
|
||||
secret, &secret_len, 0)) {
|
||||
secret_len = 0; /* assume null secret if can't find one */
|
||||
CHAPDEBUG((LOG_WARNING, "No CHAP secret found for authenticating us to %s\n", rhostname));
|
||||
CHAPDEBUG(LOG_WARNING, ("No CHAP secret found for authenticating us to %s\n",
|
||||
rhostname));
|
||||
}
|
||||
|
||||
/* cancel response send timeout if necessary */
|
||||
|
@ -499,14 +498,14 @@ ChapReceiveChallenge(chap_state *cstate, u_char *inp, int id, int len)
|
|||
cstate->resp_length = MD5_SIGNATURE_SIZE;
|
||||
break;
|
||||
|
||||
#ifdef CHAPMS
|
||||
#if MSCHAP_SUPPORT
|
||||
case CHAP_MICROSOFT:
|
||||
ChapMS(cstate, rchallenge, rchallenge_len, secret, secret_len);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
CHAPDEBUG((LOG_INFO, "unknown digest type %d\n", cstate->resp_type));
|
||||
CHAPDEBUG(LOG_INFO, ("unknown digest type %d\n", cstate->resp_type));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -528,12 +527,12 @@ ChapReceiveResponse(chap_state *cstate, u_char *inp, int id, int len)
|
|||
MD5_CTX mdContext;
|
||||
char secret[MAXSECRETLEN];
|
||||
u_char hash[MD5_SIGNATURE_SIZE];
|
||||
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: Rcvd id %d.\n", id));
|
||||
|
||||
CHAPDEBUG(LOG_INFO, ("ChapReceiveResponse: Rcvd id %d.\n", id));
|
||||
|
||||
if (cstate->serverstate == CHAPSS_CLOSED ||
|
||||
cstate->serverstate == CHAPSS_PENDING) {
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: in state %d\n",
|
||||
CHAPDEBUG(LOG_INFO, ("ChapReceiveResponse: in state %d\n",
|
||||
cstate->serverstate));
|
||||
return;
|
||||
}
|
||||
|
@ -557,7 +556,7 @@ ChapReceiveResponse(chap_state *cstate, u_char *inp, int id, int len)
|
|||
}
|
||||
|
||||
if (len < 2) {
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: rcvd short packet.\n"));
|
||||
CHAPDEBUG(LOG_INFO, ("ChapReceiveResponse: rcvd short packet.\n"));
|
||||
return;
|
||||
}
|
||||
GETCHAR(remmd_len, inp); /* get length of MD */
|
||||
|
@ -566,29 +565,30 @@ ChapReceiveResponse(chap_state *cstate, u_char *inp, int id, int len)
|
|||
|
||||
len -= sizeof (u_char) + remmd_len;
|
||||
if (len < 0) {
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: rcvd short packet.\n"));
|
||||
CHAPDEBUG(LOG_INFO, ("ChapReceiveResponse: rcvd short packet.\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
UNTIMEOUT(ChapChallengeTimeout, cstate);
|
||||
|
||||
if (len >= sizeof(rhostname)) {
|
||||
if (len >= (int)sizeof(rhostname)) {
|
||||
len = sizeof(rhostname) - 1;
|
||||
}
|
||||
BCOPY(inp, rhostname, len);
|
||||
rhostname[len] = '\000';
|
||||
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveResponse: received name field: %s\n", rhostname));
|
||||
CHAPDEBUG(LOG_INFO, ("ChapReceiveResponse: received name field: %s\n",
|
||||
rhostname));
|
||||
|
||||
/*
|
||||
* Get secret for authenticating them with us,
|
||||
* do the hash ourselves, and compare the result.
|
||||
*/
|
||||
code = CHAP_FAILURE;
|
||||
if (!get_secret(cstate->unit, rhostname, cstate->chal_name, secret, &secret_len, 1)) {
|
||||
/* CHAPDEBUG((LOG_WARNING, TL_CHAP, "No CHAP secret found for authenticating %s\n", rhostname)); */
|
||||
CHAPDEBUG((LOG_WARNING, "No CHAP secret found for authenticating %s\n",
|
||||
rhostname));
|
||||
if (!get_secret(cstate->unit, rhostname, cstate->chal_name,
|
||||
secret, &secret_len, 1)) {
|
||||
CHAPDEBUG(LOG_WARNING, ("No CHAP secret found for authenticating %s\n",
|
||||
rhostname));
|
||||
} else {
|
||||
/* generate MD based on negotiated type */
|
||||
switch (cstate->chal_type) {
|
||||
|
@ -610,7 +610,7 @@ ChapReceiveResponse(chap_state *cstate, u_char *inp, int id, int len)
|
|||
break;
|
||||
|
||||
default:
|
||||
CHAPDEBUG((LOG_INFO, "unknown digest type %d\n", cstate->chal_type));
|
||||
CHAPDEBUG(LOG_INFO, ("unknown digest type %d\n", cstate->chal_type));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -627,7 +627,7 @@ ChapReceiveResponse(chap_state *cstate, u_char *inp, int id, int len)
|
|||
TIMEOUT(ChapRechallenge, cstate, cstate->chal_interval);
|
||||
}
|
||||
} else {
|
||||
CHAPDEBUG((LOG_ERR, "CHAP peer authentication failed\n"));
|
||||
CHAPDEBUG(LOG_ERR, ("CHAP peer authentication failed\n"));
|
||||
cstate->serverstate = CHAPSS_BADAUTH;
|
||||
auth_peer_fail(cstate->unit, PPP_CHAP);
|
||||
}
|
||||
|
@ -642,7 +642,7 @@ ChapReceiveSuccess(chap_state *cstate, u_char *inp, u_char id, int len)
|
|||
LWIP_UNUSED_ARG(id);
|
||||
LWIP_UNUSED_ARG(inp);
|
||||
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveSuccess: Rcvd id %d.\n", id));
|
||||
CHAPDEBUG(LOG_INFO, ("ChapReceiveSuccess: Rcvd id %d.\n", id));
|
||||
|
||||
if (cstate->clientstate == CHAPCS_OPEN) {
|
||||
/* presumably an answer to a duplicate response */
|
||||
|
@ -651,7 +651,8 @@ ChapReceiveSuccess(chap_state *cstate, u_char *inp, u_char id, int len)
|
|||
|
||||
if (cstate->clientstate != CHAPCS_RESPONSE) {
|
||||
/* don't know what this is */
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveSuccess: in state %d\n", cstate->clientstate));
|
||||
CHAPDEBUG(LOG_INFO, ("ChapReceiveSuccess: in state %d\n",
|
||||
cstate->clientstate));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -679,11 +680,12 @@ ChapReceiveFailure(chap_state *cstate, u_char *inp, u_char id, int len)
|
|||
LWIP_UNUSED_ARG(id);
|
||||
LWIP_UNUSED_ARG(inp);
|
||||
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveFailure: Rcvd id %d.\n", id));
|
||||
CHAPDEBUG(LOG_INFO, ("ChapReceiveFailure: Rcvd id %d.\n", id));
|
||||
|
||||
if (cstate->clientstate != CHAPCS_RESPONSE) {
|
||||
/* don't know what this is */
|
||||
CHAPDEBUG((LOG_INFO, "ChapReceiveFailure: in state %d\n", cstate->clientstate));
|
||||
CHAPDEBUG(LOG_INFO, ("ChapReceiveFailure: in state %d\n",
|
||||
cstate->clientstate));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -696,8 +698,8 @@ ChapReceiveFailure(chap_state *cstate, u_char *inp, u_char id, int len)
|
|||
PRINTMSG(inp, len);
|
||||
}
|
||||
|
||||
CHAPDEBUG((LOG_ERR, "CHAP authentication failed\n"));
|
||||
auth_withpeer_fail(cstate->unit, PPP_CHAP);
|
||||
CHAPDEBUG(LOG_ERR, ("CHAP authentication failed\n"));
|
||||
auth_withpeer_fail(cstate->unit, PPP_CHAP); /* lwip: just sets the PPP error code on this unit to PPPERR_AUTHFAIL */
|
||||
}
|
||||
|
||||
|
||||
|
@ -712,25 +714,25 @@ ChapSendChallenge(chap_state *cstate)
|
|||
int outlen;
|
||||
|
||||
chal_len = cstate->chal_len;
|
||||
name_len = strlen(cstate->chal_name);
|
||||
name_len = (int)strlen(cstate->chal_name);
|
||||
outlen = CHAP_HEADERLEN + sizeof (u_char) + chal_len + name_len;
|
||||
outp = outpacket_buf[cstate->unit];
|
||||
|
||||
|
||||
MAKEHEADER(outp, PPP_CHAP); /* paste in a CHAP header */
|
||||
|
||||
|
||||
PUTCHAR(CHAP_CHALLENGE, outp);
|
||||
PUTCHAR(cstate->chal_id, outp);
|
||||
PUTSHORT(outlen, outp);
|
||||
|
||||
|
||||
PUTCHAR(chal_len, outp); /* put length of challenge */
|
||||
BCOPY(cstate->challenge, outp, chal_len);
|
||||
INCPTR(chal_len, outp);
|
||||
|
||||
|
||||
BCOPY(cstate->chal_name, outp, name_len); /* append hostname */
|
||||
|
||||
pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN);
|
||||
|
||||
CHAPDEBUG((LOG_INFO, "ChapSendChallenge: Sent id %d.\n", cstate->chal_id));
|
||||
|
||||
CHAPDEBUG(LOG_INFO, ("ChapSendChallenge: Sent id %d.\n", cstate->chal_id));
|
||||
|
||||
TIMEOUT(ChapChallengeTimeout, cstate, cstate->timeouttime);
|
||||
++cstate->chal_transmits;
|
||||
|
@ -745,18 +747,18 @@ ChapSendStatus(chap_state *cstate, int code)
|
|||
{
|
||||
u_char *outp;
|
||||
int outlen, msglen;
|
||||
char msg[256];
|
||||
|
||||
char msg[256]; /* @todo: this can be a char*, no strcpy needed */
|
||||
|
||||
if (code == CHAP_SUCCESS) {
|
||||
strcpy(msg, "Welcome!");
|
||||
} else {
|
||||
strcpy(msg, "I don't like you. Go 'way.");
|
||||
}
|
||||
msglen = strlen(msg);
|
||||
|
||||
msglen = (int)strlen(msg);
|
||||
|
||||
outlen = CHAP_HEADERLEN + msglen;
|
||||
outp = outpacket_buf[cstate->unit];
|
||||
|
||||
|
||||
MAKEHEADER(outp, PPP_CHAP); /* paste in a header */
|
||||
|
||||
PUTCHAR(code, outp);
|
||||
|
@ -764,8 +766,9 @@ ChapSendStatus(chap_state *cstate, int code)
|
|||
PUTSHORT(outlen, outp);
|
||||
BCOPY(msg, outp, msglen);
|
||||
pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN);
|
||||
|
||||
CHAPDEBUG((LOG_INFO, "ChapSendStatus: Sent code %d, id %d.\n", code, cstate->chal_id));
|
||||
|
||||
CHAPDEBUG(LOG_INFO, ("ChapSendStatus: Sent code %d, id %d.\n", code,
|
||||
cstate->chal_id));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -781,17 +784,18 @@ ChapGenChallenge(chap_state *cstate)
|
|||
int chal_len;
|
||||
u_char *ptr = cstate->challenge;
|
||||
int i;
|
||||
|
||||
|
||||
/* pick a random challenge length between MIN_CHALLENGE_LENGTH and
|
||||
MAX_CHALLENGE_LENGTH */
|
||||
chal_len = (unsigned)
|
||||
((((magic() >> 16) *
|
||||
(MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) >> 16)
|
||||
+ MIN_CHALLENGE_LENGTH);
|
||||
cstate->chal_len = chal_len;
|
||||
LWIP_ASSERT("chal_len <= 0xff", chal_len <= 0xffff);
|
||||
cstate->chal_len = (u_char)chal_len;
|
||||
cstate->chal_id = ++cstate->id;
|
||||
cstate->chal_transmits = 0;
|
||||
|
||||
|
||||
/* generate a random string */
|
||||
for (i = 0; i < chal_len; i++ ) {
|
||||
*ptr++ = (char) (magic() & 0xff);
|
||||
|
@ -808,12 +812,12 @@ ChapSendResponse(chap_state *cstate)
|
|||
{
|
||||
u_char *outp;
|
||||
int outlen, md_len, name_len;
|
||||
|
||||
|
||||
md_len = cstate->resp_length;
|
||||
name_len = strlen(cstate->resp_name);
|
||||
name_len = (int)strlen(cstate->resp_name);
|
||||
outlen = CHAP_HEADERLEN + sizeof (u_char) + md_len + name_len;
|
||||
outp = outpacket_buf[cstate->unit];
|
||||
|
||||
|
||||
MAKEHEADER(outp, PPP_CHAP);
|
||||
|
||||
PUTCHAR(CHAP_RESPONSE, outp); /* we are a response */
|
||||
|
@ -823,18 +827,18 @@ ChapSendResponse(chap_state *cstate)
|
|||
PUTCHAR(md_len, outp); /* length of MD */
|
||||
BCOPY(cstate->response, outp, md_len); /* copy MD to buffer */
|
||||
INCPTR(md_len, outp);
|
||||
|
||||
|
||||
BCOPY(cstate->resp_name, outp, name_len); /* append our name */
|
||||
|
||||
|
||||
/* send the packet */
|
||||
pppWrite(cstate->unit, outpacket_buf[cstate->unit], outlen + PPP_HDRLEN);
|
||||
|
||||
|
||||
cstate->clientstate = CHAPCS_RESPONSE;
|
||||
TIMEOUT(ChapResponseTimeout, cstate, cstate->timeouttime);
|
||||
++cstate->resp_transmits;
|
||||
}
|
||||
|
||||
#if 0
|
||||
#if PPP_ADDITIONAL_CALLBACKS
|
||||
static char *ChapCodenames[] = {
|
||||
"Challenge", "Response", "Success", "Failure"
|
||||
};
|
||||
|
@ -847,7 +851,7 @@ ChapPrintPkt( u_char *p, int plen, void (*printer) (void *, char *, ...), void *
|
|||
int code, id, len;
|
||||
int clen, nlen;
|
||||
u_char x;
|
||||
|
||||
|
||||
if (plen < CHAP_HEADERLEN) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -857,6 +861,7 @@ ChapPrintPkt( u_char *p, int plen, void (*printer) (void *, char *, ...), void *
|
|||
if (len < CHAP_HEADERLEN || len > plen) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (code >= 1 && code <= sizeof(ChapCodenames) / sizeof(char *)) {
|
||||
printer(arg, " %s", ChapCodenames[code-1]);
|
||||
} else {
|
||||
|
@ -896,7 +901,7 @@ ChapPrintPkt( u_char *p, int plen, void (*printer) (void *, char *, ...), void *
|
|||
|
||||
return len + CHAP_HEADERLEN;
|
||||
}
|
||||
#endif
|
||||
#endif /* PPP_ADDITIONAL_CALLBACKS */
|
||||
|
||||
#endif /* CHAP_SUPPORT */
|
||||
|
||||
|
|
|
@ -62,16 +62,12 @@
|
|||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: chap.h,v 1.4 2007/12/19 20:47:22 fbernon Exp $
|
||||
* $Id: chap.h,v 1.6 2010/01/24 13:19:34 goldsimon Exp $
|
||||
*/
|
||||
|
||||
#ifndef CHAP_H
|
||||
#define CHAP_H
|
||||
|
||||
/*************************
|
||||
*** PUBLIC DEFINITIONS ***
|
||||
*************************/
|
||||
|
||||
/* Code + ID + length */
|
||||
#define CHAP_HEADERLEN 4
|
||||
|
||||
|
@ -96,31 +92,6 @@
|
|||
#define MAX_CHALLENGE_LENGTH 64
|
||||
#define MAX_RESPONSE_LENGTH 64 /* sufficient for MD5 or MS-CHAP */
|
||||
|
||||
/*
|
||||
* Client (peer) states.
|
||||
*/
|
||||
#define CHAPCS_INITIAL 0 /* Lower layer down, not opened */
|
||||
#define CHAPCS_CLOSED 1 /* Lower layer up, not opened */
|
||||
#define CHAPCS_PENDING 2 /* Auth us to peer when lower up */
|
||||
#define CHAPCS_LISTEN 3 /* Listening for a challenge */
|
||||
#define CHAPCS_RESPONSE 4 /* Sent response, waiting for status */
|
||||
#define CHAPCS_OPEN 5 /* We've received Success */
|
||||
|
||||
/*
|
||||
* Server (authenticator) states.
|
||||
*/
|
||||
#define CHAPSS_INITIAL 0 /* Lower layer down, not opened */
|
||||
#define CHAPSS_CLOSED 1 /* Lower layer up, not opened */
|
||||
#define CHAPSS_PENDING 2 /* Auth peer when lower up */
|
||||
#define CHAPSS_INITIAL_CHAL 3 /* We've sent the first challenge */
|
||||
#define CHAPSS_OPEN 4 /* We've sent a Success msg */
|
||||
#define CHAPSS_RECHALLENGE 5 /* We've sent another challenge */
|
||||
#define CHAPSS_BADAUTH 6 /* We've sent a Failure msg */
|
||||
|
||||
/************************
|
||||
*** PUBLIC DATA TYPES ***
|
||||
************************/
|
||||
|
||||
/*
|
||||
* Each interface is described by a chap structure.
|
||||
*/
|
||||
|
@ -148,19 +119,32 @@ typedef struct chap_state {
|
|||
} chap_state;
|
||||
|
||||
|
||||
/******************
|
||||
*** PUBLIC DATA ***
|
||||
******************/
|
||||
/*
|
||||
* Client (peer) states.
|
||||
*/
|
||||
#define CHAPCS_INITIAL 0 /* Lower layer down, not opened */
|
||||
#define CHAPCS_CLOSED 1 /* Lower layer up, not opened */
|
||||
#define CHAPCS_PENDING 2 /* Auth us to peer when lower up */
|
||||
#define CHAPCS_LISTEN 3 /* Listening for a challenge */
|
||||
#define CHAPCS_RESPONSE 4 /* Sent response, waiting for status */
|
||||
#define CHAPCS_OPEN 5 /* We've received Success */
|
||||
|
||||
/*
|
||||
* Server (authenticator) states.
|
||||
*/
|
||||
#define CHAPSS_INITIAL 0 /* Lower layer down, not opened */
|
||||
#define CHAPSS_CLOSED 1 /* Lower layer up, not opened */
|
||||
#define CHAPSS_PENDING 2 /* Auth peer when lower up */
|
||||
#define CHAPSS_INITIAL_CHAL 3 /* We've sent the first challenge */
|
||||
#define CHAPSS_OPEN 4 /* We've sent a Success msg */
|
||||
#define CHAPSS_RECHALLENGE 5 /* We've sent another challenge */
|
||||
#define CHAPSS_BADAUTH 6 /* We've sent a Failure msg */
|
||||
|
||||
extern chap_state chap[];
|
||||
|
||||
void ChapAuthWithPeer (int, char *, u_char);
|
||||
void ChapAuthPeer (int, char *, u_char);
|
||||
|
||||
extern struct protent chap_protent;
|
||||
|
||||
|
||||
/***********************
|
||||
*** PUBLIC FUNCTIONS ***
|
||||
***********************/
|
||||
|
||||
void ChapAuthWithPeer (int, char *, int);
|
||||
void ChapAuthPeer (int, char *, int);
|
||||
|
||||
#endif /* CHAP_H */
|
||||
|
|
|
@ -85,6 +85,8 @@
|
|||
#include "chap.h"
|
||||
#include "chpms.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/*************************/
|
||||
/*** LOCAL DEFINITIONS ***/
|
||||
|
@ -137,49 +139,12 @@ static u_char Get7Bits(
|
|||
int startBit
|
||||
);
|
||||
|
||||
|
||||
/***********************************/
|
||||
/*** PUBLIC FUNCTION DEFINITIONS ***/
|
||||
/***********************************/
|
||||
void
|
||||
ChapMS( chap_state *cstate, char *rchallenge, int rchallenge_len, char *secret, int secret_len)
|
||||
{
|
||||
MS_ChapResponse response;
|
||||
#ifdef MSLANMAN
|
||||
extern int ms_lanman;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
CHAPDEBUG((LOG_INFO, "ChapMS: secret is '%.*s'\n", secret_len, secret));
|
||||
#endif
|
||||
BZERO(&response, sizeof(response));
|
||||
|
||||
/* Calculate both always */
|
||||
ChapMS_NT(rchallenge, rchallenge_len, secret, secret_len, &response);
|
||||
|
||||
#ifdef MSLANMAN
|
||||
ChapMS_LANMan(rchallenge, rchallenge_len, secret, secret_len, &response);
|
||||
|
||||
/* prefered method is set by option */
|
||||
response.UseNT = !ms_lanman;
|
||||
#else
|
||||
response.UseNT = 1;
|
||||
#endif
|
||||
|
||||
BCOPY(&response, cstate->response, MS_CHAP_RESPONSE_LEN);
|
||||
cstate->resp_length = MS_CHAP_RESPONSE_LEN;
|
||||
}
|
||||
|
||||
|
||||
/**********************************/
|
||||
/*** LOCAL FUNCTION DEFINITIONS ***/
|
||||
/**********************************/
|
||||
static void
|
||||
ChallengeResponse( u_char *challenge, /* IN 8 octets */
|
||||
u_char *pwHash, /* IN 16 octets */
|
||||
u_char *response /* OUT 24 octets */)
|
||||
{
|
||||
char ZPasswordHash[21];
|
||||
u_char ZPasswordHash[21];
|
||||
|
||||
BZERO(ZPasswordHash, sizeof(ZPasswordHash));
|
||||
BCOPY(pwHash, ZPasswordHash, 16);
|
||||
|
@ -211,19 +176,19 @@ DesEncrypt( u_char *clear, /* IN 8 octets */
|
|||
MakeKey(key, des_key);
|
||||
|
||||
Expand(des_key, crypt_key);
|
||||
setkey(crypt_key);
|
||||
setkey((char*)crypt_key);
|
||||
|
||||
#if 0
|
||||
CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet input : %02X%02X%02X%02X%02X%02X%02X%02X\n",
|
||||
CHAPDEBUG(LOG_INFO, ("DesEncrypt: 8 octet input : %02X%02X%02X%02X%02X%02X%02X%02X\n",
|
||||
clear[0], clear[1], clear[2], clear[3], clear[4], clear[5], clear[6], clear[7]));
|
||||
#endif
|
||||
|
||||
Expand(clear, des_input);
|
||||
encrypt(des_input, 0);
|
||||
encrypt((char*)des_input, 0);
|
||||
Collapse(des_input, cipher);
|
||||
|
||||
#if 0
|
||||
CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet output: %02X%02X%02X%02X%02X%02X%02X%02X\n",
|
||||
CHAPDEBUG(LOG_INFO, ("DesEncrypt: 8 octet output: %02X%02X%02X%02X%02X%02X%02X%02X\n",
|
||||
cipher[0], cipher[1], cipher[2], cipher[3], cipher[4], cipher[5], cipher[6], cipher[7]));
|
||||
#endif
|
||||
}
|
||||
|
@ -243,14 +208,14 @@ DesEncrypt( u_char *clear, /* IN 8 octets */
|
|||
des_set_key(&des_key, key_schedule);
|
||||
|
||||
#if 0
|
||||
CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet input : %02X%02X%02X%02X%02X%02X%02X%02X\n",
|
||||
CHAPDEBUG(LOG_INFO, ("DesEncrypt: 8 octet input : %02X%02X%02X%02X%02X%02X%02X%02X\n",
|
||||
clear[0], clear[1], clear[2], clear[3], clear[4], clear[5], clear[6], clear[7]));
|
||||
#endif
|
||||
|
||||
des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, key_schedule, 1);
|
||||
|
||||
#if 0
|
||||
CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet output: %02X%02X%02X%02X%02X%02X%02X%02X\n",
|
||||
CHAPDEBUG(LOG_INFO, ("DesEncrypt: 8 octet output: %02X%02X%02X%02X%02X%02X%02X%02X\n",
|
||||
cipher[0], cipher[1], cipher[2], cipher[3], cipher[4], cipher[5], cipher[6], cipher[7]));
|
||||
#endif
|
||||
}
|
||||
|
@ -329,9 +294,9 @@ MakeKey( u_char *key, /* IN 56 bit DES key missing parity bits */
|
|||
#endif
|
||||
|
||||
#if 0
|
||||
CHAPDEBUG((LOG_INFO, "MakeKey: 56-bit input : %02X%02X%02X%02X%02X%02X%02X\n",
|
||||
CHAPDEBUG(LOG_INFO, ("MakeKey: 56-bit input : %02X%02X%02X%02X%02X%02X%02X\n",
|
||||
key[0], key[1], key[2], key[3], key[4], key[5], key[6]));
|
||||
CHAPDEBUG((LOG_INFO, "MakeKey: 64-bit output: %02X%02X%02X%02X%02X%02X%02X%02X\n",
|
||||
CHAPDEBUG(LOG_INFO, ("MakeKey: 64-bit output: %02X%02X%02X%02X%02X%02X%02X%02X\n",
|
||||
des_key[0], des_key[1], des_key[2], des_key[3], des_key[4], des_key[5], des_key[6], des_key[7]));
|
||||
#endif
|
||||
}
|
||||
|
@ -348,6 +313,8 @@ ChapMS_NT( char *rchallenge,
|
|||
u_char unicodePassword[MAX_NT_PASSWORD * 2];
|
||||
static int low_byte_first = -1;
|
||||
|
||||
LWIP_UNUSED_ARG(rchallenge_len);
|
||||
|
||||
/* Initialize the Unicode version of the secret (== password). */
|
||||
/* This implicitly supports 8-bit ISO8859/1 characters. */
|
||||
BZERO(unicodePassword, sizeof(unicodePassword));
|
||||
|
@ -358,15 +325,16 @@ ChapMS_NT( char *rchallenge,
|
|||
MDupdate(&md4Context, unicodePassword, secret_len * 2 * 8); /* Unicode is 2 bytes/char, *8 for bit count */
|
||||
|
||||
if (low_byte_first == -1) {
|
||||
low_byte_first = (htons((unsigned short int)1) != 1);
|
||||
low_byte_first = (PP_HTONS((unsigned short int)1) != 1);
|
||||
}
|
||||
if (low_byte_first == 0) {
|
||||
MDreverse((u_long *)&md4Context); /* sfb 961105 */
|
||||
/* @todo: arg type - u_long* or u_int* ? */
|
||||
MDreverse((unsigned int*)&md4Context); /* sfb 961105 */
|
||||
}
|
||||
|
||||
MDupdate(&md4Context, NULL, 0); /* Tell MD4 we're done */
|
||||
|
||||
ChallengeResponse(rchallenge, (char *)md4Context.buffer, response->NTResp);
|
||||
ChallengeResponse((u_char*)rchallenge, (u_char*)md4Context.buffer, response->NTResp);
|
||||
}
|
||||
|
||||
#ifdef MSLANMAN
|
||||
|
@ -394,6 +362,35 @@ ChapMS_LANMan( char *rchallenge,
|
|||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
ChapMS( chap_state *cstate, char *rchallenge, int rchallenge_len, char *secret, int secret_len)
|
||||
{
|
||||
MS_ChapResponse response;
|
||||
#ifdef MSLANMAN
|
||||
extern int ms_lanman;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
CHAPDEBUG(LOG_INFO, ("ChapMS: secret is '%.*s'\n", secret_len, secret));
|
||||
#endif
|
||||
BZERO(&response, sizeof(response));
|
||||
|
||||
/* Calculate both always */
|
||||
ChapMS_NT(rchallenge, rchallenge_len, secret, secret_len, &response);
|
||||
|
||||
#ifdef MSLANMAN
|
||||
ChapMS_LANMan(rchallenge, rchallenge_len, secret, secret_len, &response);
|
||||
|
||||
/* prefered method is set by option */
|
||||
response.UseNT = !ms_lanman;
|
||||
#else
|
||||
response.UseNT = 1;
|
||||
#endif
|
||||
|
||||
BCOPY(&response, cstate->response, MS_CHAP_RESPONSE_LEN);
|
||||
cstate->resp_length = MS_CHAP_RESPONSE_LEN;
|
||||
}
|
||||
|
||||
#endif /* MSCHAP_SUPPORT */
|
||||
|
||||
#endif /* PPP_SUPPORT */
|
||||
|
|
|
@ -66,13 +66,7 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/*************************/
|
||||
/*** LOCAL DEFINITIONS ***/
|
||||
/*************************/
|
||||
|
||||
#if PPP_DEBUG
|
||||
|
||||
static const char *ppperr_strerr[] = {
|
||||
"LS_INITIAL", /* LS_INITIAL 0 */
|
||||
"LS_STARTING", /* LS_STARTING 1 */
|
||||
|
@ -85,17 +79,8 @@ static const char *ppperr_strerr[] = {
|
|||
"LS_ACKSENT", /* LS_ACKSENT 8 */
|
||||
"LS_OPENED" /* LS_OPENED 9 */
|
||||
};
|
||||
|
||||
#endif /* PPP_DEBUG */
|
||||
|
||||
/************************/
|
||||
/*** LOCAL DATA TYPES ***/
|
||||
/************************/
|
||||
|
||||
|
||||
/***********************************/
|
||||
/*** LOCAL FUNCTION DECLARATIONS ***/
|
||||
/***********************************/
|
||||
static void fsm_timeout (void *);
|
||||
static void fsm_rconfreq (fsm *, u_char, u_char *, int);
|
||||
static void fsm_rconfack (fsm *, int, u_char *, int);
|
||||
|
@ -107,22 +92,9 @@ static void fsm_sconfreq (fsm *, int);
|
|||
|
||||
#define PROTO_NAME(f) ((f)->callbacks->proto_name)
|
||||
|
||||
|
||||
/******************************/
|
||||
/*** PUBLIC DATA STRUCTURES ***/
|
||||
/******************************/
|
||||
|
||||
|
||||
/*****************************/
|
||||
/*** LOCAL DATA STRUCTURES ***/
|
||||
/*****************************/
|
||||
int peer_mru[NUM_PPP];
|
||||
|
||||
|
||||
/***********************************/
|
||||
/*** PUBLIC FUNCTION DEFINITIONS ***/
|
||||
/***********************************/
|
||||
|
||||
/*
|
||||
* fsm_init - Initialize fsm.
|
||||
*
|
||||
|
@ -168,11 +140,11 @@ fsm_lowerup(fsm *f)
|
|||
break;
|
||||
|
||||
default:
|
||||
FSMDEBUG((LOG_INFO, "%s: Up event in state %d (%s)!\n",
|
||||
FSMDEBUG(LOG_INFO, ("%s: Up event in state %d (%s)!\n",
|
||||
PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
|
||||
}
|
||||
|
||||
FSMDEBUG((LOG_INFO, "%s: lowerup state %d (%s) -> %d (%s)\n",
|
||||
|
||||
FSMDEBUG(LOG_INFO, ("%s: lowerup state %d (%s) -> %d (%s)\n",
|
||||
PROTO_NAME(f), oldState, ppperr_strerr[oldState], f->state, ppperr_strerr[f->state]));
|
||||
}
|
||||
|
||||
|
@ -222,11 +194,11 @@ fsm_lowerdown(fsm *f)
|
|||
break;
|
||||
|
||||
default:
|
||||
FSMDEBUG((LOG_INFO, "%s: Down event in state %d (%s)!\n",
|
||||
FSMDEBUG(LOG_INFO, ("%s: Down event in state %d (%s)!\n",
|
||||
PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
|
||||
}
|
||||
|
||||
FSMDEBUG((LOG_INFO, "%s: lowerdown state %d (%s) -> %d (%s)\n",
|
||||
FSMDEBUG(LOG_INFO, ("%s: lowerdown state %d (%s) -> %d (%s)\n",
|
||||
PROTO_NAME(f), oldState, ppperr_strerr[oldState], f->state, ppperr_strerr[f->state]));
|
||||
}
|
||||
|
||||
|
@ -271,10 +243,23 @@ fsm_open(fsm *f)
|
|||
break;
|
||||
}
|
||||
|
||||
FSMDEBUG((LOG_INFO, "%s: open state %d (%s) -> %d (%s)\n",
|
||||
FSMDEBUG(LOG_INFO, ("%s: open state %d (%s) -> %d (%s)\n",
|
||||
PROTO_NAME(f), oldState, ppperr_strerr[oldState], f->state, ppperr_strerr[f->state]));
|
||||
}
|
||||
|
||||
#if 0 /* backport pppd 2.4.4b1; */
|
||||
/*
|
||||
* terminate_layer - Start process of shutting down the FSM
|
||||
*
|
||||
* Cancel any timeout running, notify upper layers we're done, and
|
||||
* send a terminate-request message as configured.
|
||||
*/
|
||||
static void
|
||||
terminate_layer(fsm *f, int nextstate)
|
||||
{
|
||||
/* @todo */
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* fsm_close - Start closing connection.
|
||||
|
@ -290,7 +275,7 @@ fsm_close(fsm *f, char *reason)
|
|||
LWIP_UNUSED_ARG(oldState);
|
||||
|
||||
f->term_reason = reason;
|
||||
f->term_reason_len = (reason == NULL? 0: strlen(reason));
|
||||
f->term_reason_len = (reason == NULL ? 0 : (int)strlen(reason));
|
||||
switch( f->state ) {
|
||||
case LS_STARTING:
|
||||
f->state = LS_INITIAL;
|
||||
|
@ -322,38 +307,71 @@ fsm_close(fsm *f, char *reason)
|
|||
break;
|
||||
}
|
||||
|
||||
FSMDEBUG((LOG_INFO, "%s: close reason=%s state %d (%s) -> %d (%s)\n",
|
||||
FSMDEBUG(LOG_INFO, ("%s: close reason=%s state %d (%s) -> %d (%s)\n",
|
||||
PROTO_NAME(f), reason, oldState, ppperr_strerr[oldState], f->state, ppperr_strerr[f->state]));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fsm_sdata - Send some data.
|
||||
*
|
||||
* Used for all packets sent to our peer by this module.
|
||||
* fsm_timeout - Timeout expired.
|
||||
*/
|
||||
void
|
||||
fsm_sdata( fsm *f, u_char code, u_char id, u_char *data, int datalen)
|
||||
static void
|
||||
fsm_timeout(void *arg)
|
||||
{
|
||||
u_char *outp;
|
||||
int outlen;
|
||||
fsm *f = (fsm *) arg;
|
||||
|
||||
/* Adjust length to be smaller than MTU */
|
||||
outp = outpacket_buf[f->unit];
|
||||
if (datalen > peer_mru[f->unit] - (int)HEADERLEN) {
|
||||
datalen = peer_mru[f->unit] - HEADERLEN;
|
||||
switch (f->state) {
|
||||
case LS_CLOSING:
|
||||
case LS_STOPPING:
|
||||
if( f->retransmits <= 0 ) {
|
||||
FSMDEBUG(LOG_WARNING, ("%s: timeout sending Terminate-Request state=%d (%s)\n",
|
||||
PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
|
||||
/*
|
||||
* We've waited for an ack long enough. Peer probably heard us.
|
||||
*/
|
||||
f->state = (f->state == LS_CLOSING)? LS_CLOSED: LS_STOPPED;
|
||||
if( f->callbacks->finished ) {
|
||||
(*f->callbacks->finished)(f);
|
||||
}
|
||||
} else {
|
||||
FSMDEBUG(LOG_WARNING, ("%s: timeout resending Terminate-Requests state=%d (%s)\n",
|
||||
PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
|
||||
/* Send Terminate-Request */
|
||||
fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
|
||||
(u_char *) f->term_reason, f->term_reason_len);
|
||||
TIMEOUT(fsm_timeout, f, f->timeouttime);
|
||||
--f->retransmits;
|
||||
}
|
||||
break;
|
||||
|
||||
case LS_REQSENT:
|
||||
case LS_ACKRCVD:
|
||||
case LS_ACKSENT:
|
||||
if (f->retransmits <= 0) {
|
||||
FSMDEBUG(LOG_WARNING, ("%s: timeout sending Config-Requests state=%d (%s)\n",
|
||||
PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
|
||||
f->state = LS_STOPPED;
|
||||
if( (f->flags & OPT_PASSIVE) == 0 && f->callbacks->finished ) {
|
||||
(*f->callbacks->finished)(f);
|
||||
}
|
||||
} else {
|
||||
FSMDEBUG(LOG_WARNING, ("%s: timeout resending Config-Request state=%d (%s)\n",
|
||||
PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
|
||||
/* Retransmit the configure-request */
|
||||
if (f->callbacks->retransmit) {
|
||||
(*f->callbacks->retransmit)(f);
|
||||
}
|
||||
fsm_sconfreq(f, 1); /* Re-send Configure-Request */
|
||||
if( f->state == LS_ACKRCVD ) {
|
||||
f->state = LS_REQSENT;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
FSMDEBUG(LOG_INFO, ("%s: UNHANDLED timeout event in state %d (%s)!\n",
|
||||
PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
|
||||
}
|
||||
if (datalen && data != outp + PPP_HDRLEN + HEADERLEN) {
|
||||
BCOPY(data, outp + PPP_HDRLEN + HEADERLEN, datalen);
|
||||
}
|
||||
outlen = datalen + HEADERLEN;
|
||||
MAKEHEADER(outp, f->protocol);
|
||||
PUTCHAR(code, outp);
|
||||
PUTCHAR(id, outp);
|
||||
PUTSHORT(outlen, outp);
|
||||
pppWrite(f->unit, outpacket_buf[f->unit], outlen + PPP_HDRLEN);
|
||||
FSMDEBUG((LOG_INFO, "fsm_sdata(%s): Sent code %d,%d,%d.\n",
|
||||
PROTO_NAME(f), code, id, outlen));
|
||||
}
|
||||
|
||||
|
||||
|
@ -372,7 +390,7 @@ fsm_input(fsm *f, u_char *inpacket, int l)
|
|||
* If packet too short, drop it.
|
||||
*/
|
||||
if (l < HEADERLEN) {
|
||||
FSMDEBUG((LOG_WARNING, "fsm_input(%x): Rcvd short header.\n",
|
||||
FSMDEBUG(LOG_WARNING, ("fsm_input(%x): Rcvd short header.\n",
|
||||
f->protocol));
|
||||
return;
|
||||
}
|
||||
|
@ -380,23 +398,23 @@ fsm_input(fsm *f, u_char *inpacket, int l)
|
|||
GETCHAR(id, inp);
|
||||
GETSHORT(len, inp);
|
||||
if (len < HEADERLEN) {
|
||||
FSMDEBUG((LOG_INFO, "fsm_input(%x): Rcvd illegal length.\n",
|
||||
FSMDEBUG(LOG_INFO, ("fsm_input(%x): Rcvd illegal length.\n",
|
||||
f->protocol));
|
||||
return;
|
||||
}
|
||||
if (len > l) {
|
||||
FSMDEBUG((LOG_INFO, "fsm_input(%x): Rcvd short packet.\n",
|
||||
FSMDEBUG(LOG_INFO, ("fsm_input(%x): Rcvd short packet.\n",
|
||||
f->protocol));
|
||||
return;
|
||||
}
|
||||
len -= HEADERLEN; /* subtract header length */
|
||||
|
||||
if( f->state == LS_INITIAL || f->state == LS_STARTING ) {
|
||||
FSMDEBUG((LOG_INFO, "fsm_input(%x): Rcvd packet in state %d (%s).\n",
|
||||
FSMDEBUG(LOG_INFO, ("fsm_input(%x): Rcvd packet in state %d (%s).\n",
|
||||
f->protocol, f->state, ppperr_strerr[f->state]));
|
||||
return;
|
||||
}
|
||||
FSMDEBUG((LOG_INFO, "fsm_input(%s):%d,%d,%d\n", PROTO_NAME(f), code, id, l));
|
||||
FSMDEBUG(LOG_INFO, ("fsm_input(%s):%d,%d,%d\n", PROTO_NAME(f), code, id, l));
|
||||
/*
|
||||
* Action depends on code.
|
||||
*/
|
||||
|
@ -427,6 +445,7 @@ fsm_input(fsm *f, u_char *inpacket, int l)
|
|||
break;
|
||||
|
||||
default:
|
||||
FSMDEBUG(LOG_INFO, ("fsm_input(%s): default: \n", PROTO_NAME(f)));
|
||||
if( !f->callbacks->extcode ||
|
||||
!(*f->callbacks->extcode)(f, code, id, inp, len) ) {
|
||||
fsm_sdata(f, CODEREJ, ++f->id, inpacket, len + HEADERLEN);
|
||||
|
@ -436,129 +455,6 @@ fsm_input(fsm *f, u_char *inpacket, int l)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* fsm_protreject - Peer doesn't speak this protocol.
|
||||
*
|
||||
* Treat this as a catastrophic error (RXJ-).
|
||||
*/
|
||||
void
|
||||
fsm_protreject(fsm *f)
|
||||
{
|
||||
switch( f->state ) {
|
||||
case LS_CLOSING:
|
||||
UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
|
||||
/* fall through */
|
||||
case LS_CLOSED:
|
||||
f->state = LS_CLOSED;
|
||||
if( f->callbacks->finished ) {
|
||||
(*f->callbacks->finished)(f);
|
||||
}
|
||||
break;
|
||||
|
||||
case LS_STOPPING:
|
||||
case LS_REQSENT:
|
||||
case LS_ACKRCVD:
|
||||
case LS_ACKSENT:
|
||||
UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
|
||||
/* fall through */
|
||||
case LS_STOPPED:
|
||||
f->state = LS_STOPPED;
|
||||
if( f->callbacks->finished ) {
|
||||
(*f->callbacks->finished)(f);
|
||||
}
|
||||
break;
|
||||
|
||||
case LS_OPENED:
|
||||
if( f->callbacks->down ) {
|
||||
(*f->callbacks->down)(f);
|
||||
}
|
||||
/* Init restart counter, send Terminate-Request */
|
||||
f->retransmits = f->maxtermtransmits;
|
||||
fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
|
||||
(u_char *) f->term_reason, f->term_reason_len);
|
||||
TIMEOUT(fsm_timeout, f, f->timeouttime);
|
||||
--f->retransmits;
|
||||
|
||||
f->state = LS_STOPPING;
|
||||
break;
|
||||
|
||||
default:
|
||||
FSMDEBUG((LOG_INFO, "%s: Protocol-reject event in state %d (%s)!\n",
|
||||
PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**********************************/
|
||||
/*** LOCAL FUNCTION DEFINITIONS ***/
|
||||
/**********************************/
|
||||
|
||||
/*
|
||||
* fsm_timeout - Timeout expired.
|
||||
*/
|
||||
static void
|
||||
fsm_timeout(void *arg)
|
||||
{
|
||||
fsm *f = (fsm *) arg;
|
||||
|
||||
switch (f->state) {
|
||||
case LS_CLOSING:
|
||||
case LS_STOPPING:
|
||||
if( f->retransmits <= 0 ) {
|
||||
FSMDEBUG((LOG_WARNING, "%s: timeout sending Terminate-Request state=%d (%s)\n",
|
||||
PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
|
||||
/*
|
||||
* We've waited for an ack long enough. Peer probably heard us.
|
||||
*/
|
||||
f->state = (f->state == LS_CLOSING)? LS_CLOSED: LS_STOPPED;
|
||||
if( f->callbacks->finished ) {
|
||||
(*f->callbacks->finished)(f);
|
||||
}
|
||||
} else {
|
||||
FSMDEBUG((LOG_WARNING, "%s: timeout resending Terminate-Requests state=%d (%s)\n",
|
||||
PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
|
||||
/* Send Terminate-Request */
|
||||
fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
|
||||
(u_char *) f->term_reason, f->term_reason_len);
|
||||
TIMEOUT(fsm_timeout, f, f->timeouttime);
|
||||
--f->retransmits;
|
||||
}
|
||||
break;
|
||||
|
||||
case LS_REQSENT:
|
||||
case LS_ACKRCVD:
|
||||
case LS_ACKSENT:
|
||||
if (f->retransmits <= 0) {
|
||||
FSMDEBUG((LOG_WARNING, "%s: timeout sending Config-Requests state=%d (%s)\n",
|
||||
PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
|
||||
f->state = LS_STOPPED;
|
||||
if( (f->flags & OPT_PASSIVE) == 0 && f->callbacks->finished ) {
|
||||
(*f->callbacks->finished)(f);
|
||||
}
|
||||
} else {
|
||||
FSMDEBUG((LOG_WARNING, "%s: timeout resending Config-Request state=%d (%s)\n",
|
||||
PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
|
||||
/* Retransmit the configure-request */
|
||||
if (f->callbacks->retransmit) {
|
||||
(*f->callbacks->retransmit)(f);
|
||||
}
|
||||
fsm_sconfreq(f, 1); /* Re-send Configure-Request */
|
||||
if( f->state == LS_ACKRCVD ) {
|
||||
f->state = LS_REQSENT;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
FSMDEBUG((LOG_INFO, "%s: UNHANDLED timeout event in state %d (%s)!\n",
|
||||
PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fsm_rconfreq - Receive Configure-Request.
|
||||
*/
|
||||
|
@ -567,7 +463,7 @@ fsm_rconfreq(fsm *f, u_char id, u_char *inp, int len)
|
|||
{
|
||||
int code, reject_if_disagree;
|
||||
|
||||
FSMDEBUG((LOG_INFO, "fsm_rconfreq(%s): Rcvd id %d state=%d (%s)\n",
|
||||
FSMDEBUG(LOG_INFO, ("fsm_rconfreq(%s): Rcvd id %d state=%d (%s)\n",
|
||||
PROTO_NAME(f), id, f->state, ppperr_strerr[f->state]));
|
||||
switch( f->state ) {
|
||||
case LS_CLOSED:
|
||||
|
@ -638,7 +534,7 @@ fsm_rconfreq(fsm *f, u_char id, u_char *inp, int len)
|
|||
static void
|
||||
fsm_rconfack(fsm *f, int id, u_char *inp, int len)
|
||||
{
|
||||
FSMDEBUG((LOG_INFO, "fsm_rconfack(%s): Rcvd id %d state=%d (%s)\n",
|
||||
FSMDEBUG(LOG_INFO, ("fsm_rconfack(%s): Rcvd id %d state=%d (%s)\n",
|
||||
PROTO_NAME(f), id, f->state, ppperr_strerr[f->state]));
|
||||
|
||||
if (id != f->reqid || f->seen_ack) { /* Expected id? */
|
||||
|
@ -646,7 +542,7 @@ fsm_rconfack(fsm *f, int id, u_char *inp, int len)
|
|||
}
|
||||
if( !(f->callbacks->ackci? (*f->callbacks->ackci)(f, inp, len): (len == 0)) ) {
|
||||
/* Ack is bad - ignore it */
|
||||
FSMDEBUG((LOG_INFO, "%s: received bad Ack (length %d)\n",
|
||||
FSMDEBUG(LOG_INFO, ("%s: received bad Ack (length %d)\n",
|
||||
PROTO_NAME(f), len));
|
||||
return;
|
||||
}
|
||||
|
@ -700,7 +596,7 @@ fsm_rconfnakrej(fsm *f, int code, int id, u_char *inp, int len)
|
|||
int (*proc) (fsm *, u_char *, int);
|
||||
int ret;
|
||||
|
||||
FSMDEBUG((LOG_INFO, "fsm_rconfnakrej(%s): Rcvd id %d state=%d (%s)\n",
|
||||
FSMDEBUG(LOG_INFO, ("fsm_rconfnakrej(%s): Rcvd id %d state=%d (%s)\n",
|
||||
PROTO_NAME(f), id, f->state, ppperr_strerr[f->state]));
|
||||
|
||||
if (id != f->reqid || f->seen_ack) { /* Expected id? */
|
||||
|
@ -709,7 +605,7 @@ fsm_rconfnakrej(fsm *f, int code, int id, u_char *inp, int len)
|
|||
proc = (code == CONFNAK)? f->callbacks->nakci: f->callbacks->rejci;
|
||||
if (!proc || !((ret = proc(f, inp, len)))) {
|
||||
/* Nak/reject is bad - ignore it */
|
||||
FSMDEBUG((LOG_INFO, "%s: received bad %s (length %d)\n",
|
||||
FSMDEBUG(LOG_INFO, ("%s: received bad %s (length %d)\n",
|
||||
PROTO_NAME(f), (code==CONFNAK? "Nak": "reject"), len));
|
||||
return;
|
||||
}
|
||||
|
@ -759,7 +655,7 @@ fsm_rtermreq(fsm *f, int id, u_char *p, int len)
|
|||
{
|
||||
LWIP_UNUSED_ARG(p);
|
||||
|
||||
FSMDEBUG((LOG_INFO, "fsm_rtermreq(%s): Rcvd id %d state=%d (%s)\n",
|
||||
FSMDEBUG(LOG_INFO, ("fsm_rtermreq(%s): Rcvd id %d state=%d (%s)\n",
|
||||
PROTO_NAME(f), id, f->state, ppperr_strerr[f->state]));
|
||||
|
||||
switch (f->state) {
|
||||
|
@ -770,9 +666,9 @@ fsm_rtermreq(fsm *f, int id, u_char *p, int len)
|
|||
|
||||
case LS_OPENED:
|
||||
if (len > 0) {
|
||||
FSMDEBUG((LOG_INFO, "%s terminated by peer (%x)\n", PROTO_NAME(f), p));
|
||||
FSMDEBUG(LOG_INFO, ("%s terminated by peer (%p)\n", PROTO_NAME(f), p));
|
||||
} else {
|
||||
FSMDEBUG((LOG_INFO, "%s terminated by peer\n", PROTO_NAME(f)));
|
||||
FSMDEBUG(LOG_INFO, ("%s terminated by peer\n", PROTO_NAME(f)));
|
||||
}
|
||||
if (f->callbacks->down) {
|
||||
(*f->callbacks->down)(f); /* Inform upper layers */
|
||||
|
@ -793,7 +689,7 @@ fsm_rtermreq(fsm *f, int id, u_char *p, int len)
|
|||
static void
|
||||
fsm_rtermack(fsm *f)
|
||||
{
|
||||
FSMDEBUG((LOG_INFO, "fsm_rtermack(%s): state=%d (%s)\n",
|
||||
FSMDEBUG(LOG_INFO, ("fsm_rtermack(%s): state=%d (%s)\n",
|
||||
PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
|
||||
|
||||
switch (f->state) {
|
||||
|
@ -823,6 +719,9 @@ fsm_rtermack(fsm *f)
|
|||
}
|
||||
fsm_sconfreq(f, 0);
|
||||
break;
|
||||
default:
|
||||
FSMDEBUG(LOG_INFO, ("fsm_rtermack(%s): UNHANDLED state=%d (%s)!!!\n",
|
||||
PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -835,16 +734,16 @@ fsm_rcoderej(fsm *f, u_char *inp, int len)
|
|||
{
|
||||
u_char code, id;
|
||||
|
||||
FSMDEBUG((LOG_INFO, "fsm_rcoderej(%s): state=%d (%s)\n",
|
||||
FSMDEBUG(LOG_INFO, ("fsm_rcoderej(%s): state=%d (%s)\n",
|
||||
PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
|
||||
|
||||
if (len < HEADERLEN) {
|
||||
FSMDEBUG((LOG_INFO, "fsm_rcoderej: Rcvd short Code-Reject packet!\n"));
|
||||
FSMDEBUG(LOG_INFO, ("fsm_rcoderej: Rcvd short Code-Reject packet!\n"));
|
||||
return;
|
||||
}
|
||||
GETCHAR(code, inp);
|
||||
GETCHAR(id, inp);
|
||||
FSMDEBUG((LOG_WARNING, "%s: Rcvd Code-Reject for code %d, id %d\n",
|
||||
FSMDEBUG(LOG_WARNING, ("%s: Rcvd Code-Reject for code %d, id %d\n",
|
||||
PROTO_NAME(f), code, id));
|
||||
|
||||
if( f->state == LS_ACKRCVD ) {
|
||||
|
@ -853,6 +752,59 @@ fsm_rcoderej(fsm *f, u_char *inp, int len)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* fsm_protreject - Peer doesn't speak this protocol.
|
||||
*
|
||||
* Treat this as a catastrophic error (RXJ-).
|
||||
*/
|
||||
void
|
||||
fsm_protreject(fsm *f)
|
||||
{
|
||||
switch( f->state ) {
|
||||
case LS_CLOSING:
|
||||
UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
|
||||
/* fall through */
|
||||
case LS_CLOSED:
|
||||
f->state = LS_CLOSED;
|
||||
if( f->callbacks->finished ) {
|
||||
(*f->callbacks->finished)(f);
|
||||
}
|
||||
break;
|
||||
|
||||
case LS_STOPPING:
|
||||
case LS_REQSENT:
|
||||
case LS_ACKRCVD:
|
||||
case LS_ACKSENT:
|
||||
UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */
|
||||
/* fall through */
|
||||
case LS_STOPPED:
|
||||
f->state = LS_STOPPED;
|
||||
if( f->callbacks->finished ) {
|
||||
(*f->callbacks->finished)(f);
|
||||
}
|
||||
break;
|
||||
|
||||
case LS_OPENED:
|
||||
if( f->callbacks->down ) {
|
||||
(*f->callbacks->down)(f);
|
||||
}
|
||||
/* Init restart counter, send Terminate-Request */
|
||||
f->retransmits = f->maxtermtransmits;
|
||||
fsm_sdata(f, TERMREQ, f->reqid = ++f->id,
|
||||
(u_char *) f->term_reason, f->term_reason_len);
|
||||
TIMEOUT(fsm_timeout, f, f->timeouttime);
|
||||
--f->retransmits;
|
||||
|
||||
f->state = LS_STOPPING;
|
||||
break;
|
||||
|
||||
default:
|
||||
FSMDEBUG(LOG_INFO, ("%s: Protocol-reject event in state %d (%s)!\n",
|
||||
PROTO_NAME(f), f->state, ppperr_strerr[f->state]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fsm_sconfreq - Send a Configure-Request.
|
||||
*/
|
||||
|
@ -901,8 +853,38 @@ fsm_sconfreq(fsm *f, int retransmit)
|
|||
--f->retransmits;
|
||||
TIMEOUT(fsm_timeout, f, f->timeouttime);
|
||||
|
||||
FSMDEBUG((LOG_INFO, "%s: sending Configure-Request, id %d\n",
|
||||
FSMDEBUG(LOG_INFO, ("%s: sending Configure-Request, id %d\n",
|
||||
PROTO_NAME(f), f->reqid));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fsm_sdata - Send some data.
|
||||
*
|
||||
* Used for all packets sent to our peer by this module.
|
||||
*/
|
||||
void
|
||||
fsm_sdata( fsm *f, u_char code, u_char id, u_char *data, int datalen)
|
||||
{
|
||||
u_char *outp;
|
||||
int outlen;
|
||||
|
||||
/* Adjust length to be smaller than MTU */
|
||||
outp = outpacket_buf[f->unit];
|
||||
if (datalen > peer_mru[f->unit] - (int)HEADERLEN) {
|
||||
datalen = peer_mru[f->unit] - HEADERLEN;
|
||||
}
|
||||
if (datalen && data != outp + PPP_HDRLEN + HEADERLEN) {
|
||||
BCOPY(data, outp + PPP_HDRLEN + HEADERLEN, datalen);
|
||||
}
|
||||
outlen = datalen + HEADERLEN;
|
||||
MAKEHEADER(outp, f->protocol);
|
||||
PUTCHAR(code, outp);
|
||||
PUTCHAR(id, outp);
|
||||
PUTSHORT(outlen, outp);
|
||||
pppWrite(f->unit, outpacket_buf[f->unit], outlen + PPP_HDRLEN);
|
||||
FSMDEBUG(LOG_INFO, ("fsm_sdata(%s): Sent code %d,%d,%d.\n",
|
||||
PROTO_NAME(f), code, id, outlen));
|
||||
}
|
||||
|
||||
#endif /* PPP_SUPPORT */
|
||||
|
|
|
@ -48,15 +48,12 @@
|
|||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: fsm.h,v 1.4 2007/12/19 20:47:23 fbernon Exp $
|
||||
* $Id: fsm.h,v 1.5 2009/12/31 17:08:08 goldsimon Exp $
|
||||
*/
|
||||
|
||||
#ifndef FSM_H
|
||||
#define FSM_H
|
||||
|
||||
/*****************************************************************************
|
||||
************************* PUBLIC DEFINITIONS *********************************
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* LCP Packet header = Code, id, length.
|
||||
*/
|
||||
|
@ -74,31 +71,7 @@
|
|||
#define TERMACK 6 /* Termination Ack */
|
||||
#define CODEREJ 7 /* Code Reject */
|
||||
|
||||
/*
|
||||
* Link states.
|
||||
*/
|
||||
#define LS_INITIAL 0 /* Down, hasn't been opened */
|
||||
#define LS_STARTING 1 /* Down, been opened */
|
||||
#define LS_CLOSED 2 /* Up, hasn't been opened */
|
||||
#define LS_STOPPED 3 /* Open, waiting for down event */
|
||||
#define LS_CLOSING 4 /* Terminating the connection, not open */
|
||||
#define LS_STOPPING 5 /* Terminating, but open */
|
||||
#define LS_REQSENT 6 /* We've sent a Config Request */
|
||||
#define LS_ACKRCVD 7 /* We've received a Config Ack */
|
||||
#define LS_ACKSENT 8 /* We've sent a Config Ack */
|
||||
#define LS_OPENED 9 /* Connection available */
|
||||
|
||||
/*
|
||||
* Flags - indicate options controlling FSM operation
|
||||
*/
|
||||
#define OPT_PASSIVE 1 /* Don't die if we don't get a response */
|
||||
#define OPT_RESTART 2 /* Treat 2nd OPEN as DOWN, UP */
|
||||
#define OPT_SILENT 4 /* Wait for peer to speak first */
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
************************* PUBLIC DATA TYPES **********************************
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Each FSM is described by an fsm structure and fsm callbacks.
|
||||
*/
|
||||
|
@ -141,18 +114,27 @@ typedef struct fsm_callbacks {
|
|||
} fsm_callbacks;
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*********************** PUBLIC DATA STRUCTURES *******************************
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* Variables
|
||||
* Link states.
|
||||
*/
|
||||
extern int peer_mru[]; /* currently negotiated peer MRU (per unit) */
|
||||
#define LS_INITIAL 0 /* Down, hasn't been opened */
|
||||
#define LS_STARTING 1 /* Down, been opened */
|
||||
#define LS_CLOSED 2 /* Up, hasn't been opened */
|
||||
#define LS_STOPPED 3 /* Open, waiting for down event */
|
||||
#define LS_CLOSING 4 /* Terminating the connection, not open */
|
||||
#define LS_STOPPING 5 /* Terminating, but open */
|
||||
#define LS_REQSENT 6 /* We've sent a Config Request */
|
||||
#define LS_ACKRCVD 7 /* We've received a Config Ack */
|
||||
#define LS_ACKSENT 8 /* We've sent a Config Ack */
|
||||
#define LS_OPENED 9 /* Connection available */
|
||||
|
||||
/*
|
||||
* Flags - indicate options controlling FSM operation
|
||||
*/
|
||||
#define OPT_PASSIVE 1 /* Don't die if we don't get a response */
|
||||
#define OPT_RESTART 2 /* Treat 2nd OPEN as DOWN, UP */
|
||||
#define OPT_SILENT 4 /* Wait for peer to speak first */
|
||||
|
||||
/*****************************************************************************
|
||||
************************** PUBLIC FUNCTIONS **********************************
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Prototypes
|
||||
|
@ -166,4 +148,10 @@ void fsm_input (fsm*, u_char*, int);
|
|||
void fsm_protreject (fsm*);
|
||||
void fsm_sdata (fsm*, u_char, u_char, u_char*, int);
|
||||
|
||||
|
||||
/*
|
||||
* Variables
|
||||
*/
|
||||
extern int peer_mru[]; /* currently negotiated peer MRU (per unit) */
|
||||
|
||||
#endif /* FSM_H */
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/** In contrast to pppd 2.3.1, DNS support has been added, proxy-ARP and
|
||||
dial-on-demand has been stripped. */
|
||||
/*****************************************************************************
|
||||
* ipcp.c - Network PPP IP Control Protocol program file.
|
||||
*
|
||||
|
@ -61,27 +63,23 @@
|
|||
#include "vj.h"
|
||||
#include "ipcp.h"
|
||||
|
||||
#include "lwip/inet.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/*************************/
|
||||
/*** LOCAL DEFINITIONS ***/
|
||||
/*************************/
|
||||
/* #define OLD_CI_ADDRS 1 */ /* Support deprecated address negotiation. */
|
||||
|
||||
/*
|
||||
* Lengths of configuration options.
|
||||
*/
|
||||
#define CILEN_VOID 2
|
||||
#define CILEN_COMPRESS 4 /* min length for compression protocol opt. */
|
||||
#define CILEN_VJ 6 /* length for RFC1332 Van-Jacobson opt. */
|
||||
#define CILEN_ADDR 6 /* new-style single address option */
|
||||
#define CILEN_ADDRS 10 /* old-style dual address option */
|
||||
/* global vars */
|
||||
ipcp_options ipcp_wantoptions[NUM_PPP]; /* Options that we want to request */
|
||||
ipcp_options ipcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */
|
||||
ipcp_options ipcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */
|
||||
ipcp_options ipcp_hisoptions[NUM_PPP]; /* Options that we ack'd */
|
||||
|
||||
/* local vars */
|
||||
static int default_route_set[NUM_PPP]; /* Have set up a default route */
|
||||
static int cis_received[NUM_PPP]; /* # Conf-Reqs received */
|
||||
|
||||
|
||||
|
||||
/***********************************/
|
||||
/*** LOCAL FUNCTION DECLARATIONS ***/
|
||||
/***********************************/
|
||||
/*
|
||||
* Callbacks for fsm code. (CI = Configuration Information)
|
||||
*/
|
||||
|
@ -94,70 +92,14 @@ static int ipcp_rejci (fsm *, u_char *, int); /* Peer rej'd our CI */
|
|||
static int ipcp_reqci (fsm *, u_char *, int *, int); /* Rcv CI */
|
||||
static void ipcp_up (fsm *); /* We're UP */
|
||||
static void ipcp_down (fsm *); /* We're DOWN */
|
||||
#if 0
|
||||
#if PPP_ADDITIONAL_CALLBACKS
|
||||
static void ipcp_script (fsm *, char *); /* Run an up/down script */
|
||||
#endif
|
||||
static void ipcp_finished (fsm *); /* Don't need lower layer */
|
||||
|
||||
/*
|
||||
* Protocol entry points from main code.
|
||||
*/
|
||||
static void ipcp_init (int);
|
||||
static void ipcp_open (int);
|
||||
static void ipcp_close (int, char *);
|
||||
static void ipcp_lowerup (int);
|
||||
static void ipcp_lowerdown (int);
|
||||
static void ipcp_input (int, u_char *, int);
|
||||
static void ipcp_protrej (int);
|
||||
|
||||
static void ipcp_clear_addrs (int);
|
||||
|
||||
#define CODENAME(x) ((x) == CONFACK ? "ACK" : \
|
||||
(x) == CONFNAK ? "NAK" : "REJ")
|
||||
|
||||
|
||||
|
||||
/******************************/
|
||||
/*** PUBLIC DATA STRUCTURES ***/
|
||||
/******************************/
|
||||
/* global vars */
|
||||
ipcp_options ipcp_wantoptions[NUM_PPP]; /* Options that we want to request */
|
||||
ipcp_options ipcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */
|
||||
ipcp_options ipcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */
|
||||
ipcp_options ipcp_hisoptions[NUM_PPP]; /* Options that we ack'd */
|
||||
|
||||
fsm ipcp_fsm[NUM_PPP]; /* IPCP fsm structure */
|
||||
|
||||
struct protent ipcp_protent = {
|
||||
PPP_IPCP,
|
||||
ipcp_init,
|
||||
ipcp_input,
|
||||
ipcp_protrej,
|
||||
ipcp_lowerup,
|
||||
ipcp_lowerdown,
|
||||
ipcp_open,
|
||||
ipcp_close,
|
||||
#if 0
|
||||
ipcp_printpkt,
|
||||
NULL,
|
||||
#endif
|
||||
1,
|
||||
"IPCP",
|
||||
#if 0
|
||||
ip_check_options,
|
||||
NULL,
|
||||
ip_active_pkt
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*****************************/
|
||||
/*** LOCAL DATA STRUCTURES ***/
|
||||
/*****************************/
|
||||
/* local vars */
|
||||
static int cis_received[NUM_PPP]; /* # Conf-Reqs received */
|
||||
static int default_route_set[NUM_PPP]; /* Have set up a default route */
|
||||
|
||||
static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */
|
||||
ipcp_resetci, /* Reset our Configuration Information */
|
||||
|
@ -177,13 +119,55 @@ static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */
|
|||
"IPCP" /* String name of protocol */
|
||||
};
|
||||
|
||||
/*
|
||||
* Protocol entry points from main code.
|
||||
*/
|
||||
static void ipcp_init (int);
|
||||
static void ipcp_open (int);
|
||||
static void ipcp_close (int, char *);
|
||||
static void ipcp_lowerup (int);
|
||||
static void ipcp_lowerdown (int);
|
||||
static void ipcp_input (int, u_char *, int);
|
||||
static void ipcp_protrej (int);
|
||||
|
||||
|
||||
/**********************************/
|
||||
/*** LOCAL FUNCTION DEFINITIONS ***/
|
||||
/**********************************/
|
||||
struct protent ipcp_protent = {
|
||||
PPP_IPCP,
|
||||
ipcp_init,
|
||||
ipcp_input,
|
||||
ipcp_protrej,
|
||||
ipcp_lowerup,
|
||||
ipcp_lowerdown,
|
||||
ipcp_open,
|
||||
ipcp_close,
|
||||
#if PPP_ADDITIONAL_CALLBACKS
|
||||
ipcp_printpkt,
|
||||
NULL,
|
||||
#endif /* PPP_ADDITIONAL_CALLBACKS */
|
||||
1,
|
||||
"IPCP",
|
||||
#if PPP_ADDITIONAL_CALLBACKS
|
||||
ip_check_options,
|
||||
NULL,
|
||||
ip_active_pkt
|
||||
#endif /* PPP_ADDITIONAL_CALLBACKS */
|
||||
};
|
||||
|
||||
static void ipcp_clear_addrs (int);
|
||||
|
||||
/*
|
||||
* Lengths of configuration options.
|
||||
*/
|
||||
#define CILEN_VOID 2
|
||||
#define CILEN_COMPRESS 4 /* min length for compression protocol opt. */
|
||||
#define CILEN_VJ 6 /* length for RFC1332 Van-Jacobson opt. */
|
||||
#define CILEN_ADDR 6 /* new-style single address option */
|
||||
#define CILEN_ADDRS 10 /* old-style dual address option */
|
||||
|
||||
|
||||
#define CODENAME(x) ((x) == CONFACK ? "ACK" : \
|
||||
(x) == CONFNAK ? "NAK" : "REJ")
|
||||
|
||||
#define inet_ntoa(addr) ip_ntoa(((struct ip_addr*)&(addr)))
|
||||
|
||||
/*
|
||||
* ipcp_init - Initialize IPCP.
|
||||
|
@ -542,9 +526,9 @@ ipcp_ackci(fsm *f, u_char *p, int len)
|
|||
goto bad;
|
||||
}
|
||||
return (1);
|
||||
|
||||
|
||||
bad:
|
||||
IPCPDEBUG((LOG_INFO, "ipcp_ackci: received bad Ack!\n"));
|
||||
IPCPDEBUG(LOG_INFO, ("ipcp_ackci: received bad Ack!\n"));
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -628,12 +612,12 @@ ipcp_nakci(fsm *f, u_char *p, int len)
|
|||
NAKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr, go->old_addrs,
|
||||
if (go->accept_local && ciaddr1) { /* Do we know our address? */
|
||||
try.ouraddr = ciaddr1;
|
||||
IPCPDEBUG((LOG_INFO, "local IP address %s\n",
|
||||
IPCPDEBUG(LOG_INFO, ("local IP address %s\n",
|
||||
inet_ntoa(ciaddr1)));
|
||||
}
|
||||
if (go->accept_remote && ciaddr2) { /* Does he know his? */
|
||||
try.hisaddr = ciaddr2;
|
||||
IPCPDEBUG((LOG_INFO, "remote IP address %s\n",
|
||||
IPCPDEBUG(LOG_INFO, ("remote IP address %s\n",
|
||||
inet_ntoa(ciaddr2)));
|
||||
}
|
||||
);
|
||||
|
@ -671,12 +655,12 @@ ipcp_nakci(fsm *f, u_char *p, int len)
|
|||
|
||||
NAKCIDNS(CI_MS_DNS1, req_dns1,
|
||||
try.dnsaddr[0] = cidnsaddr;
|
||||
IPCPDEBUG((LOG_INFO, "primary DNS address %s\n", inet_ntoa(cidnsaddr)));
|
||||
IPCPDEBUG(LOG_INFO, ("primary DNS address %s\n", inet_ntoa(cidnsaddr)));
|
||||
);
|
||||
|
||||
NAKCIDNS(CI_MS_DNS2, req_dns2,
|
||||
try.dnsaddr[1] = cidnsaddr;
|
||||
IPCPDEBUG((LOG_INFO, "secondary DNS address %s\n", inet_ntoa(cidnsaddr)));
|
||||
IPCPDEBUG(LOG_INFO, ("secondary DNS address %s\n", inet_ntoa(cidnsaddr)));
|
||||
);
|
||||
|
||||
/*
|
||||
|
@ -754,7 +738,7 @@ ipcp_nakci(fsm *f, u_char *p, int len)
|
|||
return 1;
|
||||
|
||||
bad:
|
||||
IPCPDEBUG((LOG_INFO, "ipcp_nakci: received bad Nak!\n"));
|
||||
IPCPDEBUG(LOG_INFO, ("ipcp_nakci: received bad Nak!\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -869,7 +853,7 @@ ipcp_rejci(fsm *f, u_char *p, int len)
|
|||
return 1;
|
||||
|
||||
bad:
|
||||
IPCPDEBUG((LOG_INFO, "ipcp_rejci: received bad Reject!\n"));
|
||||
IPCPDEBUG(LOG_INFO, ("ipcp_rejci: received bad Reject!\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -922,9 +906,9 @@ ipcp_reqci(fsm *f, u_char *inp/* Requested CIs */,int *len/* Length of requested
|
|||
if (l < 2 || /* Not enough data for CI header or */
|
||||
p[1] < 2 || /* CI length too small or */
|
||||
p[1] > l) { /* CI length too big? */
|
||||
IPCPDEBUG((LOG_INFO, "ipcp_reqci: bad CI length!\n"));
|
||||
IPCPDEBUG(LOG_INFO, ("ipcp_reqci: bad CI length!\n"));
|
||||
orc = CONFREJ; /* Reject bad CI */
|
||||
cilen = l; /* Reject till end of packet */
|
||||
cilen = (u_short)l;/* Reject till end of packet */
|
||||
l = 0; /* Don't loop again */
|
||||
goto endswitch;
|
||||
}
|
||||
|
@ -936,7 +920,7 @@ ipcp_reqci(fsm *f, u_char *inp/* Requested CIs */,int *len/* Length of requested
|
|||
switch (citype) { /* Check CI type */
|
||||
#ifdef OLD_CI_ADDRS /* Need to save space... */
|
||||
case CI_ADDRS:
|
||||
IPCPDEBUG((LOG_INFO, "ipcp_reqci: received ADDRS\n"));
|
||||
IPCPDEBUG(LOG_INFO, ("ipcp_reqci: received ADDRS\n"));
|
||||
if (!ao->neg_addr ||
|
||||
cilen != CILEN_ADDRS) { /* Check CI length */
|
||||
orc = CONFREJ; /* Reject CI */
|
||||
|
@ -951,7 +935,7 @@ ipcp_reqci(fsm *f, u_char *inp/* Requested CIs */,int *len/* Length of requested
|
|||
*/
|
||||
GETLONG(tl, p); /* Parse source address (his) */
|
||||
ciaddr1 = htonl(tl);
|
||||
IPCPDEBUG((LOG_INFO, "his addr %s\n", inet_ntoa(ciaddr1)));
|
||||
IPCPDEBUG(LOG_INFO, ("his addr %s\n", inet_ntoa(ciaddr1)));
|
||||
if (ciaddr1 != wo->hisaddr
|
||||
&& (ciaddr1 == 0 || !wo->accept_remote)) {
|
||||
orc = CONFNAK;
|
||||
|
@ -975,7 +959,7 @@ ipcp_reqci(fsm *f, u_char *inp/* Requested CIs */,int *len/* Length of requested
|
|||
*/
|
||||
GETLONG(tl, p); /* Parse desination address (ours) */
|
||||
ciaddr2 = htonl(tl);
|
||||
IPCPDEBUG((LOG_INFO, "our addr %s\n", inet_ntoa(ciaddr2)));
|
||||
IPCPDEBUG(LOG_INFO, ("our addr %s\n", inet_ntoa(ciaddr2)));
|
||||
if (ciaddr2 != wo->ouraddr) {
|
||||
if (ciaddr2 == 0 || !wo->accept_local) {
|
||||
orc = CONFNAK;
|
||||
|
@ -998,11 +982,11 @@ ipcp_reqci(fsm *f, u_char *inp/* Requested CIs */,int *len/* Length of requested
|
|||
|
||||
case CI_ADDR:
|
||||
if (!ao->neg_addr) {
|
||||
IPCPDEBUG((LOG_INFO, "ipcp_reqci: Reject ADDR not allowed\n"));
|
||||
IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Reject ADDR not allowed\n"));
|
||||
orc = CONFREJ; /* Reject CI */
|
||||
break;
|
||||
} else if (cilen != CILEN_ADDR) { /* Check CI length */
|
||||
IPCPDEBUG((LOG_INFO, "ipcp_reqci: Reject ADDR bad len\n"));
|
||||
IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Reject ADDR bad len\n"));
|
||||
orc = CONFREJ; /* Reject CI */
|
||||
break;
|
||||
}
|
||||
|
@ -1023,12 +1007,12 @@ ipcp_reqci(fsm *f, u_char *inp/* Requested CIs */,int *len/* Length of requested
|
|||
tl = ntohl(wo->hisaddr);
|
||||
PUTLONG(tl, p);
|
||||
}
|
||||
IPCPDEBUG((LOG_INFO, "ipcp_reqci: Nak ADDR %s\n", inet_ntoa(ciaddr1)));
|
||||
IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Nak ADDR %s\n", inet_ntoa(ciaddr1)));
|
||||
} else if (ciaddr1 == 0 && wo->hisaddr == 0) {
|
||||
/*
|
||||
* Don't ACK an address of 0.0.0.0 - reject it instead.
|
||||
*/
|
||||
IPCPDEBUG((LOG_INFO, "ipcp_reqci: Reject ADDR %s\n", inet_ntoa(ciaddr1)));
|
||||
IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Reject ADDR %s\n", inet_ntoa(ciaddr1)));
|
||||
orc = CONFREJ;
|
||||
wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */
|
||||
break;
|
||||
|
@ -1036,7 +1020,7 @@ ipcp_reqci(fsm *f, u_char *inp/* Requested CIs */,int *len/* Length of requested
|
|||
|
||||
ho->neg_addr = 1;
|
||||
ho->hisaddr = ciaddr1;
|
||||
IPCPDEBUG((LOG_INFO, "ipcp_reqci: ADDR %s\n", inet_ntoa(ciaddr1)));
|
||||
IPCPDEBUG(LOG_INFO, ("ipcp_reqci: ADDR %s\n", inet_ntoa(ciaddr1)));
|
||||
break;
|
||||
|
||||
case CI_MS_DNS1:
|
||||
|
@ -1047,27 +1031,27 @@ ipcp_reqci(fsm *f, u_char *inp/* Requested CIs */,int *len/* Length of requested
|
|||
/* If we do not have a DNS address then we cannot send it */
|
||||
if (ao->dnsaddr[d] == 0 ||
|
||||
cilen != CILEN_ADDR) { /* Check CI length */
|
||||
IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting DNS%d Request\n", d+1));
|
||||
IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting DNS%d Request\n", d+1));
|
||||
orc = CONFREJ; /* Reject CI */
|
||||
break;
|
||||
}
|
||||
GETLONG(tl, p);
|
||||
if (htonl(tl) != ao->dnsaddr[d]) {
|
||||
IPCPDEBUG((LOG_INFO, "ipcp_reqci: Naking DNS%d Request %d\n",
|
||||
IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Naking DNS%d Request %s\n",
|
||||
d+1, inet_ntoa(tl)));
|
||||
DECPTR(sizeof(u32_t), p);
|
||||
tl = ntohl(ao->dnsaddr[d]);
|
||||
PUTLONG(tl, p);
|
||||
orc = CONFNAK;
|
||||
}
|
||||
IPCPDEBUG((LOG_INFO, "ipcp_reqci: received DNS%d Request\n", d+1));
|
||||
IPCPDEBUG(LOG_INFO, ("ipcp_reqci: received DNS%d Request\n", d+1));
|
||||
break;
|
||||
|
||||
case CI_MS_WINS1:
|
||||
case CI_MS_WINS2:
|
||||
/* Microsoft primary or secondary WINS request */
|
||||
d = citype == CI_MS_WINS2;
|
||||
IPCPDEBUG((LOG_INFO, "ipcp_reqci: received WINS%d Request\n", d+1));
|
||||
IPCPDEBUG(LOG_INFO, ("ipcp_reqci: received WINS%d Request\n", d+1));
|
||||
|
||||
/* If we do not have a DNS address then we cannot send it */
|
||||
if (ao->winsaddr[d] == 0 ||
|
||||
|
@ -1086,11 +1070,11 @@ ipcp_reqci(fsm *f, u_char *inp/* Requested CIs */,int *len/* Length of requested
|
|||
|
||||
case CI_COMPRESSTYPE:
|
||||
if (!ao->neg_vj) {
|
||||
IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting COMPRESSTYPE not allowed\n"));
|
||||
IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting COMPRESSTYPE not allowed\n"));
|
||||
orc = CONFREJ;
|
||||
break;
|
||||
} else if (cilen != CILEN_VJ && cilen != CILEN_COMPRESS) {
|
||||
IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting COMPRESSTYPE len=%d\n", cilen));
|
||||
IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting COMPRESSTYPE len=%d\n", cilen));
|
||||
orc = CONFREJ;
|
||||
break;
|
||||
}
|
||||
|
@ -1098,7 +1082,7 @@ ipcp_reqci(fsm *f, u_char *inp/* Requested CIs */,int *len/* Length of requested
|
|||
|
||||
if (!(cishort == IPCP_VJ_COMP ||
|
||||
(cishort == IPCP_VJ_COMP_OLD && cilen == CILEN_COMPRESS))) {
|
||||
IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting COMPRESSTYPE %d\n", cishort));
|
||||
IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting COMPRESSTYPE %d\n", cishort));
|
||||
orc = CONFREJ;
|
||||
break;
|
||||
}
|
||||
|
@ -1108,7 +1092,7 @@ ipcp_reqci(fsm *f, u_char *inp/* Requested CIs */,int *len/* Length of requested
|
|||
if (cilen == CILEN_VJ) {
|
||||
GETCHAR(maxslotindex, p);
|
||||
if (maxslotindex > ao->maxslotindex) {
|
||||
IPCPDEBUG((LOG_INFO, "ipcp_reqci: Naking VJ max slot %d\n", maxslotindex));
|
||||
IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Naking VJ max slot %d\n", maxslotindex));
|
||||
orc = CONFNAK;
|
||||
if (!reject_if_disagree) {
|
||||
DECPTR(1, p);
|
||||
|
@ -1117,7 +1101,7 @@ ipcp_reqci(fsm *f, u_char *inp/* Requested CIs */,int *len/* Length of requested
|
|||
}
|
||||
GETCHAR(cflag, p);
|
||||
if (cflag && !ao->cflag) {
|
||||
IPCPDEBUG((LOG_INFO, "ipcp_reqci: Naking VJ cflag %d\n", cflag));
|
||||
IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Naking VJ cflag %d\n", cflag));
|
||||
orc = CONFNAK;
|
||||
if (!reject_if_disagree) {
|
||||
DECPTR(1, p);
|
||||
|
@ -1131,13 +1115,13 @@ ipcp_reqci(fsm *f, u_char *inp/* Requested CIs */,int *len/* Length of requested
|
|||
ho->maxslotindex = MAX_SLOTS - 1;
|
||||
ho->cflag = 1;
|
||||
}
|
||||
IPCPDEBUG((LOG_INFO,
|
||||
IPCPDEBUG(LOG_INFO, (
|
||||
"ipcp_reqci: received COMPRESSTYPE p=%d old=%d maxslot=%d cflag=%d\n",
|
||||
ho->vj_protocol, ho->old_vj, ho->maxslotindex, ho->cflag));
|
||||
break;
|
||||
|
||||
default:
|
||||
IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting unknown CI type %d\n", citype));
|
||||
IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting unknown CI type %d\n", citype));
|
||||
orc = CONFREJ;
|
||||
break;
|
||||
}
|
||||
|
@ -1150,7 +1134,7 @@ endswitch:
|
|||
|
||||
if (orc == CONFNAK) { /* Nak this CI? */
|
||||
if (reject_if_disagree) { /* Getting fed up with sending NAKs? */
|
||||
IPCPDEBUG((LOG_INFO, "ipcp_reqci: Rejecting too many naks\n"));
|
||||
IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Rejecting too many naks\n"));
|
||||
orc = CONFREJ; /* Get tough if so */
|
||||
} else {
|
||||
if (rc == CONFREJ) { /* Rejecting prior CI? */
|
||||
|
@ -1187,7 +1171,7 @@ endswitch:
|
|||
*/
|
||||
if (rc != CONFREJ && !ho->neg_addr &&
|
||||
wo->req_addr && !reject_if_disagree) {
|
||||
IPCPDEBUG((LOG_INFO, "ipcp_reqci: Requesting peer address\n"));
|
||||
IPCPDEBUG(LOG_INFO, ("ipcp_reqci: Requesting peer address\n"));
|
||||
if (rc == CONFACK) {
|
||||
rc = CONFNAK;
|
||||
ucp = inp; /* reset pointer */
|
||||
|
@ -1200,7 +1184,7 @@ endswitch:
|
|||
}
|
||||
|
||||
*len = (int)(ucp - inp); /* Compute output length */
|
||||
IPCPDEBUG((LOG_INFO, "ipcp_reqci: returning Configure-%s\n", CODENAME(rc)));
|
||||
IPCPDEBUG(LOG_INFO, ("ipcp_reqci: returning Configure-%s\n", CODENAME(rc)));
|
||||
return (rc); /* Return final code */
|
||||
}
|
||||
|
||||
|
@ -1241,7 +1225,7 @@ ipcp_up(fsm *f)
|
|||
ipcp_options *wo = &ipcp_wantoptions[f->unit];
|
||||
|
||||
np_up(f->unit, PPP_IP);
|
||||
IPCPDEBUG((LOG_INFO, "ipcp: up\n"));
|
||||
IPCPDEBUG(LOG_INFO, ("ipcp: up\n"));
|
||||
|
||||
/*
|
||||
* We must have a non-zero IP address for both ends of the link.
|
||||
|
@ -1251,12 +1235,12 @@ ipcp_up(fsm *f)
|
|||
}
|
||||
|
||||
if (ho->hisaddr == 0) {
|
||||
IPCPDEBUG((LOG_ERR, "Could not determine remote IP address\n"));
|
||||
IPCPDEBUG(LOG_ERR, ("Could not determine remote IP address\n"));
|
||||
ipcp_close(f->unit, "Could not determine remote IP address");
|
||||
return;
|
||||
}
|
||||
if (go->ouraddr == 0) {
|
||||
IPCPDEBUG((LOG_ERR, "Could not determine local IP address\n"));
|
||||
IPCPDEBUG(LOG_ERR, ("Could not determine local IP address\n"));
|
||||
ipcp_close(f->unit, "Could not determine local IP address");
|
||||
return;
|
||||
}
|
||||
|
@ -1269,7 +1253,7 @@ ipcp_up(fsm *f)
|
|||
* Check that the peer is allowed to use the IP address it wants.
|
||||
*/
|
||||
if (!auth_ip_addr(f->unit, ho->hisaddr)) {
|
||||
IPCPDEBUG((LOG_ERR, "Peer is not authorized to use remote address %s\n",
|
||||
IPCPDEBUG(LOG_ERR, ("Peer is not authorized to use remote address %s\n",
|
||||
inet_ntoa(ho->hisaddr)));
|
||||
ipcp_close(f->unit, "Unauthorized remote IP address");
|
||||
return;
|
||||
|
@ -1284,14 +1268,14 @@ ipcp_up(fsm *f)
|
|||
mask = GetMask(go->ouraddr);
|
||||
|
||||
if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask, go->dnsaddr[0], go->dnsaddr[1])) {
|
||||
IPCPDEBUG((LOG_WARNING, "sifaddr failed\n"));
|
||||
IPCPDEBUG(LOG_WARNING, ("sifaddr failed\n"));
|
||||
ipcp_close(f->unit, "Interface configuration failed");
|
||||
return;
|
||||
}
|
||||
|
||||
/* bring the interface up for IP */
|
||||
if (!sifup(f->unit)) {
|
||||
IPCPDEBUG((LOG_WARNING, "sifup failed\n"));
|
||||
IPCPDEBUG(LOG_WARNING, ("sifup failed\n"));
|
||||
ipcp_close(f->unit, "Interface configuration failed");
|
||||
return;
|
||||
}
|
||||
|
@ -1305,13 +1289,13 @@ ipcp_up(fsm *f)
|
|||
}
|
||||
}
|
||||
|
||||
IPCPDEBUG((LOG_NOTICE, "local IP address %s\n", inet_ntoa(go->ouraddr)));
|
||||
IPCPDEBUG((LOG_NOTICE, "remote IP address %s\n", inet_ntoa(ho->hisaddr)));
|
||||
IPCPDEBUG(LOG_NOTICE, ("local IP address %s\n", inet_ntoa(go->ouraddr)));
|
||||
IPCPDEBUG(LOG_NOTICE, ("remote IP address %s\n", inet_ntoa(ho->hisaddr)));
|
||||
if (go->dnsaddr[0]) {
|
||||
IPCPDEBUG((LOG_NOTICE, "primary DNS address %s\n", inet_ntoa(go->dnsaddr[0])));
|
||||
IPCPDEBUG(LOG_NOTICE, ("primary DNS address %s\n", inet_ntoa(go->dnsaddr[0])));
|
||||
}
|
||||
if (go->dnsaddr[1]) {
|
||||
IPCPDEBUG((LOG_NOTICE, "secondary DNS address %s\n", inet_ntoa(go->dnsaddr[1])));
|
||||
IPCPDEBUG(LOG_NOTICE, ("secondary DNS address %s\n", inet_ntoa(go->dnsaddr[1])));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1325,7 +1309,7 @@ ipcp_up(fsm *f)
|
|||
static void
|
||||
ipcp_down(fsm *f)
|
||||
{
|
||||
IPCPDEBUG((LOG_INFO, "ipcp: down\n"));
|
||||
IPCPDEBUG(LOG_INFO, ("ipcp: down\n"));
|
||||
np_down(f->unit, PPP_IP);
|
||||
sifvjcomp(f->unit, 0, 0, 0);
|
||||
|
||||
|
@ -1361,7 +1345,7 @@ ipcp_finished(fsm *f)
|
|||
np_finished(f->unit, PPP_IP);
|
||||
}
|
||||
|
||||
#if 0
|
||||
#if PPP_ADDITIONAL_CALLBACKS
|
||||
static int
|
||||
ipcp_printpkt(u_char *p, int plen, void (*printer) (void *, char *, ...), void *arg)
|
||||
{
|
||||
|
@ -1422,6 +1406,6 @@ ip_active_pkt(u_char *pkt, int len)
|
|||
}
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
#endif /* PPP_ADDITIONAL_CALLBACKS */
|
||||
|
||||
#endif /* PPP_SUPPORT */
|
||||
|
|
|
@ -48,15 +48,12 @@
|
|||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: ipcp.h,v 1.3 2007/12/19 20:47:23 fbernon Exp $
|
||||
* $Id: ipcp.h,v 1.4 2010/01/18 20:49:43 goldsimon Exp $
|
||||
*/
|
||||
|
||||
#ifndef IPCP_H
|
||||
#define IPCP_H
|
||||
|
||||
/*************************
|
||||
*** PUBLIC DEFINITIONS ***
|
||||
*************************/
|
||||
/*
|
||||
* Options.
|
||||
*/
|
||||
|
@ -64,10 +61,10 @@
|
|||
#define CI_COMPRESSTYPE 2 /* Compression Type */
|
||||
#define CI_ADDR 3
|
||||
|
||||
#define CI_MS_WINS1 128 /* Primary WINS value */
|
||||
#define CI_MS_DNS1 129 /* Primary DNS value */
|
||||
#define CI_MS_WINS2 130 /* Secondary WINS value */
|
||||
#define CI_MS_WINS1 128 /* Primary WINS value */
|
||||
#define CI_MS_DNS2 131 /* Secondary DNS value */
|
||||
#define CI_MS_WINS2 130 /* Secondary WINS value */
|
||||
|
||||
#define IPCP_VJMODE_OLD 1 /* "old" mode (option # = 0x0037) */
|
||||
#define IPCP_VJMODE_RFC1172 2 /* "old-rfc"mode (option # = 0x002d) */
|
||||
|
@ -78,11 +75,6 @@
|
|||
#define IPCP_VJ_COMP_OLD 0x0037 /* "old" (i.e, broken) value for VJ */
|
||||
/* compression option */
|
||||
|
||||
|
||||
/************************
|
||||
*** PUBLIC DATA TYPES ***
|
||||
************************/
|
||||
|
||||
typedef struct ipcp_options {
|
||||
u_int neg_addr : 1; /* Negotiate IP Address? */
|
||||
u_int old_addrs : 1; /* Use old (IP-Addresses) option? */
|
||||
|
@ -103,11 +95,6 @@ typedef struct ipcp_options {
|
|||
u32_t winsaddr[2]; /* Primary and secondary MS WINS entries */
|
||||
} ipcp_options;
|
||||
|
||||
|
||||
/*****************************
|
||||
*** PUBLIC DATA STRUCTURES ***
|
||||
*****************************/
|
||||
|
||||
extern fsm ipcp_fsm[];
|
||||
extern ipcp_options ipcp_wantoptions[];
|
||||
extern ipcp_options ipcp_gotoptions[];
|
||||
|
@ -116,9 +103,4 @@ extern ipcp_options ipcp_hisoptions[];
|
|||
|
||||
extern struct protent ipcp_protent;
|
||||
|
||||
|
||||
/***********************
|
||||
*** PUBLIC FUNCTIONS ***
|
||||
***********************/
|
||||
|
||||
#endif /* IPCP_H */
|
||||
|
|
|
@ -72,25 +72,43 @@
|
|||
#define PPPOE_MAXMTU PPP_MAXMRU
|
||||
#endif
|
||||
|
||||
|
||||
/*************************/
|
||||
/*** LOCAL DEFINITIONS ***/
|
||||
/*************************/
|
||||
#if 0 /* UNUSED */
|
||||
/*
|
||||
* Length of each type of configuration option (in octets)
|
||||
* LCP-related command-line options.
|
||||
*/
|
||||
#define CILEN_VOID 2
|
||||
#define CILEN_CHAR 3
|
||||
#define CILEN_SHORT 4 /* CILEN_VOID + sizeof(short) */
|
||||
#define CILEN_CHAP 5 /* CILEN_VOID + sizeof(short) + 1 */
|
||||
#define CILEN_LONG 6 /* CILEN_VOID + sizeof(long) */
|
||||
#define CILEN_LQR 8 /* CILEN_VOID + sizeof(short) + sizeof(long) */
|
||||
#define CILEN_CBCP 3
|
||||
int lcp_echo_interval = 0; /* Interval between LCP echo-requests */
|
||||
int lcp_echo_fails = 0; /* Tolerance to unanswered echo-requests */
|
||||
bool lax_recv = 0; /* accept control chars in asyncmap */
|
||||
|
||||
static int setescape (char **);
|
||||
|
||||
static option_t lcp_option_list[] = {
|
||||
/* LCP options */
|
||||
/* list stripped for simplicity */
|
||||
{NULL}
|
||||
};
|
||||
#endif /* UNUSED */
|
||||
|
||||
/* options */
|
||||
LinkPhase lcp_phase[NUM_PPP]; /* Phase of link session (RFC 1661) */
|
||||
static u_int lcp_echo_interval = LCP_ECHOINTERVAL; /* Interval between LCP echo-requests */
|
||||
static u_int lcp_echo_fails = LCP_MAXECHOFAILS; /* Tolerance to unanswered echo-requests */
|
||||
|
||||
/* global vars */
|
||||
static fsm lcp_fsm[NUM_PPP]; /* LCP fsm structure (global)*/
|
||||
lcp_options lcp_wantoptions[NUM_PPP]; /* Options that we want to request */
|
||||
lcp_options lcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */
|
||||
lcp_options lcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */
|
||||
lcp_options lcp_hisoptions[NUM_PPP]; /* Options that we ack'd */
|
||||
ext_accm xmit_accm[NUM_PPP]; /* extended transmit ACCM */
|
||||
|
||||
static u32_t lcp_echos_pending = 0; /* Number of outstanding echo msgs */
|
||||
static u32_t lcp_echo_number = 0; /* ID number of next echo frame */
|
||||
static u32_t lcp_echo_timer_running = 0; /* TRUE if a timer is running */
|
||||
|
||||
/* @todo: do we really need such a large buffer? The typical 1500 bytes seem too much. */
|
||||
static u_char nak_buffer[PPP_MRU]; /* where we construct a nak packet */
|
||||
|
||||
/***********************************/
|
||||
/*** LOCAL FUNCTION DECLARATIONS ***/
|
||||
/***********************************/
|
||||
/*
|
||||
* Callbacks for fsm code. (CI = Configuration Information)
|
||||
*/
|
||||
|
@ -106,12 +124,12 @@ static void lcp_down (fsm*); /* We're DOWN */
|
|||
static void lcp_starting (fsm*); /* We need lower layer up */
|
||||
static void lcp_finished (fsm*); /* We need lower layer down */
|
||||
static int lcp_extcode (fsm*, int, u_char, u_char*, int);
|
||||
|
||||
static void lcp_rprotrej (fsm*, u_char*, int);
|
||||
|
||||
/*
|
||||
* routines to send LCP echos to peer
|
||||
*/
|
||||
|
||||
static void lcp_echo_lowerup (int);
|
||||
static void lcp_echo_lowerdown (int);
|
||||
static void LcpEchoTimeout (void*);
|
||||
|
@ -120,41 +138,6 @@ static void LcpSendEchoRequest (fsm*);
|
|||
static void LcpLinkFailure (fsm*);
|
||||
static void LcpEchoCheck (fsm*);
|
||||
|
||||
/*
|
||||
* Protocol entry points.
|
||||
* Some of these are called directly.
|
||||
*/
|
||||
static void lcp_input (int, u_char *, int);
|
||||
static void lcp_protrej (int);
|
||||
|
||||
#define CODENAME(x) ((x) == CONFACK ? "ACK" : (x) == CONFNAK ? "NAK" : "REJ")
|
||||
|
||||
|
||||
/******************************/
|
||||
/*** PUBLIC DATA STRUCTURES ***/
|
||||
/******************************/
|
||||
/* global vars */
|
||||
LinkPhase lcp_phase[NUM_PPP]; /* Phase of link session (RFC 1661) */
|
||||
lcp_options lcp_wantoptions[NUM_PPP]; /* Options that we want to request */
|
||||
lcp_options lcp_gotoptions[NUM_PPP]; /* Options that peer ack'd */
|
||||
lcp_options lcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */
|
||||
lcp_options lcp_hisoptions[NUM_PPP]; /* Options that we ack'd */
|
||||
ext_accm xmit_accm[NUM_PPP]; /* extended transmit ACCM */
|
||||
|
||||
|
||||
|
||||
/*****************************/
|
||||
/*** LOCAL DATA STRUCTURES ***/
|
||||
/*****************************/
|
||||
static fsm lcp_fsm[NUM_PPP]; /* LCP fsm structure (global)*/
|
||||
static u_int lcp_echo_interval = LCP_ECHOINTERVAL; /* Interval between LCP echo-requests */
|
||||
static u_int lcp_echo_fails = LCP_MAXECHOFAILS; /* Tolerance to unanswered echo-requests */
|
||||
static u32_t lcp_echos_pending = 0; /* Number of outstanding echo msgs */
|
||||
static u32_t lcp_echo_number = 0; /* ID number of next echo frame */
|
||||
static u32_t lcp_echo_timer_running = 0; /* TRUE if a timer is running */
|
||||
|
||||
static u_char nak_buffer[PPP_MRU]; /* where we construct a nak packet */
|
||||
|
||||
static fsm_callbacks lcp_callbacks = { /* LCP callback routines */
|
||||
lcp_resetci, /* Reset our Configuration Information */
|
||||
lcp_cilen, /* Length of our Configuration Information */
|
||||
|
@ -173,6 +156,14 @@ static fsm_callbacks lcp_callbacks = { /* LCP callback routines */
|
|||
"LCP" /* String name of protocol */
|
||||
};
|
||||
|
||||
/*
|
||||
* Protocol entry points.
|
||||
* Some of these are called directly.
|
||||
*/
|
||||
|
||||
static void lcp_input (int, u_char *, int);
|
||||
static void lcp_protrej (int);
|
||||
|
||||
struct protent lcp_protent = {
|
||||
PPP_LCP,
|
||||
lcp_init,
|
||||
|
@ -182,26 +173,66 @@ struct protent lcp_protent = {
|
|||
lcp_lowerdown,
|
||||
lcp_open,
|
||||
lcp_close,
|
||||
#if 0
|
||||
#if PPP_ADDITIONAL_CALLBACKS
|
||||
lcp_printpkt,
|
||||
NULL,
|
||||
#endif
|
||||
#endif /* PPP_ADDITIONAL_CALLBACKS */
|
||||
1,
|
||||
"LCP",
|
||||
#if 0
|
||||
#if PPP_ADDITIONAL_CALLBACKS
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
#endif
|
||||
#endif /* PPP_ADDITIONAL_CALLBACKS */
|
||||
};
|
||||
|
||||
int lcp_loopbackfail = DEFLOOPBACKFAIL;
|
||||
|
||||
/*
|
||||
* Length of each type of configuration option (in octets)
|
||||
*/
|
||||
#define CILEN_VOID 2
|
||||
#define CILEN_CHAR 3
|
||||
#define CILEN_SHORT 4 /* CILEN_VOID + sizeof(short) */
|
||||
#define CILEN_CHAP 5 /* CILEN_VOID + sizeof(short) + 1 */
|
||||
#define CILEN_LONG 6 /* CILEN_VOID + sizeof(long) */
|
||||
#define CILEN_LQR 8 /* CILEN_VOID + sizeof(short) + sizeof(long) */
|
||||
#define CILEN_CBCP 3
|
||||
|
||||
#define CODENAME(x) ((x) == CONFACK ? "ACK" : (x) == CONFNAK ? "NAK" : "REJ")
|
||||
|
||||
#if 0 /* UNUSED */
|
||||
/*
|
||||
* setescape - add chars to the set we escape on transmission.
|
||||
*/
|
||||
static int
|
||||
setescape(argv)
|
||||
char **argv;
|
||||
{
|
||||
int n, ret;
|
||||
char *p, *endp;
|
||||
|
||||
p = *argv;
|
||||
ret = 1;
|
||||
while (*p) {
|
||||
n = strtol(p, &endp, 16);
|
||||
if (p == endp) {
|
||||
option_error("escape parameter contains invalid hex number '%s'", p);
|
||||
return 0;
|
||||
}
|
||||
p = endp;
|
||||
if (n < 0 || n == 0x5E || n > 0xFF) {
|
||||
option_error("can't escape character 0x%x", n);
|
||||
ret = 0;
|
||||
} else
|
||||
xmit_accm[0][n >> 5] |= 1 << (n & 0x1F);
|
||||
while (*p == ',' || *p == ' ')
|
||||
++p;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif /* UNUSED */
|
||||
|
||||
/***********************************/
|
||||
/*** PUBLIC FUNCTION DEFINITIONS ***/
|
||||
/***********************************/
|
||||
/*
|
||||
* lcp_init - Initialize LCP.
|
||||
*/
|
||||
|
@ -211,13 +242,13 @@ lcp_init(int unit)
|
|||
fsm *f = &lcp_fsm[unit];
|
||||
lcp_options *wo = &lcp_wantoptions[unit];
|
||||
lcp_options *ao = &lcp_allowoptions[unit];
|
||||
|
||||
|
||||
f->unit = unit;
|
||||
f->protocol = PPP_LCP;
|
||||
f->callbacks = &lcp_callbacks;
|
||||
|
||||
|
||||
fsm_init(f);
|
||||
|
||||
|
||||
wo->passive = 0;
|
||||
wo->silent = 0;
|
||||
wo->restart = 0; /* Set to 1 in kernels or multi-line implementations */
|
||||
|
@ -233,7 +264,7 @@ lcp_init(int unit)
|
|||
wo->neg_accompression = 1;
|
||||
wo->neg_lqr = 0; /* no LQR implementation yet */
|
||||
wo->neg_cbcp = 0;
|
||||
|
||||
|
||||
ao->neg_mru = 1;
|
||||
ao->mru = PPP_MAXMRU;
|
||||
ao->neg_asyncmap = 1;
|
||||
|
@ -257,7 +288,7 @@ lcp_init(int unit)
|
|||
xmit_accm[unit][1] = (u_char)((ao->asyncmap >> 8) & 0xFF);
|
||||
xmit_accm[unit][2] = (u_char)((ao->asyncmap >> 16) & 0xFF);
|
||||
xmit_accm[unit][3] = (u_char)((ao->asyncmap >> 24) & 0xFF);
|
||||
LCPDEBUG((LOG_INFO, "lcp_init: xmit_accm=%X %X %X %X\n",
|
||||
LCPDEBUG(LOG_INFO, ("lcp_init: xmit_accm=%X %X %X %X\n",
|
||||
xmit_accm[unit][0],
|
||||
xmit_accm[unit][1],
|
||||
xmit_accm[unit][2],
|
||||
|
@ -310,7 +341,7 @@ lcp_close(int unit, char *reason)
|
|||
f->state = LS_CLOSED;
|
||||
lcp_finished(f);
|
||||
} else {
|
||||
fsm_close(&lcp_fsm[unit], reason);
|
||||
fsm_close(f, reason);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -337,7 +368,7 @@ lcp_lowerup(int unit)
|
|||
| ((u_long)xmit_accm[unit][1] << 8)
|
||||
| ((u_long)xmit_accm[unit][2] << 16)
|
||||
| ((u_long)xmit_accm[unit][3] << 24);
|
||||
LCPDEBUG((LOG_INFO, "lcp_lowerup: asyncmap=%X %X %X %X\n",
|
||||
LCPDEBUG(LOG_INFO, ("lcp_lowerup: asyncmap=%X %X %X %X\n",
|
||||
xmit_accm[unit][3],
|
||||
xmit_accm[unit][2],
|
||||
xmit_accm[unit][1],
|
||||
|
@ -356,25 +387,7 @@ lcp_lowerdown(int unit)
|
|||
fsm_lowerdown(&lcp_fsm[unit]);
|
||||
}
|
||||
|
||||
/*
|
||||
* lcp_sprotrej - Send a Protocol-Reject for some protocol.
|
||||
*/
|
||||
void
|
||||
lcp_sprotrej(int unit, u_char *p, int len)
|
||||
{
|
||||
/*
|
||||
* Send back the protocol and the information field of the
|
||||
* rejected packet. We only get here if LCP is in the LS_OPENED state.
|
||||
*/
|
||||
|
||||
fsm_sdata(&lcp_fsm[unit], PROTREJ, ++lcp_fsm[unit].id, p, len);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**********************************/
|
||||
/*** LOCAL FUNCTION DEFINITIONS ***/
|
||||
/**********************************/
|
||||
/*
|
||||
* lcp_input - Input LCP packet.
|
||||
*/
|
||||
|
@ -404,7 +417,7 @@ lcp_extcode(fsm *f, int code, u_char id, u_char *inp, int len)
|
|||
if (f->state != LS_OPENED) {
|
||||
break;
|
||||
}
|
||||
LCPDEBUG((LOG_INFO, "lcp: Echo-Request, Rcvd id %d\n", id));
|
||||
LCPDEBUG(LOG_INFO, ("lcp: Echo-Request, Rcvd id %d\n", id));
|
||||
magp = inp;
|
||||
PUTLONG(lcp_gotoptions[f->unit].magicnumber, magp);
|
||||
fsm_sdata(f, ECHOREP, id, inp, len);
|
||||
|
@ -413,10 +426,10 @@ lcp_extcode(fsm *f, int code, u_char id, u_char *inp, int len)
|
|||
case ECHOREP:
|
||||
lcp_received_echo_reply(f, id, inp, len);
|
||||
break;
|
||||
|
||||
|
||||
case DISCREQ:
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
@ -436,21 +449,21 @@ lcp_rprotrej(fsm *f, u_char *inp, int len)
|
|||
struct protent *protp;
|
||||
u_short prot;
|
||||
|
||||
if (len < sizeof (u_short)) {
|
||||
LCPDEBUG((LOG_INFO, "lcp_rprotrej: Rcvd short Protocol-Reject packet!\n"));
|
||||
if (len < (int)sizeof (u_short)) {
|
||||
LCPDEBUG(LOG_INFO, ("lcp_rprotrej: Rcvd short Protocol-Reject packet!\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
GETSHORT(prot, inp);
|
||||
|
||||
LCPDEBUG((LOG_INFO, "lcp_rprotrej: Rcvd Protocol-Reject packet for %x!\n", prot));
|
||||
LCPDEBUG(LOG_INFO, ("lcp_rprotrej: Rcvd Protocol-Reject packet for %x!\n", prot));
|
||||
|
||||
/*
|
||||
* Protocol-Reject packets received in any state other than the LCP
|
||||
* LS_OPENED state SHOULD be silently discarded.
|
||||
*/
|
||||
if( f->state != LS_OPENED ) {
|
||||
LCPDEBUG((LOG_INFO, "Protocol-Reject discarded: LCP in state %d\n", f->state));
|
||||
LCPDEBUG(LOG_INFO, ("Protocol-Reject discarded: LCP in state %d\n", f->state));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -464,7 +477,7 @@ lcp_rprotrej(fsm *f, u_char *inp, int len)
|
|||
}
|
||||
}
|
||||
|
||||
LCPDEBUG((LOG_WARNING, "Protocol-Reject for unsupported protocol 0x%x\n", prot));
|
||||
LCPDEBUG(LOG_WARNING, ("Protocol-Reject for unsupported protocol 0x%x\n", prot));
|
||||
}
|
||||
|
||||
|
||||
|
@ -478,11 +491,26 @@ lcp_protrej(int unit)
|
|||
/*
|
||||
* Can't reject LCP!
|
||||
*/
|
||||
LCPDEBUG((LOG_WARNING, "lcp_protrej: Received Protocol-Reject for LCP!\n"));
|
||||
LCPDEBUG(LOG_WARNING, ("lcp_protrej: Received Protocol-Reject for LCP!\n"));
|
||||
fsm_protreject(&lcp_fsm[unit]);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* lcp_sprotrej - Send a Protocol-Reject for some protocol.
|
||||
*/
|
||||
void
|
||||
lcp_sprotrej(int unit, u_char *p, int len)
|
||||
{
|
||||
/*
|
||||
* Send back the protocol and the information field of the
|
||||
* rejected packet. We only get here if LCP is in the LS_OPENED state.
|
||||
*/
|
||||
|
||||
fsm_sdata(&lcp_fsm[unit], PROTREJ, ++lcp_fsm[unit].id, p, len);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* lcp_resetci - Reset our CI.
|
||||
*/
|
||||
|
@ -500,7 +528,8 @@ lcp_resetci(fsm *f)
|
|||
/*
|
||||
* lcp_cilen - Return length of our CI.
|
||||
*/
|
||||
static int lcp_cilen(fsm *f)
|
||||
static int
|
||||
lcp_cilen(fsm *f)
|
||||
{
|
||||
lcp_options *go = &lcp_gotoptions[f->unit];
|
||||
|
||||
|
@ -537,20 +566,20 @@ lcp_addci(fsm *f, u_char *ucp, int *lenp)
|
|||
|
||||
#define ADDCIVOID(opt, neg) \
|
||||
if (neg) { \
|
||||
LCPDEBUG((LOG_INFO, "lcp_addci: opt=%d\n", opt)); \
|
||||
LCPDEBUG(LOG_INFO, ("lcp_addci: opt=%d\n", opt)); \
|
||||
PUTCHAR(opt, ucp); \
|
||||
PUTCHAR(CILEN_VOID, ucp); \
|
||||
}
|
||||
#define ADDCISHORT(opt, neg, val) \
|
||||
if (neg) { \
|
||||
LCPDEBUG((LOG_INFO, "lcp_addci: INT opt=%d %X\n", opt, val)); \
|
||||
LCPDEBUG(LOG_INFO, ("lcp_addci: INT opt=%d %X\n", opt, val)); \
|
||||
PUTCHAR(opt, ucp); \
|
||||
PUTCHAR(CILEN_SHORT, ucp); \
|
||||
PUTSHORT(val, ucp); \
|
||||
}
|
||||
#define ADDCICHAP(opt, neg, val, digest) \
|
||||
if (neg) { \
|
||||
LCPDEBUG((LOG_INFO, "lcp_addci: CHAP opt=%d %X\n", opt, val)); \
|
||||
LCPDEBUG(LOG_INFO, ("lcp_addci: CHAP opt=%d %X\n", opt, val)); \
|
||||
PUTCHAR(opt, ucp); \
|
||||
PUTCHAR(CILEN_CHAP, ucp); \
|
||||
PUTSHORT(val, ucp); \
|
||||
|
@ -558,14 +587,14 @@ lcp_addci(fsm *f, u_char *ucp, int *lenp)
|
|||
}
|
||||
#define ADDCILONG(opt, neg, val) \
|
||||
if (neg) { \
|
||||
LCPDEBUG((LOG_INFO, "lcp_addci: L opt=%d %lX\n", opt, val)); \
|
||||
LCPDEBUG(LOG_INFO, ("lcp_addci: L opt=%d %lX\n", opt, val)); \
|
||||
PUTCHAR(opt, ucp); \
|
||||
PUTCHAR(CILEN_LONG, ucp); \
|
||||
PUTLONG(val, ucp); \
|
||||
}
|
||||
#define ADDCILQR(opt, neg, val) \
|
||||
if (neg) { \
|
||||
LCPDEBUG((LOG_INFO, "lcp_addci: LQR opt=%d %lX\n", opt, val)); \
|
||||
LCPDEBUG(LOG_INFO, ("lcp_addci: LQR opt=%d %lX\n", opt, val)); \
|
||||
PUTCHAR(opt, ucp); \
|
||||
PUTCHAR(CILEN_LQR, ucp); \
|
||||
PUTSHORT(PPP_LQR, ucp); \
|
||||
|
@ -573,7 +602,7 @@ lcp_addci(fsm *f, u_char *ucp, int *lenp)
|
|||
}
|
||||
#define ADDCICHAR(opt, neg, val) \
|
||||
if (neg) { \
|
||||
LCPDEBUG((LOG_INFO, "lcp_addci: CHAR opt=%d %X '%z'\n", opt, val, val)); \
|
||||
LCPDEBUG(LOG_INFO, ("lcp_addci: CHAR opt=%d %X '%z'\n", opt, val, val)); \
|
||||
PUTCHAR(opt, ucp); \
|
||||
PUTCHAR(CILEN_CHAR, ucp); \
|
||||
PUTCHAR(val, ucp); \
|
||||
|
@ -591,7 +620,7 @@ lcp_addci(fsm *f, u_char *ucp, int *lenp)
|
|||
|
||||
if (ucp - start_ucp != *lenp) {
|
||||
/* this should never happen, because peer_mtu should be 1500 */
|
||||
LCPDEBUG((LOG_ERR, "Bug in lcp_addci: wrong length\n"));
|
||||
LCPDEBUG(LOG_ERR, ("Bug in lcp_addci: wrong length\n"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -709,10 +738,10 @@ lcp_ackci(fsm *f, u_char *p, int len)
|
|||
if (len != 0) {
|
||||
goto bad;
|
||||
}
|
||||
LCPDEBUG((LOG_INFO, "lcp_acki: Ack\n"));
|
||||
LCPDEBUG(LOG_INFO, ("lcp_acki: Ack\n"));
|
||||
return (1);
|
||||
bad:
|
||||
LCPDEBUG((LOG_WARNING, "lcp_acki: received bad Ack!\n"));
|
||||
LCPDEBUG(LOG_WARNING, ("lcp_acki: received bad Ack!\n"));
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -1020,7 +1049,7 @@ lcp_nakci(fsm *f, u_char *p, int len)
|
|||
if (f->state != LS_OPENED) {
|
||||
if (looped_back) {
|
||||
if (++try.numloops >= lcp_loopbackfail) {
|
||||
LCPDEBUG((LOG_NOTICE, "Serial line is looped back.\n"));
|
||||
LCPDEBUG(LOG_NOTICE, ("Serial line is looped back.\n"));
|
||||
lcp_close(f->unit, "Loopback detected");
|
||||
}
|
||||
} else {
|
||||
|
@ -1032,7 +1061,7 @@ lcp_nakci(fsm *f, u_char *p, int len)
|
|||
return 1;
|
||||
|
||||
bad:
|
||||
LCPDEBUG((LOG_WARNING, "lcp_nakci: received bad Nak!\n"));
|
||||
LCPDEBUG(LOG_WARNING, ("lcp_nakci: received bad Nak!\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1070,7 +1099,7 @@ lcp_rejci(fsm *f, u_char *p, int len)
|
|||
len -= CILEN_VOID; \
|
||||
INCPTR(CILEN_VOID, p); \
|
||||
try.neg = 0; \
|
||||
LCPDEBUG((LOG_INFO, "lcp_rejci: void opt %d rejected\n", opt)); \
|
||||
LCPDEBUG(LOG_INFO, ("lcp_rejci: void opt %d rejected\n", opt)); \
|
||||
}
|
||||
#define REJCISHORT(opt, neg, val) \
|
||||
if (go->neg && \
|
||||
|
@ -1085,7 +1114,7 @@ lcp_rejci(fsm *f, u_char *p, int len)
|
|||
goto bad; \
|
||||
} \
|
||||
try.neg = 0; \
|
||||
LCPDEBUG((LOG_INFO,"lcp_rejci: short opt %d rejected\n", opt)); \
|
||||
LCPDEBUG(LOG_INFO, ("lcp_rejci: short opt %d rejected\n", opt)); \
|
||||
}
|
||||
#define REJCICHAP(opt, neg, val, digest) \
|
||||
if (go->neg && \
|
||||
|
@ -1102,7 +1131,7 @@ lcp_rejci(fsm *f, u_char *p, int len)
|
|||
} \
|
||||
try.neg = 0; \
|
||||
try.neg_upap = 0; \
|
||||
LCPDEBUG((LOG_INFO,"lcp_rejci: chap opt %d rejected\n", opt)); \
|
||||
LCPDEBUG(LOG_INFO, ("lcp_rejci: chap opt %d rejected\n", opt)); \
|
||||
}
|
||||
#define REJCILONG(opt, neg, val) \
|
||||
if (go->neg && \
|
||||
|
@ -1117,7 +1146,7 @@ lcp_rejci(fsm *f, u_char *p, int len)
|
|||
goto bad; \
|
||||
} \
|
||||
try.neg = 0; \
|
||||
LCPDEBUG((LOG_INFO,"lcp_rejci: long opt %d rejected\n", opt)); \
|
||||
LCPDEBUG(LOG_INFO, ("lcp_rejci: long opt %d rejected\n", opt)); \
|
||||
}
|
||||
#define REJCILQR(opt, neg, val) \
|
||||
if (go->neg && \
|
||||
|
@ -1133,7 +1162,7 @@ lcp_rejci(fsm *f, u_char *p, int len)
|
|||
goto bad; \
|
||||
} \
|
||||
try.neg = 0; \
|
||||
LCPDEBUG((LOG_INFO,"lcp_rejci: LQR opt %d rejected\n", opt)); \
|
||||
LCPDEBUG(LOG_INFO, ("lcp_rejci: LQR opt %d rejected\n", opt)); \
|
||||
}
|
||||
#define REJCICBCP(opt, neg, val) \
|
||||
if (go->neg && \
|
||||
|
@ -1148,7 +1177,7 @@ lcp_rejci(fsm *f, u_char *p, int len)
|
|||
goto bad; \
|
||||
} \
|
||||
try.neg = 0; \
|
||||
LCPDEBUG((LOG_INFO,"lcp_rejci: Callback opt %d rejected\n", opt)); \
|
||||
LCPDEBUG(LOG_INFO, ("lcp_rejci: Callback opt %d rejected\n", opt)); \
|
||||
}
|
||||
|
||||
REJCISHORT(CI_MRU, neg_mru, go->mru);
|
||||
|
@ -1178,7 +1207,7 @@ lcp_rejci(fsm *f, u_char *p, int len)
|
|||
return 1;
|
||||
|
||||
bad:
|
||||
LCPDEBUG((LOG_WARNING, "lcp_rejci: received bad Reject!\n"));
|
||||
LCPDEBUG(LOG_WARNING, ("lcp_rejci: received bad Reject!\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1200,7 +1229,8 @@ lcp_reqci(fsm *f,
|
|||
lcp_options *ho = &lcp_hisoptions[f->unit];
|
||||
lcp_options *ao = &lcp_allowoptions[f->unit];
|
||||
u_char *cip, *next; /* Pointer to current and next CIs */
|
||||
int cilen, citype, cichar; /* Parsed len, type, char value */
|
||||
int cilen, citype; /* Parsed len, type */
|
||||
u_char cichar; /* Parsed char value */
|
||||
u_short cishort; /* Parsed short value */
|
||||
u32_t cilong; /* Parse long value */
|
||||
int rc = CONFACK; /* Final packet return code */
|
||||
|
@ -1211,7 +1241,7 @@ lcp_reqci(fsm *f,
|
|||
int l = *lenp; /* Length left */
|
||||
#if TRACELCP > 0
|
||||
char traceBuf[80];
|
||||
int traceNdx = 0;
|
||||
size_t traceNdx = 0;
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -1231,7 +1261,7 @@ lcp_reqci(fsm *f,
|
|||
if (l < 2 || /* Not enough data for CI header or */
|
||||
p[1] < 2 || /* CI length too small or */
|
||||
p[1] > l) { /* CI length too big? */
|
||||
LCPDEBUG((LOG_WARNING, "lcp_reqci: bad CI length!\n"));
|
||||
LCPDEBUG(LOG_WARNING, ("lcp_reqci: bad CI length!\n"));
|
||||
orc = CONFREJ; /* Reject bad CI */
|
||||
cilen = l; /* Reject till end of packet */
|
||||
l = 0; /* Don't loop again */
|
||||
|
@ -1246,11 +1276,11 @@ lcp_reqci(fsm *f,
|
|||
switch (citype) { /* Check CI type */
|
||||
case CI_MRU:
|
||||
if (!ao->neg_mru) { /* Allow option? */
|
||||
LCPDEBUG((LOG_INFO, "lcp_reqci: Reject MRU - not allowed\n"));
|
||||
LCPDEBUG(LOG_INFO, ("lcp_reqci: Reject MRU - not allowed\n"));
|
||||
orc = CONFREJ; /* Reject CI */
|
||||
break;
|
||||
} else if (cilen != CILEN_SHORT) { /* Check CI length */
|
||||
LCPDEBUG((LOG_INFO, "lcp_reqci: Reject MRU - bad length\n"));
|
||||
LCPDEBUG(LOG_INFO, ("lcp_reqci: Reject MRU - bad length\n"));
|
||||
orc = CONFREJ; /* Reject CI */
|
||||
break;
|
||||
}
|
||||
|
@ -1262,7 +1292,7 @@ lcp_reqci(fsm *f,
|
|||
* we'll just ignore it.
|
||||
*/
|
||||
if (cishort < PPP_MINMRU) {
|
||||
LCPDEBUG((LOG_INFO, "lcp_reqci: Nak - MRU too small\n"));
|
||||
LCPDEBUG(LOG_INFO, ("lcp_reqci: Nak - MRU too small\n"));
|
||||
orc = CONFNAK; /* Nak CI */
|
||||
PUTCHAR(CI_MRU, nakp);
|
||||
PUTCHAR(CILEN_SHORT, nakp);
|
||||
|
@ -1279,11 +1309,11 @@ lcp_reqci(fsm *f,
|
|||
|
||||
case CI_ASYNCMAP:
|
||||
if (!ao->neg_asyncmap) {
|
||||
LCPDEBUG((LOG_INFO, "lcp_reqci: Reject ASYNCMAP not allowed\n"));
|
||||
LCPDEBUG(LOG_INFO, ("lcp_reqci: Reject ASYNCMAP not allowed\n"));
|
||||
orc = CONFREJ;
|
||||
break;
|
||||
} else if (cilen != CILEN_LONG) {
|
||||
LCPDEBUG((LOG_INFO, "lcp_reqci: Reject ASYNCMAP bad length\n"));
|
||||
LCPDEBUG(LOG_INFO, ("lcp_reqci: Reject ASYNCMAP bad length\n"));
|
||||
orc = CONFREJ;
|
||||
break;
|
||||
}
|
||||
|
@ -1294,7 +1324,7 @@ lcp_reqci(fsm *f,
|
|||
* which are set in lcp_allowoptions[unit].asyncmap.
|
||||
*/
|
||||
if ((ao->asyncmap & ~cilong) != 0) {
|
||||
LCPDEBUG((LOG_INFO, "lcp_reqci: Nak ASYNCMAP %lX missing %lX\n",
|
||||
LCPDEBUG(LOG_INFO, ("lcp_reqci: Nak ASYNCMAP %lX missing %lX\n",
|
||||
cilong, ao->asyncmap));
|
||||
orc = CONFNAK;
|
||||
PUTCHAR(CI_ASYNCMAP, nakp);
|
||||
|
@ -1312,14 +1342,14 @@ lcp_reqci(fsm *f,
|
|||
|
||||
case CI_AUTHTYPE:
|
||||
if (cilen < CILEN_SHORT) {
|
||||
LCPDEBUG((LOG_INFO, "lcp_reqci: Reject AUTHTYPE missing arg\n"));
|
||||
LCPDEBUG(LOG_INFO, ("lcp_reqci: Reject AUTHTYPE missing arg\n"));
|
||||
orc = CONFREJ;
|
||||
break;
|
||||
} else if (!(ao->neg_upap || ao->neg_chap)) {
|
||||
/*
|
||||
* Reject the option if we're not willing to authenticate.
|
||||
*/
|
||||
LCPDEBUG((LOG_INFO, "lcp_reqci: Reject AUTHTYPE not allowed\n"));
|
||||
LCPDEBUG(LOG_INFO, ("lcp_reqci: Reject AUTHTYPE not allowed\n"));
|
||||
orc = CONFREJ;
|
||||
break;
|
||||
}
|
||||
|
@ -1338,16 +1368,16 @@ lcp_reqci(fsm *f,
|
|||
|
||||
if (cishort == PPP_PAP) {
|
||||
if (ho->neg_chap) { /* we've already accepted CHAP */
|
||||
LCPDEBUG((LOG_WARNING, "lcp_reqci: Reject AUTHTYPE PAP already accepted\n"));
|
||||
LCPDEBUG(LOG_WARNING, ("lcp_reqci: Reject AUTHTYPE PAP already accepted\n"));
|
||||
orc = CONFREJ;
|
||||
break;
|
||||
} else if (cilen != CILEN_SHORT) {
|
||||
LCPDEBUG((LOG_WARNING, "lcp_reqci: Reject AUTHTYPE PAP bad len\n"));
|
||||
LCPDEBUG(LOG_WARNING, ("lcp_reqci: Reject AUTHTYPE PAP bad len\n"));
|
||||
orc = CONFREJ;
|
||||
break;
|
||||
}
|
||||
if (!ao->neg_upap) { /* we don't want to do PAP */
|
||||
LCPDEBUG((LOG_WARNING, "lcp_reqci: Nak AUTHTYPE PAP not allowed\n"));
|
||||
LCPDEBUG(LOG_WARNING, ("lcp_reqci: Nak AUTHTYPE PAP not allowed\n"));
|
||||
orc = CONFNAK; /* NAK it and suggest CHAP */
|
||||
PUTCHAR(CI_AUTHTYPE, nakp);
|
||||
PUTCHAR(CILEN_CHAP, nakp);
|
||||
|
@ -1364,16 +1394,16 @@ lcp_reqci(fsm *f,
|
|||
}
|
||||
if (cishort == PPP_CHAP) {
|
||||
if (ho->neg_upap) { /* we've already accepted PAP */
|
||||
LCPDEBUG((LOG_WARNING, "lcp_reqci: Reject AUTHTYPE CHAP accepted PAP\n"));
|
||||
LCPDEBUG(LOG_WARNING, ("lcp_reqci: Reject AUTHTYPE CHAP accepted PAP\n"));
|
||||
orc = CONFREJ;
|
||||
break;
|
||||
} else if (cilen != CILEN_CHAP) {
|
||||
LCPDEBUG((LOG_WARNING, "lcp_reqci: Reject AUTHTYPE CHAP bad len\n"));
|
||||
LCPDEBUG(LOG_WARNING, ("lcp_reqci: Reject AUTHTYPE CHAP bad len\n"));
|
||||
orc = CONFREJ;
|
||||
break;
|
||||
}
|
||||
if (!ao->neg_chap) { /* we don't want to do CHAP */
|
||||
LCPDEBUG((LOG_WARNING, "lcp_reqci: Nak AUTHTYPE CHAP not allowed\n"));
|
||||
LCPDEBUG(LOG_WARNING, ("lcp_reqci: Nak AUTHTYPE CHAP not allowed\n"));
|
||||
orc = CONFNAK; /* NAK it and suggest PAP */
|
||||
PUTCHAR(CI_AUTHTYPE, nakp);
|
||||
PUTCHAR(CILEN_SHORT, nakp);
|
||||
|
@ -1382,11 +1412,11 @@ lcp_reqci(fsm *f,
|
|||
}
|
||||
GETCHAR(cichar, p); /* get digest type*/
|
||||
if (cichar != CHAP_DIGEST_MD5
|
||||
#ifdef CHAPMS
|
||||
#if MSCHAP_SUPPORT
|
||||
&& cichar != CHAP_MICROSOFT
|
||||
#endif
|
||||
) {
|
||||
LCPDEBUG((LOG_WARNING, "lcp_reqci: Nak AUTHTYPE CHAP digest=%d\n", cichar));
|
||||
LCPDEBUG(LOG_WARNING, ("lcp_reqci: Nak AUTHTYPE CHAP digest=%d\n", (int)cichar));
|
||||
orc = CONFNAK;
|
||||
PUTCHAR(CI_AUTHTYPE, nakp);
|
||||
PUTCHAR(CILEN_CHAP, nakp);
|
||||
|
@ -1395,7 +1425,7 @@ lcp_reqci(fsm *f,
|
|||
break;
|
||||
}
|
||||
#if TRACELCP > 0
|
||||
snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CHAP %X,%d", cishort, cichar);
|
||||
snprintf(&traceBuf[traceNdx], sizeof(traceBuf), " CHAP %X,%d", cishort, (int)cichar);
|
||||
traceNdx = strlen(traceBuf);
|
||||
#endif
|
||||
ho->chap_mdtype = cichar; /* save md type */
|
||||
|
@ -1411,12 +1441,12 @@ lcp_reqci(fsm *f,
|
|||
orc = CONFNAK;
|
||||
PUTCHAR(CI_AUTHTYPE, nakp);
|
||||
if (ao->neg_chap) {
|
||||
LCPDEBUG((LOG_WARNING, "lcp_reqci: Nak AUTHTYPE %d req CHAP\n", cishort));
|
||||
LCPDEBUG(LOG_WARNING, ("lcp_reqci: Nak AUTHTYPE %d req CHAP\n", cishort));
|
||||
PUTCHAR(CILEN_CHAP, nakp);
|
||||
PUTSHORT(PPP_CHAP, nakp);
|
||||
PUTCHAR(ao->chap_mdtype, nakp);
|
||||
} else {
|
||||
LCPDEBUG((LOG_WARNING, "lcp_reqci: Nak AUTHTYPE %d req PAP\n", cishort));
|
||||
LCPDEBUG(LOG_WARNING, ("lcp_reqci: Nak AUTHTYPE %d req PAP\n", cishort));
|
||||
PUTCHAR(CILEN_SHORT, nakp);
|
||||
PUTSHORT(PPP_PAP, nakp);
|
||||
}
|
||||
|
@ -1541,7 +1571,7 @@ lcp_reqci(fsm *f,
|
|||
endswitch:
|
||||
#if TRACELCP
|
||||
if (traceNdx >= 80 - 32) {
|
||||
LCPDEBUG((LOG_INFO, "lcp_reqci: rcvd%s\n", traceBuf));
|
||||
LCPDEBUG(LOG_INFO, ("lcp_reqci: rcvd%s\n", traceBuf));
|
||||
traceNdx = 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -1595,10 +1625,10 @@ lcp_reqci(fsm *f,
|
|||
|
||||
#if TRACELCP > 0
|
||||
if (traceNdx > 0) {
|
||||
LCPDEBUG((LOG_INFO, "lcp_reqci: %s\n", traceBuf));
|
||||
LCPDEBUG(LOG_INFO, ("lcp_reqci: %s\n", traceBuf));
|
||||
}
|
||||
#endif
|
||||
LCPDEBUG((LOG_INFO, "lcp_reqci: returning CONF%s.\n", CODENAME(rc)));
|
||||
LCPDEBUG(LOG_INFO, ("lcp_reqci: returning CONF%s.\n", CODENAME(rc)));
|
||||
return (rc); /* Return final code */
|
||||
}
|
||||
|
||||
|
@ -1645,7 +1675,7 @@ lcp_up(fsm *f)
|
|||
|
||||
lcp_echo_lowerup(f->unit); /* Enable echo messages */
|
||||
|
||||
link_established(f->unit);
|
||||
link_established(f->unit); /* The link is up; authenticate now */
|
||||
}
|
||||
|
||||
|
||||
|
@ -1677,7 +1707,7 @@ lcp_down(fsm *f)
|
|||
static void
|
||||
lcp_starting(fsm *f)
|
||||
{
|
||||
link_required(f->unit);
|
||||
link_required(f->unit); /* lwip: currently does nothing */
|
||||
}
|
||||
|
||||
|
||||
|
@ -1687,11 +1717,11 @@ lcp_starting(fsm *f)
|
|||
static void
|
||||
lcp_finished(fsm *f)
|
||||
{
|
||||
link_terminated(f->unit);
|
||||
link_terminated(f->unit); /* we are finished with the link */
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
#if PPP_ADDITIONAL_CALLBACKS
|
||||
/*
|
||||
* print_string - print a readable representation of a string using
|
||||
* printer.
|
||||
|
@ -1898,7 +1928,7 @@ lcp_printpkt( u_char *p, int plen, void (*printer) (void *, char *, ...), void *
|
|||
|
||||
return (int)(p - pstart);
|
||||
}
|
||||
#endif
|
||||
#endif /* PPP_ADDITIONAL_CALLBACKS */
|
||||
|
||||
/*
|
||||
* Time to shut down the link because there is nothing out there.
|
||||
|
@ -1907,8 +1937,8 @@ static void
|
|||
LcpLinkFailure (fsm *f)
|
||||
{
|
||||
if (f->state == LS_OPENED) {
|
||||
LCPDEBUG((LOG_INFO, "No response to %d echo-requests\n", lcp_echos_pending));
|
||||
LCPDEBUG((LOG_NOTICE, "Serial link appears to be disconnected.\n"));
|
||||
LCPDEBUG(LOG_INFO, ("No response to %d echo-requests\n", lcp_echos_pending));
|
||||
LCPDEBUG(LOG_NOTICE, ("Serial link appears to be disconnected.\n"));
|
||||
lcp_close(f->unit, "Peer not responding");
|
||||
}
|
||||
}
|
||||
|
@ -1954,15 +1984,15 @@ lcp_received_echo_reply (fsm *f, int id, u_char *inp, int len)
|
|||
|
||||
/* Check the magic number - don't count replies from ourselves. */
|
||||
if (len < 4) {
|
||||
LCPDEBUG((LOG_WARNING, "lcp: received short Echo-Reply, length %d\n", len));
|
||||
LCPDEBUG(LOG_WARNING, ("lcp: received short Echo-Reply, length %d\n", len));
|
||||
return;
|
||||
}
|
||||
GETLONG(magic, inp);
|
||||
if (lcp_gotoptions[f->unit].neg_magicnumber && magic == lcp_gotoptions[f->unit].magicnumber) {
|
||||
LCPDEBUG((LOG_WARNING, "appear to have received our own echo-reply!\n"));
|
||||
LCPDEBUG(LOG_WARNING, ("appear to have received our own echo-reply!\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Reset the number of outstanding echo frames */
|
||||
lcp_echos_pending = 0;
|
||||
}
|
||||
|
@ -1980,7 +2010,7 @@ LcpSendEchoRequest (fsm *f)
|
|||
* Detect the failure of the peer at this point.
|
||||
*/
|
||||
if (lcp_echo_fails != 0) {
|
||||
if (lcp_echos_pending++ >= lcp_echo_fails) {
|
||||
if (lcp_echos_pending >= lcp_echo_fails) {
|
||||
LcpLinkFailure(f);
|
||||
lcp_echos_pending = 0;
|
||||
}
|
||||
|
@ -1994,6 +2024,7 @@ LcpSendEchoRequest (fsm *f)
|
|||
pktp = pkt;
|
||||
PUTLONG(lcp_magic, pktp);
|
||||
fsm_sdata(f, ECHOREQ, (u_char)(lcp_echo_number++ & 0xFF), pkt, (int)(pktp - pkt));
|
||||
++lcp_echos_pending;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -48,15 +48,11 @@
|
|||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: lcp.h,v 1.3 2007/12/19 20:47:23 fbernon Exp $
|
||||
* $Id: lcp.h,v 1.4 2010/01/18 20:49:43 goldsimon Exp $
|
||||
*/
|
||||
|
||||
#ifndef LCP_H
|
||||
#define LCP_H
|
||||
|
||||
/*************************
|
||||
*** PUBLIC DEFINITIONS ***
|
||||
*************************/
|
||||
/*
|
||||
* Options.
|
||||
*/
|
||||
|
@ -73,7 +69,7 @@
|
|||
#define CI_EPDISC 19 /* endpoint discriminator */
|
||||
|
||||
/*
|
||||
* LCP-specific packet types.
|
||||
* LCP-specific packet types (code numbers).
|
||||
*/
|
||||
#define PROTREJ 8 /* Protocol Reject */
|
||||
#define ECHOREQ 9 /* Echo Request */
|
||||
|
@ -81,11 +77,6 @@
|
|||
#define DISCREQ 11 /* Discard Request */
|
||||
#define CBCP_OPT 6 /* Use callback control protocol */
|
||||
|
||||
|
||||
/************************
|
||||
*** PUBLIC DATA TYPES ***
|
||||
************************/
|
||||
|
||||
/*
|
||||
* The state of options is described by an lcp_options structure.
|
||||
*/
|
||||
|
@ -135,9 +126,6 @@ typedef enum {
|
|||
} LinkPhase;
|
||||
|
||||
|
||||
/*****************************
|
||||
*** PUBLIC DATA STRUCTURES ***
|
||||
*****************************/
|
||||
|
||||
extern LinkPhase lcp_phase[NUM_PPP]; /* Phase of link session (RFC 1661) */
|
||||
extern lcp_options lcp_wantoptions[];
|
||||
|
@ -147,10 +135,6 @@ extern lcp_options lcp_hisoptions[];
|
|||
extern ext_accm xmit_accm[];
|
||||
|
||||
|
||||
/***********************
|
||||
*** PUBLIC FUNCTIONS ***
|
||||
***********************/
|
||||
|
||||
void lcp_init (int);
|
||||
void lcp_open (int);
|
||||
void lcp_close (int, char *);
|
||||
|
|
|
@ -57,9 +57,7 @@
|
|||
#include "randm.h"
|
||||
#include "magic.h"
|
||||
|
||||
/***********************************/
|
||||
/*** PUBLIC FUNCTION DEFINITIONS ***/
|
||||
/***********************************/
|
||||
|
||||
/*
|
||||
* magicInit - Initialize the magic number generator.
|
||||
*
|
||||
|
|
|
@ -48,16 +48,12 @@
|
|||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: magic.h,v 1.2 2007/12/02 22:35:55 fbernon Exp $
|
||||
* $Id: magic.h,v 1.3 2010/01/18 20:49:43 goldsimon Exp $
|
||||
*/
|
||||
|
||||
#ifndef MAGIC_H
|
||||
#define MAGIC_H
|
||||
|
||||
/*****************************************************************************
|
||||
************************** PUBLIC FUNCTIONS **********************************
|
||||
*****************************************************************************/
|
||||
|
||||
/* Initialize the magic number generator */
|
||||
void magicInit(void);
|
||||
|
||||
|
|
|
@ -138,8 +138,8 @@ MD5Update(MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen)
|
|||
unsigned int i, ii;
|
||||
|
||||
#if 0
|
||||
ppp_trace(LOG_INFO, "MD5Update: %u:%.*H\n", inLen, MIN(inLen, 20) * 2, inBuf);
|
||||
ppp_trace(LOG_INFO, "MD5Update: %u:%s\n", inLen, inBuf);
|
||||
PPPDEBUG(LOG_INFO, ("MD5Update: %u:%.*H\n", inLen, LWIP_MIN(inLen, 20) * 2, inBuf));
|
||||
PPPDEBUG(LOG_INFO, ("MD5Update: %u:%s\n", inLen, inBuf));
|
||||
#endif
|
||||
|
||||
/* compute number of bytes mod 64 */
|
||||
|
|
|
@ -63,9 +63,27 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
/***********************************/
|
||||
/*** LOCAL FUNCTION DECLARATIONS ***/
|
||||
/***********************************/
|
||||
#if 0 /* UNUSED */
|
||||
static bool hide_password = 1;
|
||||
|
||||
/*
|
||||
* Command-line options.
|
||||
*/
|
||||
static option_t pap_option_list[] = {
|
||||
{ "hide-password", o_bool, &hide_password,
|
||||
"Don't output passwords to log", 1 },
|
||||
{ "show-password", o_bool, &hide_password,
|
||||
"Show password string in debug log messages", 0 },
|
||||
{ "pap-restart", o_int, &upap[0].us_timeouttime,
|
||||
"Set retransmit timeout for PAP" },
|
||||
{ "pap-max-authreq", o_int, &upap[0].us_maxtransmits,
|
||||
"Set max number of transmissions for auth-reqs" },
|
||||
{ "pap-timeout", o_int, &upap[0].us_reqtimeout,
|
||||
"Set time limit for peer PAP authentication" },
|
||||
{ NULL }
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Protocol entry points.
|
||||
*/
|
||||
|
@ -74,19 +92,10 @@ static void upap_lowerup (int);
|
|||
static void upap_lowerdown (int);
|
||||
static void upap_input (int, u_char *, int);
|
||||
static void upap_protrej (int);
|
||||
#if PPP_ADDITIONAL_CALLBACKS
|
||||
static int upap_printpkt (u_char *, int, void (*)(void *, char *, ...), void *);
|
||||
#endif /* PPP_ADDITIONAL_CALLBACKS */
|
||||
|
||||
static void upap_timeout (void *);
|
||||
static void upap_reqtimeout(void *);
|
||||
static void upap_rauthreq (upap_state *, u_char *, int, int);
|
||||
static void upap_rauthack (upap_state *, u_char *, int, int);
|
||||
static void upap_rauthnak (upap_state *, u_char *, int, int);
|
||||
static void upap_sauthreq (upap_state *);
|
||||
static void upap_sresp (upap_state *, u_char, u_char, char *, int);
|
||||
|
||||
|
||||
/******************************/
|
||||
/*** PUBLIC DATA STRUCTURES ***/
|
||||
/******************************/
|
||||
struct protent pap_protent = {
|
||||
PPP_PAP,
|
||||
upap_init,
|
||||
|
@ -96,41 +105,51 @@ struct protent pap_protent = {
|
|||
upap_lowerdown,
|
||||
NULL,
|
||||
NULL,
|
||||
#if 0
|
||||
#if PPP_ADDITIONAL_CALLBACKS
|
||||
upap_printpkt,
|
||||
NULL,
|
||||
#endif
|
||||
#endif /* PPP_ADDITIONAL_CALLBACKS */
|
||||
1,
|
||||
"PAP",
|
||||
#if 0
|
||||
#if PPP_ADDITIONAL_CALLBACKS
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
#endif
|
||||
#endif /* PPP_ADDITIONAL_CALLBACKS */
|
||||
};
|
||||
|
||||
upap_state upap[NUM_PPP]; /* UPAP state; one for each unit */
|
||||
|
||||
static void upap_timeout (void *);
|
||||
static void upap_reqtimeout(void *);
|
||||
static void upap_rauthreq (upap_state *, u_char *, u_char, int);
|
||||
static void upap_rauthack (upap_state *, u_char *, int, int);
|
||||
static void upap_rauthnak (upap_state *, u_char *, int, int);
|
||||
static void upap_sauthreq (upap_state *);
|
||||
static void upap_sresp (upap_state *, u_char, u_char, char *, int);
|
||||
|
||||
|
||||
/***********************************/
|
||||
/*** PUBLIC FUNCTION DEFINITIONS ***/
|
||||
/***********************************/
|
||||
/*
|
||||
* Set the default login name and password for the pap sessions
|
||||
* upap_init - Initialize a UPAP unit.
|
||||
*/
|
||||
void
|
||||
upap_setloginpasswd(int unit, const char *luser, const char *lpassword)
|
||||
static void
|
||||
upap_init(int unit)
|
||||
{
|
||||
upap_state *u = &upap[unit];
|
||||
|
||||
/* Save the username and password we're given */
|
||||
u->us_user = luser;
|
||||
u->us_userlen = strlen(luser);
|
||||
u->us_passwd = lpassword;
|
||||
u->us_passwdlen = strlen(lpassword);
|
||||
}
|
||||
|
||||
UPAPDEBUG(LOG_INFO, ("upap_init: %d\n", unit));
|
||||
u->us_unit = unit;
|
||||
u->us_user = NULL;
|
||||
u->us_userlen = 0;
|
||||
u->us_passwd = NULL;
|
||||
u->us_passwdlen = 0;
|
||||
u->us_clientstate = UPAPCS_INITIAL;
|
||||
u->us_serverstate = UPAPSS_INITIAL;
|
||||
u->us_id = 0;
|
||||
u->us_timeouttime = UPAP_DEFTIMEOUT;
|
||||
u->us_maxtransmits = 10;
|
||||
u->us_reqtimeout = UPAP_DEFREQTIME;
|
||||
}
|
||||
|
||||
/*
|
||||
* upap_authwithpeer - Authenticate us with our peer (start client).
|
||||
|
@ -142,10 +161,14 @@ upap_authwithpeer(int unit, char *user, char *password)
|
|||
{
|
||||
upap_state *u = &upap[unit];
|
||||
|
||||
UPAPDEBUG((LOG_INFO, "upap_authwithpeer: %d user=%s password=%s s=%d\n",
|
||||
UPAPDEBUG(LOG_INFO, ("upap_authwithpeer: %d user=%s password=%s s=%d\n",
|
||||
unit, user, password, u->us_clientstate));
|
||||
|
||||
upap_setloginpasswd(unit, user, password);
|
||||
/* Save the username and password we're given */
|
||||
u->us_user = user;
|
||||
u->us_userlen = (int)strlen(user);
|
||||
u->us_passwd = password;
|
||||
u->us_passwdlen = (int)strlen(password);
|
||||
|
||||
u->us_transmits = 0;
|
||||
|
||||
|
@ -183,33 +206,6 @@ upap_authpeer(int unit)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**********************************/
|
||||
/*** LOCAL FUNCTION DEFINITIONS ***/
|
||||
/**********************************/
|
||||
/*
|
||||
* upap_init - Initialize a UPAP unit.
|
||||
*/
|
||||
static void
|
||||
upap_init(int unit)
|
||||
{
|
||||
upap_state *u = &upap[unit];
|
||||
|
||||
UPAPDEBUG((LOG_INFO, "upap_init: %d\n", unit));
|
||||
u->us_unit = unit;
|
||||
u->us_user = NULL;
|
||||
u->us_userlen = 0;
|
||||
u->us_passwd = NULL;
|
||||
u->us_passwdlen = 0;
|
||||
u->us_clientstate = UPAPCS_INITIAL;
|
||||
u->us_serverstate = UPAPSS_INITIAL;
|
||||
u->us_id = 0;
|
||||
u->us_timeouttime = UPAP_DEFTIMEOUT;
|
||||
u->us_maxtransmits = 10;
|
||||
u->us_reqtimeout = UPAP_DEFREQTIME;
|
||||
}
|
||||
|
||||
/*
|
||||
* upap_timeout - Retransmission timer for sending auth-reqs expired.
|
||||
*/
|
||||
|
@ -218,22 +214,23 @@ upap_timeout(void *arg)
|
|||
{
|
||||
upap_state *u = (upap_state *) arg;
|
||||
|
||||
UPAPDEBUG((LOG_INFO, "upap_timeout: %d timeout %d expired s=%d\n",
|
||||
UPAPDEBUG(LOG_INFO, ("upap_timeout: %d timeout %d expired s=%d\n",
|
||||
u->us_unit, u->us_timeouttime, u->us_clientstate));
|
||||
|
||||
if (u->us_clientstate != UPAPCS_AUTHREQ) {
|
||||
UPAPDEBUG(LOG_INFO, ("upap_timeout: not in AUTHREQ state!\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (u->us_transmits >= u->us_maxtransmits) {
|
||||
/* give up in disgust */
|
||||
UPAPDEBUG((LOG_ERR, "No response to PAP authenticate-requests\n"));
|
||||
UPAPDEBUG(LOG_ERR, ("No response to PAP authenticate-requests\n"));
|
||||
u->us_clientstate = UPAPCS_BADAUTH;
|
||||
auth_withpeer_fail(u->us_unit, PPP_PAP);
|
||||
return;
|
||||
}
|
||||
|
||||
upap_sauthreq(u); /* Send Authenticate-Request */
|
||||
upap_sauthreq(u); /* Send Authenticate-Request and set upap timeout*/
|
||||
}
|
||||
|
||||
|
||||
|
@ -264,12 +261,13 @@ upap_lowerup(int unit)
|
|||
{
|
||||
upap_state *u = &upap[unit];
|
||||
|
||||
UPAPDEBUG((LOG_INFO, "upap_lowerup: %d s=%d\n", unit, u->us_clientstate));
|
||||
UPAPDEBUG(LOG_INFO, ("upap_lowerup: init %d clientstate s=%d\n", unit, u->us_clientstate));
|
||||
|
||||
if (u->us_clientstate == UPAPCS_INITIAL) {
|
||||
u->us_clientstate = UPAPCS_CLOSED;
|
||||
} else if (u->us_clientstate == UPAPCS_PENDING) {
|
||||
upap_sauthreq(u); /* send an auth-request */
|
||||
/* now client state is UPAPCS__AUTHREQ */
|
||||
}
|
||||
|
||||
if (u->us_serverstate == UPAPSS_INITIAL) {
|
||||
|
@ -293,7 +291,7 @@ upap_lowerdown(int unit)
|
|||
{
|
||||
upap_state *u = &upap[unit];
|
||||
|
||||
UPAPDEBUG((LOG_INFO, "upap_lowerdown: %d s=%d\n", unit, u->us_clientstate));
|
||||
UPAPDEBUG(LOG_INFO, ("upap_lowerdown: %d s=%d\n", unit, u->us_clientstate));
|
||||
|
||||
if (u->us_clientstate == UPAPCS_AUTHREQ) { /* Timeout pending? */
|
||||
UNTIMEOUT(upap_timeout, u); /* Cancel timeout */
|
||||
|
@ -318,11 +316,11 @@ upap_protrej(int unit)
|
|||
upap_state *u = &upap[unit];
|
||||
|
||||
if (u->us_clientstate == UPAPCS_AUTHREQ) {
|
||||
UPAPDEBUG((LOG_ERR, "PAP authentication failed due to protocol-reject\n"));
|
||||
UPAPDEBUG(LOG_ERR, ("PAP authentication failed due to protocol-reject\n"));
|
||||
auth_withpeer_fail(unit, PPP_PAP);
|
||||
}
|
||||
if (u->us_serverstate == UPAPSS_LISTEN) {
|
||||
UPAPDEBUG((LOG_ERR, "PAP authentication of peer failed (protocol-reject)\n"));
|
||||
UPAPDEBUG(LOG_ERR, ("PAP authentication of peer failed (protocol-reject)\n"));
|
||||
auth_peer_fail(unit, PPP_PAP);
|
||||
}
|
||||
upap_lowerdown(unit);
|
||||
|
@ -345,19 +343,19 @@ upap_input(int unit, u_char *inpacket, int l)
|
|||
* If packet too short, drop it.
|
||||
*/
|
||||
inp = inpacket;
|
||||
if (l < UPAP_HEADERLEN) {
|
||||
UPAPDEBUG((LOG_INFO, "pap_input: rcvd short header.\n"));
|
||||
if (l < (int)UPAP_HEADERLEN) {
|
||||
UPAPDEBUG(LOG_INFO, ("pap_input: rcvd short header.\n"));
|
||||
return;
|
||||
}
|
||||
GETCHAR(code, inp);
|
||||
GETCHAR(id, inp);
|
||||
GETSHORT(len, inp);
|
||||
if (len < UPAP_HEADERLEN) {
|
||||
UPAPDEBUG((LOG_INFO, "pap_input: rcvd illegal length.\n"));
|
||||
if (len < (int)UPAP_HEADERLEN) {
|
||||
UPAPDEBUG(LOG_INFO, ("pap_input: rcvd illegal length.\n"));
|
||||
return;
|
||||
}
|
||||
if (len > l) {
|
||||
UPAPDEBUG((LOG_INFO, "pap_input: rcvd short packet.\n"));
|
||||
UPAPDEBUG(LOG_INFO, ("pap_input: rcvd short packet.\n"));
|
||||
return;
|
||||
}
|
||||
len -= UPAP_HEADERLEN;
|
||||
|
@ -379,6 +377,7 @@ upap_input(int unit, u_char *inpacket, int l)
|
|||
break;
|
||||
|
||||
default: /* XXX Need code reject */
|
||||
UPAPDEBUG(LOG_INFO, ("pap_input: UNHANDLED default: code: %d, id: %d, len: %d.\n", code, id, len));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -388,15 +387,15 @@ upap_input(int unit, u_char *inpacket, int l)
|
|||
* upap_rauth - Receive Authenticate.
|
||||
*/
|
||||
static void
|
||||
upap_rauthreq(upap_state *u, u_char *inp, int id, int len)
|
||||
upap_rauthreq(upap_state *u, u_char *inp, u_char id, int len)
|
||||
{
|
||||
u_char ruserlen, rpasswdlen;
|
||||
char *ruser, *rpasswd;
|
||||
int retcode;
|
||||
u_char retcode;
|
||||
char *msg;
|
||||
int msglen;
|
||||
|
||||
UPAPDEBUG((LOG_INFO, "pap_rauth: Rcvd id %d.\n", id));
|
||||
UPAPDEBUG(LOG_INFO, ("pap_rauth: Rcvd id %d.\n", id));
|
||||
|
||||
if (u->us_serverstate < UPAPSS_LISTEN) {
|
||||
return;
|
||||
|
@ -418,21 +417,21 @@ upap_rauthreq(upap_state *u, u_char *inp, int id, int len)
|
|||
/*
|
||||
* Parse user/passwd.
|
||||
*/
|
||||
if (len < sizeof (u_char)) {
|
||||
UPAPDEBUG((LOG_INFO, "pap_rauth: rcvd short packet.\n"));
|
||||
if (len < (int)sizeof (u_char)) {
|
||||
UPAPDEBUG(LOG_INFO, ("pap_rauth: rcvd short packet.\n"));
|
||||
return;
|
||||
}
|
||||
GETCHAR(ruserlen, inp);
|
||||
len -= sizeof (u_char) + ruserlen + sizeof (u_char);
|
||||
if (len < 0) {
|
||||
UPAPDEBUG((LOG_INFO, "pap_rauth: rcvd short packet.\n"));
|
||||
UPAPDEBUG(LOG_INFO, ("pap_rauth: rcvd short packet.\n"));
|
||||
return;
|
||||
}
|
||||
ruser = (char *) inp;
|
||||
INCPTR(ruserlen, inp);
|
||||
GETCHAR(rpasswdlen, inp);
|
||||
if (len < rpasswdlen) {
|
||||
UPAPDEBUG((LOG_INFO, "pap_rauth: rcvd short packet.\n"));
|
||||
UPAPDEBUG(LOG_INFO, ("pap_rauth: rcvd short packet.\n"));
|
||||
return;
|
||||
}
|
||||
rpasswd = (char *) inp;
|
||||
|
@ -441,6 +440,7 @@ upap_rauthreq(upap_state *u, u_char *inp, int id, int len)
|
|||
* Check the username and password given.
|
||||
*/
|
||||
retcode = check_passwd(u->us_unit, ruser, ruserlen, rpasswd, rpasswdlen, &msg, &msglen);
|
||||
/* lwip: currently retcode is always UPAP_AUTHACK */
|
||||
BZERO(rpasswd, rpasswdlen);
|
||||
|
||||
upap_sresp(u, retcode, id, msg, msglen);
|
||||
|
@ -470,28 +470,30 @@ upap_rauthack(upap_state *u, u_char *inp, int id, int len)
|
|||
|
||||
LWIP_UNUSED_ARG(id);
|
||||
|
||||
UPAPDEBUG((LOG_INFO, "pap_rauthack: Rcvd id %d s=%d\n", id, u->us_clientstate));
|
||||
UPAPDEBUG(LOG_INFO, ("pap_rauthack: Rcvd id %d s=%d\n", id, u->us_clientstate));
|
||||
|
||||
if (u->us_clientstate != UPAPCS_AUTHREQ) { /* XXX */
|
||||
UPAPDEBUG(LOG_INFO, ("pap_rauthack: us_clientstate != UPAPCS_AUTHREQ\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse message.
|
||||
*/
|
||||
if (len < sizeof (u_char)) {
|
||||
UPAPDEBUG((LOG_INFO, "pap_rauthack: rcvd short packet.\n"));
|
||||
return;
|
||||
if (len < (int)sizeof (u_char)) {
|
||||
UPAPDEBUG(LOG_INFO, ("pap_rauthack: ignoring missing msg-length.\n"));
|
||||
} else {
|
||||
GETCHAR(msglen, inp);
|
||||
if (msglen > 0) {
|
||||
len -= sizeof (u_char);
|
||||
if (len < msglen) {
|
||||
UPAPDEBUG(LOG_INFO, ("pap_rauthack: rcvd short packet.\n"));
|
||||
return;
|
||||
}
|
||||
msg = (char *) inp;
|
||||
PRINTMSG(msg, msglen);
|
||||
}
|
||||
}
|
||||
GETCHAR(msglen, inp);
|
||||
len -= sizeof (u_char);
|
||||
if (len < msglen) {
|
||||
UPAPDEBUG((LOG_INFO, "pap_rauthack: rcvd short packet.\n"));
|
||||
return;
|
||||
}
|
||||
msg = (char *) inp;
|
||||
PRINTMSG(msg, msglen);
|
||||
|
||||
UNTIMEOUT(upap_timeout, u); /* Cancel timeout */
|
||||
u->us_clientstate = UPAPCS_OPEN;
|
||||
|
||||
|
@ -500,7 +502,7 @@ upap_rauthack(upap_state *u, u_char *inp, int id, int len)
|
|||
|
||||
|
||||
/*
|
||||
* upap_rauthnak - Receive Authenticate-Nakk.
|
||||
* upap_rauthnak - Receive Authenticate-Nak.
|
||||
*/
|
||||
static void
|
||||
upap_rauthnak(upap_state *u, u_char *inp, int id, int len)
|
||||
|
@ -510,7 +512,7 @@ upap_rauthnak(upap_state *u, u_char *inp, int id, int len)
|
|||
|
||||
LWIP_UNUSED_ARG(id);
|
||||
|
||||
UPAPDEBUG((LOG_INFO, "pap_rauthnak: Rcvd id %d s=%d\n", id, u->us_clientstate));
|
||||
UPAPDEBUG(LOG_INFO, ("pap_rauthnak: Rcvd id %d s=%d\n", id, u->us_clientstate));
|
||||
|
||||
if (u->us_clientstate != UPAPCS_AUTHREQ) { /* XXX */
|
||||
return;
|
||||
|
@ -520,13 +522,13 @@ upap_rauthnak(upap_state *u, u_char *inp, int id, int len)
|
|||
* Parse message.
|
||||
*/
|
||||
if (len < sizeof (u_char)) {
|
||||
UPAPDEBUG((LOG_INFO, "pap_rauthnak: rcvd short packet.\n"));
|
||||
UPAPDEBUG(LOG_INFO, ("pap_rauthnak: ignoring missing msg-length.\n"));
|
||||
} else {
|
||||
GETCHAR(msglen, inp);
|
||||
if(msglen > 0) {
|
||||
len -= sizeof (u_char);
|
||||
if (len < msglen) {
|
||||
UPAPDEBUG((LOG_INFO, "pap_rauthnak: rcvd short packet.\n"));
|
||||
UPAPDEBUG(LOG_INFO, ("pap_rauthnak: rcvd short packet.\n"));
|
||||
return;
|
||||
}
|
||||
msg = (char *) inp;
|
||||
|
@ -536,7 +538,7 @@ upap_rauthnak(upap_state *u, u_char *inp, int id, int len)
|
|||
|
||||
u->us_clientstate = UPAPCS_BADAUTH;
|
||||
|
||||
UPAPDEBUG((LOG_ERR, "PAP authentication failed\n"));
|
||||
UPAPDEBUG(LOG_ERR, ("PAP authentication failed\n"));
|
||||
auth_withpeer_fail(u->us_unit, PPP_PAP);
|
||||
}
|
||||
|
||||
|
@ -567,7 +569,7 @@ upap_sauthreq(upap_state *u)
|
|||
|
||||
pppWrite(u->us_unit, outpacket_buf[u->us_unit], outlen + PPP_HDRLEN);
|
||||
|
||||
UPAPDEBUG((LOG_INFO, "pap_sauth: Sent id %d\n", u->us_id));
|
||||
UPAPDEBUG(LOG_INFO, ("pap_sauth: Sent id %d\n", u->us_id));
|
||||
|
||||
TIMEOUT(upap_timeout, u, u->us_timeouttime);
|
||||
++u->us_transmits;
|
||||
|
@ -595,10 +597,14 @@ upap_sresp(upap_state *u, u_char code, u_char id, char *msg, int msglen)
|
|||
BCOPY(msg, outp, msglen);
|
||||
pppWrite(u->us_unit, outpacket_buf[u->us_unit], outlen + PPP_HDRLEN);
|
||||
|
||||
UPAPDEBUG((LOG_INFO, "pap_sresp: Sent code %d, id %d s=%d\n", code, id, u->us_clientstate));
|
||||
UPAPDEBUG(LOG_INFO, ("pap_sresp: Sent code %d, id %d s=%d\n", code, id, u->us_clientstate));
|
||||
}
|
||||
|
||||
#if 0
|
||||
#if PPP_ADDITIONAL_CALLBACKS
|
||||
static char *upap_codenames[] = {
|
||||
"AuthReq", "AuthAck", "AuthNak"
|
||||
};
|
||||
|
||||
/*
|
||||
* upap_printpkt - print the contents of a PAP packet.
|
||||
*/
|
||||
|
@ -615,7 +621,7 @@ static int upap_printpkt(
|
|||
LWIP_UNUSED_ARG(arg);
|
||||
return 0;
|
||||
}
|
||||
#endif /* 0 */
|
||||
#endif /* PPP_ADDITIONAL_CALLBACKS */
|
||||
|
||||
#endif /* PAP_SUPPORT */
|
||||
|
||||
|
|
|
@ -54,9 +54,6 @@
|
|||
|
||||
#if PAP_SUPPORT /* don't build if not configured for use in lwipopts.h */
|
||||
|
||||
/*************************
|
||||
*** PUBLIC DEFINITIONS ***
|
||||
*************************/
|
||||
/*
|
||||
* Packet header = Code, id, length.
|
||||
*/
|
||||
|
@ -70,6 +67,24 @@
|
|||
#define UPAP_AUTHACK 2 /* Authenticate-Ack */
|
||||
#define UPAP_AUTHNAK 3 /* Authenticate-Nak */
|
||||
|
||||
/*
|
||||
* Each interface is described by upap structure.
|
||||
*/
|
||||
typedef struct upap_state {
|
||||
int us_unit; /* Interface unit number */
|
||||
const char *us_user; /* User */
|
||||
int us_userlen; /* User length */
|
||||
const char *us_passwd; /* Password */
|
||||
int us_passwdlen; /* Password length */
|
||||
int us_clientstate; /* Client state */
|
||||
int us_serverstate; /* Server state */
|
||||
u_char us_id; /* Current id */
|
||||
int us_timeouttime; /* Timeout (seconds) for auth-req retrans. */
|
||||
int us_transmits; /* Number of auth-reqs sent */
|
||||
int us_maxtransmits; /* Maximum number of auth-reqs to send */
|
||||
int us_reqtimeout; /* Time to wait for auth-req from peer */
|
||||
} upap_state;
|
||||
|
||||
/*
|
||||
* Client states.
|
||||
*/
|
||||
|
@ -91,36 +106,8 @@
|
|||
#define UPAPSS_BADAUTH 5 /* We've sent a Nak */
|
||||
|
||||
|
||||
/************************
|
||||
*** PUBLIC DATA TYPES ***
|
||||
************************/
|
||||
|
||||
/*
|
||||
* Each interface is described by upap structure.
|
||||
*/
|
||||
typedef struct upap_state {
|
||||
int us_unit; /* Interface unit number */
|
||||
const char *us_user; /* User */
|
||||
int us_userlen; /* User length */
|
||||
const char *us_passwd; /* Password */
|
||||
int us_passwdlen; /* Password length */
|
||||
int us_clientstate; /* Client state */
|
||||
int us_serverstate; /* Server state */
|
||||
u_char us_id; /* Current id */
|
||||
int us_timeouttime; /* Timeout (seconds) for auth-req retrans. */
|
||||
int us_transmits; /* Number of auth-reqs sent */
|
||||
int us_maxtransmits; /* Maximum number of auth-reqs to send */
|
||||
int us_reqtimeout; /* Time to wait for auth-req from peer */
|
||||
} upap_state;
|
||||
|
||||
|
||||
/***********************
|
||||
*** PUBLIC FUNCTIONS ***
|
||||
***********************/
|
||||
|
||||
extern upap_state upap[];
|
||||
|
||||
void upap_setloginpasswd(int unit, const char *luser, const char *lpassword);
|
||||
void upap_authwithpeer (int, char *, char *);
|
||||
void upap_authpeer (int);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -40,12 +40,23 @@
|
|||
|
||||
#include "lwip/def.h"
|
||||
#include "lwip/sio.h"
|
||||
#include "lwip/api.h"
|
||||
#include "lwip/sockets.h"
|
||||
#include "lwip/stats.h"
|
||||
#include "lwip/mem.h"
|
||||
#include "lwip/tcpip.h"
|
||||
#include "lwip/netif.h"
|
||||
#include "lwip/sys.h"
|
||||
#include "lwip/timers.h"
|
||||
|
||||
/** Some defines for code we skip compared to the original pppd.
|
||||
* These are just here to minimise the use of the ugly "#if 0". */
|
||||
#define PPP_ADDITIONAL_CALLBACKS 0
|
||||
|
||||
/** Some error checks to test for unsupported code */
|
||||
#if CBCP_SUPPORT
|
||||
#error "CBCP is not supported in lwIP PPP"
|
||||
#endif
|
||||
#if CCP_SUPPORT
|
||||
#error "CCP is not supported in lwIP PPP"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* pppd.h - PPP daemon global declarations.
|
||||
|
@ -93,7 +104,7 @@
|
|||
* OR MODIFICATIONS.
|
||||
*/
|
||||
|
||||
#define TIMEOUT(f, a, t) sys_untimeout((f), (a)), sys_timeout((t)*1000, (f), (a))
|
||||
#define TIMEOUT(f, a, t) do { sys_untimeout((f), (a)); sys_timeout((t)*1000, (f), (a)); } while(0)
|
||||
#define UNTIMEOUT(f, a) sys_untimeout((f), (a))
|
||||
|
||||
|
||||
|
@ -212,7 +223,7 @@ enum NPmode {
|
|||
#define BZERO(s, n) memset(s, 0, n)
|
||||
|
||||
#if PPP_DEBUG
|
||||
#define PRINTMSG(m, l) { m[l] = '\0'; ppp_trace(LOG_INFO, "Remote message: %s\n", m); }
|
||||
#define PRINTMSG(m, l) { m[l] = '\0'; LWIP_DEBUGF(LOG_INFO, ("Remote message: %s\n", m)); }
|
||||
#else /* PPP_DEBUG */
|
||||
#define PRINTMSG(m, l)
|
||||
#endif /* PPP_DEBUG */
|
||||
|
@ -276,24 +287,24 @@ struct protent {
|
|||
void (*open) (int unit);
|
||||
/* Close the protocol */
|
||||
void (*close) (int unit, char *reason);
|
||||
#if 0
|
||||
#if PPP_ADDITIONAL_CALLBACKS
|
||||
/* Print a packet in readable form */
|
||||
int (*printpkt) (u_char *pkt, int len,
|
||||
void (*printer) (void *, char *, ...),
|
||||
void *arg);
|
||||
/* Process a received data packet */
|
||||
void (*datainput) (int unit, u_char *pkt, int len);
|
||||
#endif
|
||||
int enabled_flag; /* 0 iff protocol is disabled */
|
||||
#endif /* PPP_ADDITIONAL_CALLBACKS */
|
||||
int enabled_flag; /* 0 if protocol is disabled */
|
||||
char *name; /* Text name of protocol */
|
||||
#if 0
|
||||
#if PPP_ADDITIONAL_CALLBACKS
|
||||
/* Check requested options, assign defaults */
|
||||
void (*check_options) (u_long);
|
||||
/* Configure interface for demand-dial */
|
||||
int (*demand_conf) (int unit);
|
||||
/* Say whether to bring up link for this pkt */
|
||||
int (*active_pkt) (u_char *pkt, int len);
|
||||
#endif
|
||||
#endif /* PPP_ADDITIONAL_CALLBACKS */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -325,7 +336,7 @@ struct ppp_settings {
|
|||
};
|
||||
|
||||
struct ppp_addrs {
|
||||
struct ip_addr our_ipaddr, his_ipaddr, netmask, dns1, dns2;
|
||||
ip_addr_t our_ipaddr, his_ipaddr, netmask, dns1, dns2;
|
||||
};
|
||||
|
||||
/*****************************
|
||||
|
@ -413,7 +424,7 @@ int pppIOCtl(int pd, int cmd, void *arg);
|
|||
/*
|
||||
* Return the Maximum Transmission Unit for the given PPP connection.
|
||||
*/
|
||||
u_int pppMTU(int pd);
|
||||
u_short pppMTU(int pd);
|
||||
|
||||
/*
|
||||
* Write n characters to a ppp link.
|
||||
|
@ -429,10 +440,10 @@ void pppLinkTerminated(int pd);
|
|||
|
||||
void pppLinkDown(int pd);
|
||||
|
||||
void pppMainWakeup(int pd);
|
||||
void pppos_input(int pd, u_char* data, int len);
|
||||
|
||||
/* Configure i/f transmit parameters */
|
||||
void ppp_send_config (int, int, u32_t, int, int);
|
||||
void ppp_send_config (int, u16_t, u32_t, int, int);
|
||||
/* Set extended transmit ACCM */
|
||||
void ppp_set_xaccm (int, ext_accm *);
|
||||
/* Configure i/f receive parameters */
|
||||
|
@ -441,7 +452,7 @@ void ppp_recv_config (int, int, u32_t, int, int);
|
|||
int get_idle_time (int, struct ppp_idle *);
|
||||
|
||||
/* Configure VJ TCP header compression */
|
||||
int sifvjcomp (int, int, int, int);
|
||||
int sifvjcomp (int, int, u8_t, u8_t);
|
||||
/* Configure i/f down (for IP) */
|
||||
int sifup (int);
|
||||
/* Set mode for handling packets for proto */
|
||||
|
@ -460,6 +471,13 @@ int cifdefaultroute (int, u32_t, u32_t);
|
|||
/* Get appropriate netmask for address */
|
||||
u32_t GetMask (u32_t);
|
||||
|
||||
#if LWIP_NETIF_STATUS_CALLBACK
|
||||
void ppp_set_netif_statuscallback(int pd, netif_status_callback_fn status_callback);
|
||||
#endif /* LWIP_NETIF_STATUS_CALLBACK */
|
||||
#if LWIP_NETIF_LINK_CALLBACK
|
||||
void ppp_set_netif_linkcallback(int pd, netif_status_callback_fn link_callback);
|
||||
#endif /* LWIP_NETIF_LINK_CALLBACK */
|
||||
|
||||
#endif /* PPP_SUPPORT */
|
||||
|
||||
#endif /* PPP_H */
|
||||
|
|
|
@ -72,104 +72,22 @@
|
|||
|
||||
#if PPPOE_SUPPORT /* don't build if not configured for use in lwipopts.h */
|
||||
|
||||
#include "netif/ppp_oe.h"
|
||||
|
||||
#include "ppp.h"
|
||||
#include "pppdebug.h"
|
||||
|
||||
#include "lwip/sys.h"
|
||||
|
||||
#include "netif/ppp_oe.h"
|
||||
#include "netif/etharp.h"
|
||||
#include "lwip/timers.h"
|
||||
#include "lwip/memp.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/** @todo Replace this part with a simple list like other lwIP lists */
|
||||
#ifndef _SYS_QUEUE_H_
|
||||
#define _SYS_QUEUE_H_
|
||||
|
||||
/*
|
||||
* A list is headed by a single forward pointer (or an array of forward
|
||||
* pointers for a hash table header). The elements are doubly linked
|
||||
* so that an arbitrary element can be removed without a need to
|
||||
* traverse the list. New elements can be added to the list before
|
||||
* or after an existing element or at the head of the list. A list
|
||||
* may only be traversed in the forward direction.
|
||||
*
|
||||
* For details on the use of these macros, see the queue(3) manual page.
|
||||
*/
|
||||
|
||||
/*
|
||||
* List declarations.
|
||||
*/
|
||||
#define LIST_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *lh_first; /* first element */ \
|
||||
}
|
||||
|
||||
#define LIST_HEAD_INITIALIZER(head) \
|
||||
{ NULL }
|
||||
|
||||
#define LIST_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *le_next; /* next element */ \
|
||||
struct type **le_prev; /* address of previous next element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* List functions.
|
||||
*/
|
||||
|
||||
#define LIST_EMPTY(head) ((head)->lh_first == NULL)
|
||||
|
||||
#define LIST_FIRST(head) ((head)->lh_first)
|
||||
|
||||
#define LIST_FOREACH(var, head, field) \
|
||||
for ((var) = LIST_FIRST((head)); \
|
||||
(var); \
|
||||
(var) = LIST_NEXT((var), field))
|
||||
|
||||
#define LIST_INIT(head) do { \
|
||||
LIST_FIRST((head)) = NULL; \
|
||||
} while (0)
|
||||
|
||||
#define LIST_INSERT_AFTER(listelm, elm, field) do { \
|
||||
if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL) \
|
||||
LIST_NEXT((listelm), field)->field.le_prev = \
|
||||
&LIST_NEXT((elm), field); \
|
||||
LIST_NEXT((listelm), field) = (elm); \
|
||||
(elm)->field.le_prev = &LIST_NEXT((listelm), field); \
|
||||
} while (0)
|
||||
|
||||
#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
|
||||
(elm)->field.le_prev = (listelm)->field.le_prev; \
|
||||
LIST_NEXT((elm), field) = (listelm); \
|
||||
*(listelm)->field.le_prev = (elm); \
|
||||
(listelm)->field.le_prev = &LIST_NEXT((elm), field); \
|
||||
} while (0)
|
||||
|
||||
#define LIST_INSERT_HEAD(head, elm, field) do { \
|
||||
if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \
|
||||
LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field); \
|
||||
LIST_FIRST((head)) = (elm); \
|
||||
(elm)->field.le_prev = &LIST_FIRST((head)); \
|
||||
} while (0)
|
||||
|
||||
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
|
||||
|
||||
#define LIST_REMOVE(elm, field) do { \
|
||||
if (LIST_NEXT((elm), field) != NULL) \
|
||||
LIST_NEXT((elm), field)->field.le_prev = \
|
||||
(elm)->field.le_prev; \
|
||||
*(elm)->field.le_prev = LIST_NEXT((elm), field); \
|
||||
} while (0)
|
||||
|
||||
#endif /* !_SYS_QUEUE_H_ */
|
||||
|
||||
|
||||
/* Add a 16 bit unsigned value to a buffer pointed to by PTR */
|
||||
#define PPPOE_ADD_16(PTR, VAL) \
|
||||
*(PTR)++ = (VAL) / 256; \
|
||||
*(PTR)++ = (VAL) % 256
|
||||
*(PTR)++ = (u8_t)((VAL) / 256); \
|
||||
*(PTR)++ = (u8_t)((VAL) % 256)
|
||||
|
||||
/* Add a complete PPPoE header to the buffer pointed to by PTR */
|
||||
#define PPPOE_ADD_HEADER(PTR, CODE, SESS, LEN) \
|
||||
|
@ -184,31 +102,16 @@ struct { \
|
|||
#define PPPOE_DISC_MAXPADR 2 /* retry PADR twice */
|
||||
|
||||
#ifdef PPPOE_SERVER
|
||||
#error "PPPOE_SERVER is not yet supported under lwIP!"
|
||||
/* from if_spppsubr.c */
|
||||
#define IFF_PASSIVE IFF_LINK0 /* wait passively for connection */
|
||||
#endif
|
||||
|
||||
struct pppoe_softc {
|
||||
LIST_ENTRY(pppoe_softc) sc_list;
|
||||
struct netif *sc_ethif; /* ethernet interface we are using */
|
||||
int sc_pd; /* ppp unit number */
|
||||
void (*sc_linkStatusCB)(int pd, int up);
|
||||
|
||||
int sc_state; /* discovery phase or session connected */
|
||||
struct eth_addr sc_dest; /* hardware address of concentrator */
|
||||
u16_t sc_session; /* PPPoE session id */
|
||||
|
||||
char *sc_service_name; /* if != NULL: requested name of service */
|
||||
char *sc_concentrator_name; /* if != NULL: requested concentrator id */
|
||||
u8_t *sc_ac_cookie; /* content of AC cookie we must echo back */
|
||||
size_t sc_ac_cookie_len; /* length of cookie data */
|
||||
#ifdef PPPOE_SERVER
|
||||
u8_t *sc_hunique; /* content of host unique we must echo back */
|
||||
size_t sc_hunique_len; /* length of host unique */
|
||||
#ifndef PPPOE_ERRORSTRING_LEN
|
||||
#define PPPOE_ERRORSTRING_LEN 64
|
||||
#endif
|
||||
int sc_padi_retried; /* number of PADI retries already done */
|
||||
int sc_padr_retried; /* number of PADR retries already done */
|
||||
};
|
||||
static char pppoe_error_tmp[PPPOE_ERRORSTRING_LEN];
|
||||
|
||||
|
||||
/* input routines */
|
||||
static void pppoe_dispatch_disc_pkt(struct netif *, struct pbuf *);
|
||||
|
@ -234,24 +137,16 @@ static err_t pppoe_send_padt(struct netif *, u_int, const u8_t *);
|
|||
static struct pppoe_softc * pppoe_find_softc_by_session(u_int, struct netif *);
|
||||
static struct pppoe_softc * pppoe_find_softc_by_hunique(u8_t *, size_t, struct netif *);
|
||||
|
||||
static LIST_HEAD(pppoe_softc_head, pppoe_softc) pppoe_softc_list;
|
||||
|
||||
int pppoe_hdrlen;
|
||||
|
||||
void
|
||||
pppoe_init(void)
|
||||
{
|
||||
pppoe_hdrlen = sizeof(struct eth_hdr) + PPPOE_HEADERLEN;
|
||||
LIST_INIT(&pppoe_softc_list);
|
||||
}
|
||||
/** linked list of created pppoe interfaces */
|
||||
static struct pppoe_softc *pppoe_softc_list;
|
||||
|
||||
err_t
|
||||
pppoe_create(struct netif *ethif, int pd, void (*linkStatusCB)(int pd, int up), struct pppoe_softc **scptr)
|
||||
{
|
||||
struct pppoe_softc *sc;
|
||||
|
||||
sc = mem_malloc(sizeof(struct pppoe_softc));
|
||||
if(!sc) {
|
||||
sc = (struct pppoe_softc *)memp_malloc(MEMP_PPPOE_IF);
|
||||
if (sc == NULL) {
|
||||
*scptr = NULL;
|
||||
return ERR_MEM;
|
||||
}
|
||||
|
@ -264,7 +159,9 @@ pppoe_create(struct netif *ethif, int pd, void (*linkStatusCB)(int pd, int up),
|
|||
sc->sc_linkStatusCB = linkStatusCB;
|
||||
sc->sc_ethif = ethif;
|
||||
|
||||
LIST_INSERT_HEAD(&pppoe_softc_list, sc, sc_list);
|
||||
/* put the new interface at the head of the list */
|
||||
sc->next = pppoe_softc_list;
|
||||
pppoe_softc_list = sc;
|
||||
|
||||
*scptr = sc;
|
||||
|
||||
|
@ -274,9 +171,9 @@ pppoe_create(struct netif *ethif, int pd, void (*linkStatusCB)(int pd, int up),
|
|||
err_t
|
||||
pppoe_destroy(struct netif *ifp)
|
||||
{
|
||||
struct pppoe_softc * sc;
|
||||
struct pppoe_softc *sc, *prev = NULL;
|
||||
|
||||
LIST_FOREACH(sc, &pppoe_softc_list, sc_list) {
|
||||
for (sc = pppoe_softc_list; sc != NULL; prev = sc, sc = sc->next) {
|
||||
if (sc->sc_ethif == ifp) {
|
||||
break;
|
||||
}
|
||||
|
@ -286,19 +183,24 @@ pppoe_destroy(struct netif *ifp)
|
|||
return ERR_IF;
|
||||
}
|
||||
|
||||
tcpip_untimeout(pppoe_timeout, sc);
|
||||
LIST_REMOVE(sc, sc_list);
|
||||
sys_untimeout(pppoe_timeout, sc);
|
||||
if (prev == NULL) {
|
||||
/* remove sc from the head of the list */
|
||||
pppoe_softc_list = sc->next;
|
||||
} else {
|
||||
/* remove sc from the list */
|
||||
prev->next = sc->next;
|
||||
}
|
||||
|
||||
#ifdef PPPOE_TODO
|
||||
if (sc->sc_concentrator_name) {
|
||||
mem_free(sc->sc_concentrator_name);
|
||||
}
|
||||
if (sc->sc_service_name) {
|
||||
mem_free(sc->sc_service_name);
|
||||
}
|
||||
if (sc->sc_ac_cookie) {
|
||||
mem_free(sc->sc_ac_cookie);
|
||||
}
|
||||
mem_free(sc);
|
||||
#endif /* PPPOE_TODO */
|
||||
memp_free(MEMP_PPPOE_IF, sc);
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
@ -318,7 +220,7 @@ pppoe_find_softc_by_session(u_int session, struct netif *rcvif)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
LIST_FOREACH(sc, &pppoe_softc_list, sc_list) {
|
||||
for (sc = pppoe_softc_list; sc != NULL; sc = sc->next) {
|
||||
if (sc->sc_state == PPPOE_STATE_SESSION
|
||||
&& sc->sc_session == session) {
|
||||
if (sc->sc_ethif == rcvif) {
|
||||
|
@ -338,7 +240,7 @@ pppoe_find_softc_by_hunique(u8_t *token, size_t len, struct netif *rcvif)
|
|||
{
|
||||
struct pppoe_softc *sc, *t;
|
||||
|
||||
if (LIST_EMPTY(&pppoe_softc_list)) {
|
||||
if (pppoe_softc_list == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -347,14 +249,14 @@ pppoe_find_softc_by_hunique(u8_t *token, size_t len, struct netif *rcvif)
|
|||
}
|
||||
MEMCPY(&t, token, len);
|
||||
|
||||
LIST_FOREACH(sc, &pppoe_softc_list, sc_list) {
|
||||
for (sc = pppoe_softc_list; sc != NULL; sc = sc->next) {
|
||||
if (sc == t) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (sc == NULL) {
|
||||
PPPDEBUG((LOG_DEBUG, "pppoe: alien host unique tag, no session found\n"));
|
||||
PPPDEBUG(LOG_DEBUG, ("pppoe: alien host unique tag, no session found\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -373,10 +275,8 @@ pppoe_find_softc_by_hunique(u8_t *token, size_t len, struct netif *rcvif)
|
|||
}
|
||||
|
||||
static void
|
||||
pppoe_linkstatus_up(void *arg)
|
||||
pppoe_linkstatus_up(struct pppoe_softc *sc)
|
||||
{
|
||||
struct pppoe_softc *sc = (struct pppoe_softc*)arg;
|
||||
|
||||
sc->sc_linkStatusCB(sc->sc_pd, 1);
|
||||
}
|
||||
|
||||
|
@ -389,9 +289,8 @@ pppoe_dispatch_disc_pkt(struct netif *netif, struct pbuf *pb)
|
|||
struct pppoe_softc *sc;
|
||||
const char *err_msg;
|
||||
char devname[6];
|
||||
char *error;
|
||||
u8_t *ac_cookie;
|
||||
size_t ac_cookie_len;
|
||||
u16_t ac_cookie_len;
|
||||
#ifdef PPPOE_SERVER
|
||||
u8_t *hunique;
|
||||
size_t hunique_len;
|
||||
|
@ -439,7 +338,7 @@ pppoe_dispatch_disc_pkt(struct netif *netif, struct pbuf *pb)
|
|||
goto done;
|
||||
}
|
||||
if(pb->tot_len == pb->len) {
|
||||
pb->tot_len = pb->len = off + plen; /* ignore trailing garbage */
|
||||
pb->tot_len = pb->len = (u16_t)off + plen; /* ignore trailing garbage */
|
||||
}
|
||||
tag = 0;
|
||||
len = 0;
|
||||
|
@ -492,17 +391,11 @@ pppoe_dispatch_disc_pkt(struct netif *netif, struct pbuf *pb)
|
|||
break;
|
||||
}
|
||||
if (err_msg) {
|
||||
error = NULL;
|
||||
if (errortag && len) {
|
||||
error = mem_malloc(len+1);
|
||||
if (error) {
|
||||
strncpy(error, (char*)pb->payload + off + sizeof(pt), len);
|
||||
error[len-1] = '\0';
|
||||
}
|
||||
}
|
||||
if (error) {
|
||||
printf("%s: %s: %s\n", devname, err_msg, error);
|
||||
mem_free(error);
|
||||
u16_t error_len = LWIP_MIN(len, sizeof(pppoe_error_tmp)-1);
|
||||
strncpy(pppoe_error_tmp, (char*)pb->payload + off + sizeof(pt), error_len);
|
||||
pppoe_error_tmp[error_len-1] = '\0';
|
||||
printf("%s: %s: %s\n", devname, err_msg, pppoe_error_tmp);
|
||||
} else {
|
||||
printf("%s: %s\n", devname, err_msg);
|
||||
}
|
||||
|
@ -554,9 +447,9 @@ breakbreak:;
|
|||
sc->sc_state = PPPOE_STATE_PADO_SENT;
|
||||
pppoe_send_pado(sc);
|
||||
break;
|
||||
#endif /* PPPOE_SERVER */
|
||||
#endif /* PPPOE_SERVER */
|
||||
case PPPOE_CODE_PADR:
|
||||
#ifdef PPPOE_SERVER
|
||||
#ifdef PPPOE_SERVER
|
||||
/*
|
||||
* get sc from ac_cookie if IFF_PASSIVE
|
||||
*/
|
||||
|
@ -590,16 +483,16 @@ breakbreak:;
|
|||
}
|
||||
pppoe_send_pads(sc);
|
||||
sc->sc_state = PPPOE_STATE_SESSION;
|
||||
tcpip_timeout (100, pppoe_linkstatus_up, sc); /* notify upper layers */
|
||||
pppoe_linkstatus_up(sc); /* notify upper layers */
|
||||
break;
|
||||
#else
|
||||
#else
|
||||
/* ignore, we are no access concentrator */
|
||||
goto done;
|
||||
#endif /* PPPOE_SERVER */
|
||||
#endif /* PPPOE_SERVER */
|
||||
case PPPOE_CODE_PADO:
|
||||
if (sc == NULL) {
|
||||
/* be quiet if there is not a single pppoe instance */
|
||||
if (!LIST_EMPTY(&pppoe_softc_list)) {
|
||||
if (pppoe_softc_list != NULL) {
|
||||
printf("pppoe: received PADO but could not find request for it\n");
|
||||
}
|
||||
goto done;
|
||||
|
@ -609,34 +502,27 @@ breakbreak:;
|
|||
goto done;
|
||||
}
|
||||
if (ac_cookie) {
|
||||
if (sc->sc_ac_cookie) {
|
||||
mem_free(sc->sc_ac_cookie);
|
||||
}
|
||||
sc->sc_ac_cookie = mem_malloc(ac_cookie_len);
|
||||
if (sc->sc_ac_cookie == NULL) {
|
||||
goto done;
|
||||
}
|
||||
sc->sc_ac_cookie_len = ac_cookie_len;
|
||||
MEMCPY(sc->sc_ac_cookie, ac_cookie, ac_cookie_len);
|
||||
}
|
||||
MEMCPY(&sc->sc_dest, ethhdr->src.addr, sizeof(sc->sc_dest.addr));
|
||||
tcpip_untimeout(pppoe_timeout, sc);
|
||||
sys_untimeout(pppoe_timeout, sc);
|
||||
sc->sc_padr_retried = 0;
|
||||
sc->sc_state = PPPOE_STATE_PADR_SENT;
|
||||
if ((err = pppoe_send_padr(sc)) != 0) {
|
||||
PPPDEBUG((LOG_DEBUG, "pppoe: %c%c%"U16_F": failed to send PADR, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err));
|
||||
PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADR, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err));
|
||||
}
|
||||
tcpip_timeout(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc);
|
||||
sys_timeout(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc);
|
||||
break;
|
||||
case PPPOE_CODE_PADS:
|
||||
if (sc == NULL) {
|
||||
goto done;
|
||||
}
|
||||
sc->sc_session = session;
|
||||
tcpip_untimeout(pppoe_timeout, sc);
|
||||
PPPDEBUG((LOG_DEBUG, "pppoe: %c%c%"U16_F": session 0x%x connected\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, session));
|
||||
sys_untimeout(pppoe_timeout, sc);
|
||||
PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": session 0x%x connected\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, session));
|
||||
sc->sc_state = PPPOE_STATE_SESSION;
|
||||
tcpip_timeout (100, pppoe_linkstatus_up, sc); /* notify upper layers */
|
||||
pppoe_linkstatus_up(sc); /* notify upper layers */
|
||||
break;
|
||||
case PPPOE_CODE_PADT:
|
||||
if (sc == NULL) {
|
||||
|
@ -646,11 +532,11 @@ breakbreak:;
|
|||
break;
|
||||
default:
|
||||
if(sc) {
|
||||
printf("%c%c%"U16_F": unknown code (0x%04x) session = 0x%04x\n",
|
||||
printf("%c%c%"U16_F": unknown code (0x%"X16_F") session = 0x%"X16_F"\n",
|
||||
sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num,
|
||||
ph->code, session);
|
||||
(u16_t)ph->code, session);
|
||||
} else {
|
||||
printf("pppoe: unknown code (0x%04x) session = 0x%04x\n", ph->code, session);
|
||||
printf("pppoe: unknown code (0x%"X16_F") session = 0x%"X16_F"\n", (u16_t)ph->code, session);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -664,7 +550,7 @@ void
|
|||
pppoe_disc_input(struct netif *netif, struct pbuf *p)
|
||||
{
|
||||
/* avoid error messages if there is not a single pppoe instance */
|
||||
if (!LIST_EMPTY(&pppoe_softc_list)) {
|
||||
if (pppoe_softc_list != NULL) {
|
||||
pppoe_dispatch_disc_pkt(netif, p);
|
||||
} else {
|
||||
pbuf_free(p);
|
||||
|
@ -686,7 +572,7 @@ pppoe_data_input(struct netif *netif, struct pbuf *pb)
|
|||
#endif
|
||||
if (pbuf_header(pb, -(int)sizeof(struct eth_hdr)) != 0) {
|
||||
/* bail out */
|
||||
PPPDEBUG((LOG_ERR, "pppoe_data_input: pbuf_header failed\n"));
|
||||
PPPDEBUG(LOG_ERR, ("pppoe_data_input: pbuf_header failed\n"));
|
||||
LINK_STATS_INC(link.lenerr);
|
||||
goto drop;
|
||||
}
|
||||
|
@ -726,12 +612,12 @@ pppoe_data_input(struct netif *netif, struct pbuf *pb)
|
|||
|
||||
if (pbuf_header(pb, -(int)(PPPOE_HEADERLEN)) != 0) {
|
||||
/* bail out */
|
||||
PPPDEBUG((LOG_ERR, "pppoe_data_input: pbuf_header PPPOE_HEADERLEN failed\n"));
|
||||
PPPDEBUG(LOG_ERR, ("pppoe_data_input: pbuf_header PPPOE_HEADERLEN failed\n"));
|
||||
LINK_STATS_INC(link.lenerr);
|
||||
goto drop;
|
||||
}
|
||||
|
||||
PPPDEBUG((LOG_DEBUG, "pppoe_data_input: %c%c%"U16_F": pkthdr.len=%d, pppoe.len=%d\n",
|
||||
PPPDEBUG(LOG_DEBUG, ("pppoe_data_input: %c%c%"U16_F": pkthdr.len=%d, pppoe.len=%d\n",
|
||||
sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num,
|
||||
pb->len, plen));
|
||||
|
||||
|
@ -765,7 +651,7 @@ pppoe_output(struct pppoe_softc *sc, struct pbuf *pb)
|
|||
MEMCPY(ethhdr->dest.addr, sc->sc_dest.addr, sizeof(ethhdr->dest.addr));
|
||||
MEMCPY(ethhdr->src.addr, ((struct eth_addr *)sc->sc_ethif->hwaddr)->addr, sizeof(ethhdr->src.addr));
|
||||
|
||||
PPPDEBUG((LOG_DEBUG, "pppoe: %c%c%"U16_F" (%x) state=%d, session=0x%x output -> %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F", len=%d\n",
|
||||
PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F" (%x) state=%d, session=0x%x output -> %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F", len=%d\n",
|
||||
sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, etype,
|
||||
sc->sc_state, sc->sc_session,
|
||||
sc->sc_dest.addr[0], sc->sc_dest.addr[1], sc->sc_dest.addr[2], sc->sc_dest.addr[3], sc->sc_dest.addr[4], sc->sc_dest.addr[5],
|
||||
|
@ -783,46 +669,59 @@ pppoe_send_padi(struct pppoe_softc *sc)
|
|||
{
|
||||
struct pbuf *pb;
|
||||
u8_t *p;
|
||||
int len, l1 = 0, l2 = 0; /* XXX: gcc */
|
||||
int len;
|
||||
#ifdef PPPOE_TODO
|
||||
int l1 = 0, l2 = 0; /* XXX: gcc */
|
||||
#endif /* PPPOE_TODO */
|
||||
|
||||
if (sc->sc_state >PPPOE_STATE_PADI_SENT) {
|
||||
PPPDEBUG((LOG_ERR, "ERROR: pppoe_send_padi in state %d", sc->sc_state));
|
||||
PPPDEBUG(LOG_ERR, ("ERROR: pppoe_send_padi in state %d", sc->sc_state));
|
||||
}
|
||||
|
||||
/* calculate length of frame (excluding ethernet header + pppoe header) */
|
||||
len = 2 + 2 + 2 + 2 + sizeof sc; /* service name tag is required, host unique is send too */
|
||||
#ifdef PPPOE_TODO
|
||||
if (sc->sc_service_name != NULL) {
|
||||
l1 = strlen(sc->sc_service_name);
|
||||
l1 = (int)strlen(sc->sc_service_name);
|
||||
len += l1;
|
||||
}
|
||||
if (sc->sc_concentrator_name != NULL) {
|
||||
l2 = strlen(sc->sc_concentrator_name);
|
||||
l2 = (int)strlen(sc->sc_concentrator_name);
|
||||
len += 2 + 2 + l2;
|
||||
}
|
||||
#endif /* PPPOE_TODO */
|
||||
LWIP_ASSERT("sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff",
|
||||
sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff);
|
||||
|
||||
/* allocate a buffer */
|
||||
pb = pbuf_alloc(PBUF_LINK, sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len, PBUF_RAM);
|
||||
pb = pbuf_alloc(PBUF_LINK, (u16_t)(sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len), PBUF_RAM);
|
||||
if (!pb) {
|
||||
return ERR_MEM;
|
||||
}
|
||||
LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len);
|
||||
|
||||
p = (u8_t*)pb->payload + sizeof (struct eth_hdr);
|
||||
/* fill in pkt */
|
||||
PPPOE_ADD_HEADER(p, PPPOE_CODE_PADI, 0, len);
|
||||
PPPOE_ADD_HEADER(p, PPPOE_CODE_PADI, 0, (u16_t)len);
|
||||
PPPOE_ADD_16(p, PPPOE_TAG_SNAME);
|
||||
#ifdef PPPOE_TODO
|
||||
if (sc->sc_service_name != NULL) {
|
||||
PPPOE_ADD_16(p, l1);
|
||||
MEMCPY(p, sc->sc_service_name, l1);
|
||||
p += l1;
|
||||
} else {
|
||||
} else
|
||||
#endif /* PPPOE_TODO */
|
||||
{
|
||||
PPPOE_ADD_16(p, 0);
|
||||
}
|
||||
#ifdef PPPOE_TODO
|
||||
if (sc->sc_concentrator_name != NULL) {
|
||||
PPPOE_ADD_16(p, PPPOE_TAG_ACNAME);
|
||||
PPPOE_ADD_16(p, l2);
|
||||
MEMCPY(p, sc->sc_concentrator_name, l2);
|
||||
p += l2;
|
||||
}
|
||||
#endif /* PPPOE_TODO */
|
||||
PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE);
|
||||
PPPOE_ADD_16(p, sizeof(sc));
|
||||
MEMCPY(p, &sc, sizeof sc);
|
||||
|
@ -837,7 +736,7 @@ pppoe_timeout(void *arg)
|
|||
int retry_wait, err;
|
||||
struct pppoe_softc *sc = (struct pppoe_softc*)arg;
|
||||
|
||||
PPPDEBUG((LOG_DEBUG, "pppoe: %c%c%"U16_F": timeout\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num));
|
||||
PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": timeout\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num));
|
||||
|
||||
switch (sc->sc_state) {
|
||||
case PPPOE_STATE_PADI_SENT:
|
||||
|
@ -869,9 +768,9 @@ pppoe_timeout(void *arg)
|
|||
}
|
||||
if ((err = pppoe_send_padi(sc)) != 0) {
|
||||
sc->sc_padi_retried--;
|
||||
PPPDEBUG((LOG_DEBUG, "pppoe: %c%c%"U16_F": failed to transmit PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err));
|
||||
PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to transmit PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err));
|
||||
}
|
||||
tcpip_timeout(retry_wait, pppoe_timeout, sc);
|
||||
sys_timeout(retry_wait, pppoe_timeout, sc);
|
||||
break;
|
||||
|
||||
case PPPOE_STATE_PADR_SENT:
|
||||
|
@ -881,16 +780,16 @@ pppoe_timeout(void *arg)
|
|||
sc->sc_state = PPPOE_STATE_PADI_SENT;
|
||||
sc->sc_padr_retried = 0;
|
||||
if ((err = pppoe_send_padi(sc)) != 0) {
|
||||
PPPDEBUG((LOG_DEBUG, "pppoe: %c%c%"U16_F": failed to send PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err));
|
||||
PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err));
|
||||
}
|
||||
tcpip_timeout(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried), pppoe_timeout, sc);
|
||||
sys_timeout(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried), pppoe_timeout, sc);
|
||||
return;
|
||||
}
|
||||
if ((err = pppoe_send_padr(sc)) != 0) {
|
||||
sc->sc_padr_retried--;
|
||||
PPPDEBUG((LOG_DEBUG, "pppoe: %c%c%"U16_F": failed to send PADR, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err));
|
||||
PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADR, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err));
|
||||
}
|
||||
tcpip_timeout(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc);
|
||||
sys_timeout(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc);
|
||||
break;
|
||||
case PPPOE_STATE_CLOSING:
|
||||
pppoe_do_disconnect(sc);
|
||||
|
@ -920,8 +819,8 @@ pppoe_connect(struct pppoe_softc *sc)
|
|||
sc->sc_state = PPPOE_STATE_PADI_SENT;
|
||||
sc->sc_padr_retried = 0;
|
||||
err = pppoe_send_padi(sc);
|
||||
PPPDEBUG((LOG_DEBUG, "pppoe: %c%c%"U16_F": failed to send PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err));
|
||||
tcpip_timeout(PPPOE_DISC_TIMEOUT, pppoe_timeout, sc);
|
||||
PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err));
|
||||
sys_timeout(PPPOE_DISC_TIMEOUT, pppoe_timeout, sc);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -938,7 +837,7 @@ pppoe_disconnect(struct pppoe_softc *sc)
|
|||
* function and defer disconnecting to the timeout handler.
|
||||
*/
|
||||
sc->sc_state = PPPOE_STATE_CLOSING;
|
||||
tcpip_timeout(20, pppoe_timeout, sc);
|
||||
sys_timeout(20, pppoe_timeout, sc);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -949,17 +848,13 @@ pppoe_do_disconnect(struct pppoe_softc *sc)
|
|||
if (sc->sc_state < PPPOE_STATE_SESSION) {
|
||||
err = EBUSY;
|
||||
} else {
|
||||
PPPDEBUG((LOG_DEBUG, "pppoe: %c%c%"U16_F": disconnecting\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num));
|
||||
PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": disconnecting\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num));
|
||||
err = pppoe_send_padt(sc->sc_ethif, sc->sc_session, (const u8_t *)&sc->sc_dest);
|
||||
}
|
||||
|
||||
/* cleanup softc */
|
||||
sc->sc_state = PPPOE_STATE_INITIAL;
|
||||
MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest));
|
||||
if (sc->sc_ac_cookie) {
|
||||
mem_free(sc->sc_ac_cookie);
|
||||
sc->sc_ac_cookie = NULL;
|
||||
}
|
||||
sc->sc_ac_cookie_len = 0;
|
||||
#ifdef PPPOE_SERVER
|
||||
if (sc->sc_hunique) {
|
||||
|
@ -995,32 +890,43 @@ pppoe_send_padr(struct pppoe_softc *sc)
|
|||
{
|
||||
struct pbuf *pb;
|
||||
u8_t *p;
|
||||
size_t len, l1 = 0; /* XXX: gcc */
|
||||
size_t len;
|
||||
#ifdef PPPOE_TODO
|
||||
size_t l1 = 0; /* XXX: gcc */
|
||||
#endif /* PPPOE_TODO */
|
||||
|
||||
if (sc->sc_state != PPPOE_STATE_PADR_SENT) {
|
||||
return ERR_CONN;
|
||||
}
|
||||
|
||||
len = 2 + 2 + 2 + 2 + sizeof(sc); /* service name, host unique */
|
||||
#ifdef PPPOE_TODO
|
||||
if (sc->sc_service_name != NULL) { /* service name tag maybe empty */
|
||||
l1 = strlen(sc->sc_service_name);
|
||||
len += l1;
|
||||
}
|
||||
#endif /* PPPOE_TODO */
|
||||
if (sc->sc_ac_cookie_len > 0) {
|
||||
len += 2 + 2 + sc->sc_ac_cookie_len; /* AC cookie */
|
||||
}
|
||||
pb = pbuf_alloc(PBUF_LINK, sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len, PBUF_RAM);
|
||||
LWIP_ASSERT("sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff",
|
||||
sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff);
|
||||
pb = pbuf_alloc(PBUF_LINK, (u16_t)(sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len), PBUF_RAM);
|
||||
if (!pb) {
|
||||
return ERR_MEM;
|
||||
}
|
||||
LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len);
|
||||
p = (u8_t*)pb->payload + sizeof (struct eth_hdr);
|
||||
PPPOE_ADD_HEADER(p, PPPOE_CODE_PADR, 0, len);
|
||||
PPPOE_ADD_16(p, PPPOE_TAG_SNAME);
|
||||
#ifdef PPPOE_TODO
|
||||
if (sc->sc_service_name != NULL) {
|
||||
PPPOE_ADD_16(p, l1);
|
||||
MEMCPY(p, sc->sc_service_name, l1);
|
||||
p += l1;
|
||||
} else {
|
||||
} else
|
||||
#endif /* PPPOE_TODO */
|
||||
{
|
||||
PPPOE_ADD_16(p, 0);
|
||||
}
|
||||
if (sc->sc_ac_cookie_len > 0) {
|
||||
|
@ -1049,9 +955,10 @@ pppoe_send_padt(struct netif *outgoing_if, u_int session, const u8_t *dest)
|
|||
if (!pb) {
|
||||
return ERR_MEM;
|
||||
}
|
||||
LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len);
|
||||
|
||||
ethhdr = (struct eth_hdr *)pb->payload;
|
||||
ethhdr->type = htons(ETHTYPE_PPPOEDISC);
|
||||
ethhdr->type = PP_HTONS(ETHTYPE_PPPOEDISC);
|
||||
MEMCPY(ethhdr->dest.addr, dest, sizeof(ethhdr->dest.addr));
|
||||
MEMCPY(ethhdr->src.addr, ((struct eth_addr *)outgoing_if->hwaddr)->addr, sizeof(ethhdr->src.addr));
|
||||
|
||||
|
@ -1087,6 +994,7 @@ pppoe_send_pado(struct pppoe_softc *sc)
|
|||
if (!pb) {
|
||||
return ERR_MEM;
|
||||
}
|
||||
LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len);
|
||||
p = (u8_t*)pb->payload + sizeof (struct eth_hdr);
|
||||
PPPOE_ADD_HEADER(p, PPPOE_CODE_PADO, 0, len);
|
||||
PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE);
|
||||
|
@ -1123,6 +1031,7 @@ pppoe_send_pads(struct pppoe_softc *sc)
|
|||
if (!pb) {
|
||||
return ERR_MEM;
|
||||
}
|
||||
LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len);
|
||||
p = (u8_t*)pb->payload + sizeof (struct eth_hdr);
|
||||
PPPOE_ADD_HEADER(p, PPPOE_CODE_PADS, sc->sc_session, len);
|
||||
PPPOE_ADD_16(p, PPPOE_TAG_SNAME);
|
||||
|
@ -1158,7 +1067,7 @@ pppoe_xmit(struct pppoe_softc *sc, struct pbuf *pb)
|
|||
/* make room for Ethernet header - should not fail */
|
||||
if (pbuf_header(pb, sizeof(struct eth_hdr) + PPPOE_HEADERLEN) != 0) {
|
||||
/* bail out */
|
||||
PPPDEBUG((LOG_ERR, "pppoe: %c%c%"U16_F": pppoe_xmit: could not allocate room for header\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num));
|
||||
PPPDEBUG(LOG_ERR, ("pppoe: %c%c%"U16_F": pppoe_xmit: could not allocate room for header\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num));
|
||||
LINK_STATS_INC(link.lenerr);
|
||||
pbuf_free(pb);
|
||||
return ERR_BUF;
|
||||
|
@ -1204,8 +1113,8 @@ pppoe_clear_softc(struct pppoe_softc *sc, const char *message)
|
|||
LWIP_UNUSED_ARG(message);
|
||||
|
||||
/* stop timer */
|
||||
tcpip_untimeout(pppoe_timeout, sc);
|
||||
PPPDEBUG((LOG_DEBUG, "pppoe: %c%c%"U16_F": session 0x%x terminated, %s\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, sc->sc_session, message));
|
||||
sys_untimeout(pppoe_timeout, sc);
|
||||
PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": session 0x%x terminated, %s\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, sc->sc_session, message));
|
||||
|
||||
/* fix our state */
|
||||
sc->sc_state = PPPOE_STATE_INITIAL;
|
||||
|
@ -1215,10 +1124,6 @@ pppoe_clear_softc(struct pppoe_softc *sc, const char *message)
|
|||
|
||||
/* clean up softc */
|
||||
MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest));
|
||||
if (sc->sc_ac_cookie) {
|
||||
mem_free(sc->sc_ac_cookie);
|
||||
sc->sc_ac_cookie = NULL;
|
||||
}
|
||||
sc->sc_ac_cookie_len = 0;
|
||||
sc->sc_session = 0;
|
||||
}
|
||||
|
|
|
@ -36,50 +36,37 @@
|
|||
#ifndef PPPDEBUG_H
|
||||
#define PPPDEBUG_H
|
||||
|
||||
/************************
|
||||
*** PUBLIC DATA TYPES ***
|
||||
************************/
|
||||
/* Trace levels. */
|
||||
typedef enum {
|
||||
LOG_CRITICAL = 0,
|
||||
LOG_ERR = 1,
|
||||
LOG_NOTICE = 2,
|
||||
LOG_WARNING = 3,
|
||||
LOG_INFO = 5,
|
||||
LOG_DETAIL = 6,
|
||||
LOG_DEBUG = 7
|
||||
} LogCodes;
|
||||
#define LOG_CRITICAL (PPP_DEBUG | LWIP_DBG_LEVEL_SEVERE)
|
||||
#define LOG_ERR (PPP_DEBUG | LWIP_DBG_LEVEL_SEVERE)
|
||||
#define LOG_NOTICE (PPP_DEBUG | LWIP_DBG_LEVEL_WARNING)
|
||||
#define LOG_WARNING (PPP_DEBUG | LWIP_DBG_LEVEL_WARNING)
|
||||
#define LOG_INFO (PPP_DEBUG)
|
||||
#define LOG_DETAIL (PPP_DEBUG)
|
||||
#define LOG_DEBUG (PPP_DEBUG)
|
||||
|
||||
|
||||
/***********************
|
||||
*** PUBLIC FUNCTIONS ***
|
||||
***********************/
|
||||
/*
|
||||
* ppp_trace - a form of printf to send tracing information to stderr
|
||||
*/
|
||||
void ppp_trace(int level, const char *format,...);
|
||||
|
||||
#define TRACELCP PPP_DEBUG
|
||||
|
||||
#if PPP_DEBUG
|
||||
|
||||
#define AUTHDEBUG(a) ppp_trace a
|
||||
#define IPCPDEBUG(a) ppp_trace a
|
||||
#define UPAPDEBUG(a) ppp_trace a
|
||||
#define LCPDEBUG(a) ppp_trace a
|
||||
#define FSMDEBUG(a) ppp_trace a
|
||||
#define CHAPDEBUG(a) ppp_trace a
|
||||
#define PPPDEBUG(a) ppp_trace a
|
||||
#define AUTHDEBUG(a, b) LWIP_DEBUGF(a, b)
|
||||
#define IPCPDEBUG(a, b) LWIP_DEBUGF(a, b)
|
||||
#define UPAPDEBUG(a, b) LWIP_DEBUGF(a, b)
|
||||
#define LCPDEBUG(a, b) LWIP_DEBUGF(a, b)
|
||||
#define FSMDEBUG(a, b) LWIP_DEBUGF(a, b)
|
||||
#define CHAPDEBUG(a, b) LWIP_DEBUGF(a, b)
|
||||
#define PPPDEBUG(a, b) LWIP_DEBUGF(a, b)
|
||||
|
||||
#else /* PPP_DEBUG */
|
||||
|
||||
#define AUTHDEBUG(a)
|
||||
#define IPCPDEBUG(a)
|
||||
#define UPAPDEBUG(a)
|
||||
#define LCPDEBUG(a)
|
||||
#define FSMDEBUG(a)
|
||||
#define CHAPDEBUG(a)
|
||||
#define PPPDEBUG(a)
|
||||
#define AUTHDEBUG(a, b)
|
||||
#define IPCPDEBUG(a, b)
|
||||
#define UPAPDEBUG(a, b)
|
||||
#define LCPDEBUG(a, b)
|
||||
#define FSMDEBUG(a, b)
|
||||
#define CHAPDEBUG(a, b)
|
||||
#define PPPDEBUG(a, b)
|
||||
|
||||
#endif /* PPP_DEBUG */
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ avChurnRand(char *randData, u32_t randLen)
|
|||
{
|
||||
MD5_CTX md5;
|
||||
|
||||
/* ppp_trace(LOG_INFO, "churnRand: %u@%P\n", randLen, randData); */
|
||||
/* LWIP_DEBUGF(LOG_INFO, ("churnRand: %u@%P\n", randLen, randData)); */
|
||||
MD5Init(&md5);
|
||||
MD5Update(&md5, (u_char *)randPool, sizeof(randPool));
|
||||
if (randData) {
|
||||
|
@ -100,7 +100,7 @@ avChurnRand(char *randData, u32_t randLen)
|
|||
MD5Update(&md5, (u_char *)&sysData, sizeof(sysData));
|
||||
}
|
||||
MD5Final((u_char *)randPool, &md5);
|
||||
/* ppp_trace(LOG_INFO, "churnRand: -> 0\n"); */
|
||||
/* LWIP_DEBUGF(LOG_INFO, ("churnRand: -> 0\n")); */
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -47,18 +47,10 @@
|
|||
#define INCR(counter)
|
||||
#endif
|
||||
|
||||
#if defined(NO_CHAR_BITFIELDS)
|
||||
#define getip_hl(base) ((base).ip_hl_v&0xf)
|
||||
#define getth_off(base) (((base).th_x2_off&0xf0)>>4)
|
||||
#else
|
||||
#define getip_hl(base) ((base).ip_hl)
|
||||
#define getth_off(base) ((base).th_off)
|
||||
#endif
|
||||
|
||||
void
|
||||
vj_compress_init(struct vjcompress *comp)
|
||||
{
|
||||
register u_int i;
|
||||
register u_char i;
|
||||
register struct cstate *tstate = comp->tstate;
|
||||
|
||||
#if MAX_SLOTS == 0
|
||||
|
@ -86,21 +78,21 @@ vj_compress_init(struct vjcompress *comp)
|
|||
#define ENCODE(n) { \
|
||||
if ((u_short)(n) >= 256) { \
|
||||
*cp++ = 0; \
|
||||
cp[1] = (n); \
|
||||
cp[0] = (n) >> 8; \
|
||||
cp[1] = (u_char)(n); \
|
||||
cp[0] = (u_char)((n) >> 8); \
|
||||
cp += 2; \
|
||||
} else { \
|
||||
*cp++ = (n); \
|
||||
*cp++ = (u_char)(n); \
|
||||
} \
|
||||
}
|
||||
#define ENCODEZ(n) { \
|
||||
if ((u_short)(n) >= 256 || (u_short)(n) == 0) { \
|
||||
*cp++ = 0; \
|
||||
cp[1] = (n); \
|
||||
cp[0] = (n) >> 8; \
|
||||
cp[1] = (u_char)(n); \
|
||||
cp[0] = (u_char)((n) >> 8); \
|
||||
cp += 2; \
|
||||
} else { \
|
||||
*cp++ = (n); \
|
||||
*cp++ = (u_char)(n); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
@ -145,11 +137,11 @@ vj_compress_init(struct vjcompress *comp)
|
|||
u_int
|
||||
vj_compress_tcp(struct vjcompress *comp, struct pbuf *pb)
|
||||
{
|
||||
register struct ip *ip = (struct ip *)pb->payload;
|
||||
register struct ip_hdr *ip = (struct ip_hdr *)pb->payload;
|
||||
register struct cstate *cs = comp->last_cs->cs_next;
|
||||
register u_short hlen = getip_hl(*ip);
|
||||
register struct tcphdr *oth;
|
||||
register struct tcphdr *th;
|
||||
register u_short hlen = IPH_HL(ip);
|
||||
register struct tcp_hdr *oth;
|
||||
register struct tcp_hdr *th;
|
||||
register u_short deltaS, deltaA;
|
||||
register u_long deltaL;
|
||||
register u_int changes = 0;
|
||||
|
@ -159,7 +151,7 @@ vj_compress_tcp(struct vjcompress *comp, struct pbuf *pb)
|
|||
/*
|
||||
* Check that the packet is IP proto TCP.
|
||||
*/
|
||||
if (ip->ip_p != IPPROTO_TCP) {
|
||||
if (IPH_PROTO(ip) != IP_PROTO_TCP) {
|
||||
return (TYPE_IP);
|
||||
}
|
||||
|
||||
|
@ -168,11 +160,11 @@ vj_compress_tcp(struct vjcompress *comp, struct pbuf *pb)
|
|||
* `compressible' (i.e., ACK isn't set or some other control bit is
|
||||
* set).
|
||||
*/
|
||||
if ((ip->ip_off & htons(0x3fff)) || pb->tot_len < 40) {
|
||||
if ((IPH_OFFSET(ip) & PP_HTONS(0x3fff)) || pb->tot_len < 40) {
|
||||
return (TYPE_IP);
|
||||
}
|
||||
th = (struct tcphdr *)&((long *)ip)[hlen];
|
||||
if ((th->th_flags & (TCP_SYN|TCP_FIN|TCP_RST|TCP_ACK)) != TCP_ACK) {
|
||||
th = (struct tcp_hdr *)&((long *)ip)[hlen];
|
||||
if ((TCPH_FLAGS(th) & (TCP_SYN|TCP_FIN|TCP_RST|TCP_ACK)) != TCP_ACK) {
|
||||
return (TYPE_IP);
|
||||
}
|
||||
/*
|
||||
|
@ -183,9 +175,9 @@ vj_compress_tcp(struct vjcompress *comp, struct pbuf *pb)
|
|||
* again & we don't have to do any reordering if it's used.
|
||||
*/
|
||||
INCR(vjs_packets);
|
||||
if (ip->ip_src.s_addr != cs->cs_ip.ip_src.s_addr
|
||||
|| ip->ip_dst.s_addr != cs->cs_ip.ip_dst.s_addr
|
||||
|| *(long *)th != ((long *)&cs->cs_ip)[getip_hl(cs->cs_ip)]) {
|
||||
if (!ip_addr_cmp(&ip->src, &cs->cs_ip.src)
|
||||
|| !ip_addr_cmp(&ip->dest, &cs->cs_ip.dest)
|
||||
|| *(long *)th != ((long *)&cs->cs_ip)[IPH_HL(&cs->cs_ip)]) {
|
||||
/*
|
||||
* Wasn't the first -- search for it.
|
||||
*
|
||||
|
@ -204,9 +196,9 @@ vj_compress_tcp(struct vjcompress *comp, struct pbuf *pb)
|
|||
do {
|
||||
lcs = cs; cs = cs->cs_next;
|
||||
INCR(vjs_searches);
|
||||
if (ip->ip_src.s_addr == cs->cs_ip.ip_src.s_addr
|
||||
&& ip->ip_dst.s_addr == cs->cs_ip.ip_dst.s_addr
|
||||
&& *(long *)th == ((long *)&cs->cs_ip)[getip_hl(cs->cs_ip)]) {
|
||||
if (ip_addr_cmp(&ip->src, &cs->cs_ip.src)
|
||||
&& ip_addr_cmp(&ip->dest, &cs->cs_ip.dest)
|
||||
&& *(long *)th == ((long *)&cs->cs_ip)[IPH_HL(&cs->cs_ip)]) {
|
||||
goto found;
|
||||
}
|
||||
} while (cs != lastcs);
|
||||
|
@ -221,7 +213,7 @@ vj_compress_tcp(struct vjcompress *comp, struct pbuf *pb)
|
|||
*/
|
||||
INCR(vjs_misses);
|
||||
comp->last_cs = lcs;
|
||||
hlen += getth_off(*th);
|
||||
hlen += TCPH_OFFSET(th);
|
||||
hlen <<= 2;
|
||||
/* Check that the IP/TCP headers are contained in the first buffer. */
|
||||
if (hlen > pb->len) {
|
||||
|
@ -242,13 +234,13 @@ vj_compress_tcp(struct vjcompress *comp, struct pbuf *pb)
|
|||
}
|
||||
}
|
||||
|
||||
oth = (struct tcphdr *)&((long *)&cs->cs_ip)[hlen];
|
||||
oth = (struct tcp_hdr *)&((long *)&cs->cs_ip)[hlen];
|
||||
deltaS = hlen;
|
||||
hlen += getth_off(*th);
|
||||
hlen += TCPH_OFFSET(th);
|
||||
hlen <<= 2;
|
||||
/* Check that the IP/TCP headers are contained in the first buffer. */
|
||||
if (hlen > pb->len) {
|
||||
PPPDEBUG((LOG_INFO, "vj_compress_tcp: header len %d spans buffers\n", hlen));
|
||||
PPPDEBUG(LOG_INFO, ("vj_compress_tcp: header len %d spans buffers\n", hlen));
|
||||
return (TYPE_IP);
|
||||
}
|
||||
|
||||
|
@ -266,9 +258,9 @@ vj_compress_tcp(struct vjcompress *comp, struct pbuf *pb)
|
|||
if (((u_short *)ip)[0] != ((u_short *)&cs->cs_ip)[0]
|
||||
|| ((u_short *)ip)[3] != ((u_short *)&cs->cs_ip)[3]
|
||||
|| ((u_short *)ip)[4] != ((u_short *)&cs->cs_ip)[4]
|
||||
|| getth_off(*th) != getth_off(*oth)
|
||||
|| TCPH_OFFSET(th) != TCPH_OFFSET(oth)
|
||||
|| (deltaS > 5 && BCMP(ip + 1, &cs->cs_ip + 1, (deltaS - 5) << 2))
|
||||
|| (getth_off(*th) > 5 && BCMP(th + 1, oth + 1, (getth_off(*th) - 5) << 2))) {
|
||||
|| (TCPH_OFFSET(th) > 5 && BCMP(th + 1, oth + 1, (TCPH_OFFSET(th) - 5) << 2))) {
|
||||
goto uncompressed;
|
||||
}
|
||||
|
||||
|
@ -278,11 +270,11 @@ vj_compress_tcp(struct vjcompress *comp, struct pbuf *pb)
|
|||
* ack, seq (the order minimizes the number of temporaries
|
||||
* needed in this section of code).
|
||||
*/
|
||||
if (th->th_flags & TCP_URG) {
|
||||
deltaS = ntohs(th->th_urp);
|
||||
if (TCPH_FLAGS(th) & TCP_URG) {
|
||||
deltaS = ntohs(th->urgp);
|
||||
ENCODEZ(deltaS);
|
||||
changes |= NEW_U;
|
||||
} else if (th->th_urp != oth->th_urp) {
|
||||
} else if (th->urgp != oth->urgp) {
|
||||
/* argh! URG not set but urp changed -- a sensible
|
||||
* implementation should never do this but RFC793
|
||||
* doesn't prohibit the change so we have to deal
|
||||
|
@ -290,12 +282,12 @@ vj_compress_tcp(struct vjcompress *comp, struct pbuf *pb)
|
|||
goto uncompressed;
|
||||
}
|
||||
|
||||
if ((deltaS = (u_short)(ntohs(th->th_win) - ntohs(oth->th_win))) != 0) {
|
||||
if ((deltaS = (u_short)(ntohs(th->wnd) - ntohs(oth->wnd))) != 0) {
|
||||
ENCODE(deltaS);
|
||||
changes |= NEW_W;
|
||||
}
|
||||
|
||||
if ((deltaL = ntohl(th->th_ack) - ntohl(oth->th_ack)) != 0) {
|
||||
if ((deltaL = ntohl(th->ackno) - ntohl(oth->ackno)) != 0) {
|
||||
if (deltaL > 0xffff) {
|
||||
goto uncompressed;
|
||||
}
|
||||
|
@ -304,7 +296,7 @@ vj_compress_tcp(struct vjcompress *comp, struct pbuf *pb)
|
|||
changes |= NEW_A;
|
||||
}
|
||||
|
||||
if ((deltaL = ntohl(th->th_seq) - ntohl(oth->th_seq)) != 0) {
|
||||
if ((deltaL = ntohl(th->seqno) - ntohl(oth->seqno)) != 0) {
|
||||
if (deltaL > 0xffff) {
|
||||
goto uncompressed;
|
||||
}
|
||||
|
@ -323,8 +315,8 @@ vj_compress_tcp(struct vjcompress *comp, struct pbuf *pb)
|
|||
* retransmitted ack or window probe. Send it uncompressed
|
||||
* in case the other side missed the compressed version.
|
||||
*/
|
||||
if (ip->ip_len != cs->cs_ip.ip_len &&
|
||||
ntohs(cs->cs_ip.ip_len) == hlen) {
|
||||
if (IPH_LEN(ip) != IPH_LEN(&cs->cs_ip) &&
|
||||
ntohs(IPH_LEN(&cs->cs_ip)) == hlen) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -339,7 +331,7 @@ vj_compress_tcp(struct vjcompress *comp, struct pbuf *pb)
|
|||
goto uncompressed;
|
||||
|
||||
case NEW_S|NEW_A:
|
||||
if (deltaS == deltaA && deltaS == ntohs(cs->cs_ip.ip_len) - hlen) {
|
||||
if (deltaS == deltaA && deltaS == ntohs(IPH_LEN(&cs->cs_ip)) - hlen) {
|
||||
/* special case for echoed terminal traffic */
|
||||
changes = SPECIAL_I;
|
||||
cp = new_seq;
|
||||
|
@ -347,7 +339,7 @@ vj_compress_tcp(struct vjcompress *comp, struct pbuf *pb)
|
|||
break;
|
||||
|
||||
case NEW_S:
|
||||
if (deltaS == ntohs(cs->cs_ip.ip_len) - hlen) {
|
||||
if (deltaS == ntohs(IPH_LEN(&cs->cs_ip)) - hlen) {
|
||||
/* special case for data xfer */
|
||||
changes = SPECIAL_D;
|
||||
cp = new_seq;
|
||||
|
@ -355,19 +347,19 @@ vj_compress_tcp(struct vjcompress *comp, struct pbuf *pb)
|
|||
break;
|
||||
}
|
||||
|
||||
deltaS = (u_short)(ntohs(ip->ip_id) - ntohs(cs->cs_ip.ip_id));
|
||||
deltaS = (u_short)(ntohs(IPH_ID(ip)) - ntohs(IPH_ID(&cs->cs_ip)));
|
||||
if (deltaS != 1) {
|
||||
ENCODEZ(deltaS);
|
||||
changes |= NEW_I;
|
||||
}
|
||||
if (th->th_flags & TCP_PSH) {
|
||||
if (TCPH_FLAGS(th) & TCP_PSH) {
|
||||
changes |= TCP_PUSH_BIT;
|
||||
}
|
||||
/*
|
||||
* Grab the cksum before we overwrite it below. Then update our
|
||||
* state with this packet's header.
|
||||
*/
|
||||
deltaA = ntohs(th->th_sum);
|
||||
deltaA = ntohs(th->chksum);
|
||||
BCOPY(ip, &cs->cs_ip, hlen);
|
||||
|
||||
/*
|
||||
|
@ -388,7 +380,7 @@ vj_compress_tcp(struct vjcompress *comp, struct pbuf *pb)
|
|||
LWIP_ASSERT("pbuf_header failed\n", 0);
|
||||
}
|
||||
cp = (u_char *)pb->payload;
|
||||
*cp++ = changes | NEW_C;
|
||||
*cp++ = (u_char)(changes | NEW_C);
|
||||
*cp++ = cs->cs_id;
|
||||
} else {
|
||||
hlen -= deltaS + 3;
|
||||
|
@ -397,10 +389,10 @@ vj_compress_tcp(struct vjcompress *comp, struct pbuf *pb)
|
|||
LWIP_ASSERT("pbuf_header failed\n", 0);
|
||||
}
|
||||
cp = (u_char *)pb->payload;
|
||||
*cp++ = changes;
|
||||
*cp++ = (u_char)changes;
|
||||
}
|
||||
*cp++ = deltaA >> 8;
|
||||
*cp++ = deltaA;
|
||||
*cp++ = (u_char)(deltaA >> 8);
|
||||
*cp++ = (u_char)deltaA;
|
||||
BCOPY(new_seq, cp, deltaS);
|
||||
INCR(vjs_compressed);
|
||||
return (TYPE_COMPRESSED_TCP);
|
||||
|
@ -412,7 +404,7 @@ vj_compress_tcp(struct vjcompress *comp, struct pbuf *pb)
|
|||
*/
|
||||
uncompressed:
|
||||
BCOPY(ip, &cs->cs_ip, hlen);
|
||||
ip->ip_p = cs->cs_id;
|
||||
IPH_PROTO_SET(ip, cs->cs_id);
|
||||
comp->last_xmit = cs->cs_id;
|
||||
return (TYPE_UNCOMPRESSED_TCP);
|
||||
}
|
||||
|
@ -436,26 +428,26 @@ vj_uncompress_uncomp(struct pbuf *nb, struct vjcompress *comp)
|
|||
{
|
||||
register u_int hlen;
|
||||
register struct cstate *cs;
|
||||
register struct ip *ip;
|
||||
register struct ip_hdr *ip;
|
||||
|
||||
ip = (struct ip *)nb->payload;
|
||||
hlen = getip_hl(*ip) << 2;
|
||||
if (ip->ip_p >= MAX_SLOTS
|
||||
|| hlen + sizeof(struct tcphdr) > nb->len
|
||||
|| (hlen += getth_off(*((struct tcphdr *)&((char *)ip)[hlen])) << 2)
|
||||
ip = (struct ip_hdr *)nb->payload;
|
||||
hlen = IPH_HL(ip) << 2;
|
||||
if (IPH_PROTO(ip) >= MAX_SLOTS
|
||||
|| hlen + sizeof(struct tcp_hdr) > nb->len
|
||||
|| (hlen += TCPH_OFFSET(((struct tcp_hdr *)&((char *)ip)[hlen])) << 2)
|
||||
> nb->len
|
||||
|| hlen > MAX_HDR) {
|
||||
PPPDEBUG((LOG_INFO, "vj_uncompress_uncomp: bad cid=%d, hlen=%d buflen=%d\n",
|
||||
ip->ip_p, hlen, nb->len));
|
||||
PPPDEBUG(LOG_INFO, ("vj_uncompress_uncomp: bad cid=%d, hlen=%d buflen=%d\n",
|
||||
IPH_PROTO(ip), hlen, nb->len));
|
||||
comp->flags |= VJF_TOSS;
|
||||
INCR(vjs_errorin);
|
||||
return -1;
|
||||
}
|
||||
cs = &comp->rstate[comp->last_recv = ip->ip_p];
|
||||
cs = &comp->rstate[comp->last_recv = IPH_PROTO(ip)];
|
||||
comp->flags &=~ VJF_TOSS;
|
||||
ip->ip_p = IPPROTO_TCP;
|
||||
IPH_PROTO_SET(ip, IP_PROTO_TCP);
|
||||
BCOPY(ip, &cs->cs_ip, hlen);
|
||||
cs->cs_hlen = hlen;
|
||||
cs->cs_hlen = (u_short)hlen;
|
||||
INCR(vjs_uncompressedin);
|
||||
return 0;
|
||||
}
|
||||
|
@ -472,7 +464,7 @@ int
|
|||
vj_uncompress_tcp(struct pbuf **nb, struct vjcompress *comp)
|
||||
{
|
||||
u_char *cp;
|
||||
struct tcphdr *th;
|
||||
struct tcp_hdr *th;
|
||||
struct cstate *cs;
|
||||
u_short *bp;
|
||||
struct pbuf *n0 = *nb;
|
||||
|
@ -488,7 +480,7 @@ vj_uncompress_tcp(struct pbuf **nb, struct vjcompress *comp)
|
|||
* If we have a good state index, clear the 'discard' flag.
|
||||
*/
|
||||
if (*cp >= MAX_SLOTS) {
|
||||
PPPDEBUG((LOG_INFO, "vj_uncompress_tcp: bad cid=%d\n", *cp));
|
||||
PPPDEBUG(LOG_INFO, ("vj_uncompress_tcp: bad cid=%d\n", *cp));
|
||||
goto bad;
|
||||
}
|
||||
|
||||
|
@ -501,63 +493,63 @@ vj_uncompress_tcp(struct pbuf **nb, struct vjcompress *comp)
|
|||
* explicit state index, we have to toss the packet.
|
||||
*/
|
||||
if (comp->flags & VJF_TOSS) {
|
||||
PPPDEBUG((LOG_INFO, "vj_uncompress_tcp: tossing\n"));
|
||||
PPPDEBUG(LOG_INFO, ("vj_uncompress_tcp: tossing\n"));
|
||||
INCR(vjs_tossed);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
cs = &comp->rstate[comp->last_recv];
|
||||
hlen = getip_hl(cs->cs_ip) << 2;
|
||||
th = (struct tcphdr *)&((u_char *)&cs->cs_ip)[hlen];
|
||||
th->th_sum = htons((*cp << 8) | cp[1]);
|
||||
hlen = IPH_HL(&cs->cs_ip) << 2;
|
||||
th = (struct tcp_hdr *)&((u_char *)&cs->cs_ip)[hlen];
|
||||
th->chksum = htons((*cp << 8) | cp[1]);
|
||||
cp += 2;
|
||||
if (changes & TCP_PUSH_BIT) {
|
||||
th->th_flags |= TCP_PSH;
|
||||
TCPH_SET_FLAG(th, TCP_PSH);
|
||||
} else {
|
||||
th->th_flags &=~ TCP_PSH;
|
||||
TCPH_UNSET_FLAG(th, TCP_PSH);
|
||||
}
|
||||
|
||||
switch (changes & SPECIALS_MASK) {
|
||||
case SPECIAL_I:
|
||||
{
|
||||
register u32_t i = ntohs(cs->cs_ip.ip_len) - cs->cs_hlen;
|
||||
register u32_t i = ntohs(IPH_LEN(&cs->cs_ip)) - cs->cs_hlen;
|
||||
/* some compilers can't nest inline assembler.. */
|
||||
tmp = ntohl(th->th_ack) + i;
|
||||
th->th_ack = htonl(tmp);
|
||||
tmp = ntohl(th->th_seq) + i;
|
||||
th->th_seq = htonl(tmp);
|
||||
tmp = ntohl(th->ackno) + i;
|
||||
th->ackno = htonl(tmp);
|
||||
tmp = ntohl(th->seqno) + i;
|
||||
th->seqno = htonl(tmp);
|
||||
}
|
||||
break;
|
||||
|
||||
case SPECIAL_D:
|
||||
/* some compilers can't nest inline assembler.. */
|
||||
tmp = ntohl(th->th_seq) + ntohs(cs->cs_ip.ip_len) - cs->cs_hlen;
|
||||
th->th_seq = htonl(tmp);
|
||||
tmp = ntohl(th->seqno) + ntohs(IPH_LEN(&cs->cs_ip)) - cs->cs_hlen;
|
||||
th->seqno = htonl(tmp);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (changes & NEW_U) {
|
||||
th->th_flags |= TCP_URG;
|
||||
DECODEU(th->th_urp);
|
||||
TCPH_SET_FLAG(th, TCP_URG);
|
||||
DECODEU(th->urgp);
|
||||
} else {
|
||||
th->th_flags &=~ TCP_URG;
|
||||
TCPH_UNSET_FLAG(th, TCP_URG);
|
||||
}
|
||||
if (changes & NEW_W) {
|
||||
DECODES(th->th_win);
|
||||
DECODES(th->wnd);
|
||||
}
|
||||
if (changes & NEW_A) {
|
||||
DECODEL(th->th_ack);
|
||||
DECODEL(th->ackno);
|
||||
}
|
||||
if (changes & NEW_S) {
|
||||
DECODEL(th->th_seq);
|
||||
DECODEL(th->seqno);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (changes & NEW_I) {
|
||||
DECODES(cs->cs_ip.ip_id);
|
||||
DECODES(cs->cs_ip._id);
|
||||
} else {
|
||||
cs->cs_ip.ip_id = ntohs(cs->cs_ip.ip_id) + 1;
|
||||
cs->cs_ip.ip_id = htons(cs->cs_ip.ip_id);
|
||||
IPH_ID_SET(&cs->cs_ip, ntohs(IPH_ID(&cs->cs_ip)) + 1);
|
||||
IPH_ID_SET(&cs->cs_ip, htons(IPH_ID(&cs->cs_ip)));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -571,27 +563,27 @@ vj_uncompress_tcp(struct pbuf **nb, struct vjcompress *comp)
|
|||
* We must have dropped some characters (crc should detect
|
||||
* this but the old slip framing won't)
|
||||
*/
|
||||
PPPDEBUG((LOG_INFO, "vj_uncompress_tcp: head buffer %d too short %d\n",
|
||||
PPPDEBUG(LOG_INFO, ("vj_uncompress_tcp: head buffer %d too short %d\n",
|
||||
n0->len, vjlen));
|
||||
goto bad;
|
||||
}
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
tmp = n0->tot_len - vjlen + cs->cs_hlen;
|
||||
cs->cs_ip.ip_len = htons(tmp);
|
||||
IPH_LEN_SET(&cs->cs_ip, htons((u_short)tmp));
|
||||
#else
|
||||
cs->cs_ip.ip_len = htons(n0->tot_len - vjlen + cs->cs_hlen);
|
||||
IPH_LEN_SET(&cs->cs_ip, htons(n0->tot_len - vjlen + cs->cs_hlen));
|
||||
#endif
|
||||
|
||||
/* recompute the ip header checksum */
|
||||
bp = (u_short *) &cs->cs_ip;
|
||||
cs->cs_ip.ip_sum = 0;
|
||||
IPH_CHKSUM_SET(&cs->cs_ip, 0);
|
||||
for (tmp = 0; hlen > 0; hlen -= 2) {
|
||||
tmp += *bp++;
|
||||
}
|
||||
tmp = (tmp & 0xffff) + (tmp >> 16);
|
||||
tmp = (tmp & 0xffff) + (tmp >> 16);
|
||||
cs->cs_ip.ip_sum = (u_short)(~tmp);
|
||||
IPH_CHKSUM_SET(&cs->cs_ip, (u_short)(~tmp));
|
||||
|
||||
/* Remove the compressed header and prepend the uncompressed header. */
|
||||
if(pbuf_header(n0, -((s16_t)(vjlen)))) {
|
||||
|
@ -606,7 +598,7 @@ vj_uncompress_tcp(struct pbuf **nb, struct vjcompress *comp)
|
|||
|
||||
np = pbuf_alloc(PBUF_RAW, n0->len + cs->cs_hlen, PBUF_POOL);
|
||||
if(!np) {
|
||||
PPPDEBUG((LOG_WARNING, "vj_uncompress_tcp: realign failed\n"));
|
||||
PPPDEBUG(LOG_WARNING, ("vj_uncompress_tcp: realign failed\n"));
|
||||
goto bad;
|
||||
}
|
||||
|
||||
|
@ -636,7 +628,7 @@ vj_uncompress_tcp(struct pbuf **nb, struct vjcompress *comp)
|
|||
LWIP_ASSERT("vj_uncompress_tcp: cs->cs_hlen <= PBUF_POOL_BUFSIZE", cs->cs_hlen <= PBUF_POOL_BUFSIZE);
|
||||
np = pbuf_alloc(PBUF_RAW, cs->cs_hlen, PBUF_POOL);
|
||||
if(!np) {
|
||||
PPPDEBUG((LOG_WARNING, "vj_uncompress_tcp: prepend failed\n"));
|
||||
PPPDEBUG(LOG_WARNING, ("vj_uncompress_tcp: prepend failed\n"));
|
||||
goto bad;
|
||||
}
|
||||
pbuf_cat(np, n0);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Definitions for tcp compression routines.
|
||||
*
|
||||
* $Id: vj.h,v 1.5 2007/12/19 20:47:23 fbernon Exp $
|
||||
* $Id: vj.h,v 1.7 2010/02/22 17:52:09 goldsimon Exp $
|
||||
*
|
||||
* Copyright (c) 1989 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
|
@ -25,7 +25,8 @@
|
|||
#ifndef VJ_H
|
||||
#define VJ_H
|
||||
|
||||
#include "vjbsdhdr.h"
|
||||
#include "lwip/ip.h"
|
||||
#include "lwip/tcp_impl.h"
|
||||
|
||||
#define MAX_SLOTS 16 /* must be > 2 and < 256 */
|
||||
#define MAX_HDR 128
|
||||
|
@ -108,7 +109,7 @@ struct cstate {
|
|||
u_char cs_filler;
|
||||
union {
|
||||
char csu_hdr[MAX_HDR];
|
||||
struct ip csu_ip; /* ip/tcp hdr from most recent packet */
|
||||
struct ip_hdr csu_ip; /* ip/tcp hdr from most recent packet */
|
||||
} vjcs_u;
|
||||
};
|
||||
#define cs_ip vjcs_u.csu_ip
|
||||
|
|
|
@ -88,7 +88,7 @@ struct slipif_priv {
|
|||
* @return always returns ERR_OK since the serial layer does not provide return values
|
||||
*/
|
||||
err_t
|
||||
slipif_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr)
|
||||
slipif_output(struct netif *netif, struct pbuf *p, ip_addr_t *ipaddr)
|
||||
{
|
||||
struct slipif_priv *priv;
|
||||
struct pbuf *q;
|
||||
|
|
Loading…
Reference in a new issue