- Upgrade to the latest version of lwIP (1.40)

svn path=/branches/GSoC_2011/TcpIpDriver/; revision=52655
This commit is contained in:
Claudiu Mihail 2011-07-12 14:06:50 +00:00
parent b5a8722b5e
commit 11a025ade9
62 changed files with 3028 additions and 2728 deletions

View file

@ -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 */
}
/**

View file

@ -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

View file

@ -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 */
};
/**

View file

@ -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;

View file

@ -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"

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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).

View file

@ -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);

View file

@ -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
/*

View file

@ -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 */

View file

@ -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;
}

View file

@ -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 {

View file

@ -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"
/**

View file

@ -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);

View file

@ -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), &current_iphdr_src) &&
ip_addr_cmp(&(pcb->local_ip), &current_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), &current_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), &current_iphdr_src) &&
ip_addr_cmp(&(pcb->local_ip), &current_iphdr_dest))
{
ip_addr_cmp(&(pcb->local_ip), &current_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), &current_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), &current_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"));
}
/**

View file

@ -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

View file

@ -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"

View file

@ -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;

View file

@ -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 */
};

View file

@ -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*/

View file

@ -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

View file

@ -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.

View file

@ -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

View file

@ -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)*/

View file

@ -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__ */

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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__ */

View file

@ -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
/**

View file

@ -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 */

View file

@ -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

View file

@ -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

View file

@ -18,6 +18,8 @@
#define ARP_QUEUEING 0
#define ETH_PAD_SIZE 2
#define IP_FORWARD 0
#define IP_REASS_MAX_PBUFS 0xFFFFFFFF

View file

@ -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

View file

@ -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);

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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;
}
}

View file

@ -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 *);

View file

@ -57,9 +57,7 @@
#include "randm.h"
#include "magic.h"
/***********************************/
/*** PUBLIC FUNCTION DEFINITIONS ***/
/***********************************/
/*
* magicInit - Initialize the magic number generator.
*

View file

@ -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);

View file

@ -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 */

View file

@ -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 */

View file

@ -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

View file

@ -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 */

View file

@ -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;
}

View file

@ -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 */

View file

@ -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")); */
}
/*

View file

@ -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);

View file

@ -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

View file

@ -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;