[syslinux:lwip] lwip: now to the point we can make a TCP connection...

syslinux-bot for H. Peter Anvin hpa at zytor.com
Fri Apr 22 20:05:44 PDT 2011


Commit-ID:  699cc38092333d7326cbf32ae862d30c59f2c502
Gitweb:     http://syslinux.zytor.com/commit/699cc38092333d7326cbf32ae862d30c59f2c502
Author:     H. Peter Anvin <hpa at zytor.com>
AuthorDate: Wed, 16 Sep 2009 17:48:26 -0700
Committer:  Eric W. Biederman <ebiederm at xmission.com>
CommitDate: Tue, 12 Apr 2011 14:40:53 -0700

lwip: now to the point we can make a TCP connection...

lwip is now functional enough that TCP and DNS seem to work.  More
tests still need to be done, though.

Signed-off-by: H. Peter Anvin <hpa at zytor.com>
Signed-off-by: Eric W. Biederman <ebiederm at xmission.com>


---
 core/fs/pxe/pxe.c                |   80 ++++++++++++++++++++++++++++++-
 core/lwip/src/include/lwipopts.h |    9 +++-
 core/lwip/src/netif/undiif.c     |  100 ++++++++++++++++++++++++-------------
 3 files changed, 152 insertions(+), 37 deletions(-)

diff --git a/core/fs/pxe/pxe.c b/core/fs/pxe/pxe.c
index ebf3dc1..14a767d 100644
--- a/core/fs/pxe/pxe.c
+++ b/core/fs/pxe/pxe.c
@@ -8,6 +8,7 @@
 #include "pxe.h"
 #if 1
 #include "lwip/api.h"
+#include "lwip/dns.h"
 #endif
 
 static uint16_t real_base_mem;	   /* Amount of DOS memory after freeing */
@@ -980,6 +981,7 @@ static void gpxe_init(void)
     has_gpxe = (~gpxe_funcs & 0x4b) == 0;
 }
 
+#if 0
 /*
  * Initialize UDP stack
  *
@@ -996,7 +998,67 @@ static void udp_init(void)
 	kaboom();
     }
 }
+#endif
+
+static void lwip_test(void)
+{
+    err_t err;
+    struct ip_addr ip;
+    struct netconn *conn;
+    char header_buf[512];
+    int header_len;
+    static const char host_str[] = "www.zytor.com";
+    struct netbuf *buf;
+
+    /* Test the lwIP stack by trying to open a HTTP connection... */
+    printf("Starting lwIP test...\n");
+    err = netconn_gethostbyname(host_str, &ip);
+    printf("Gethostbyname: ip = %d.%d.%d.%d, err = %d\n",
+	   ((uint8_t *)&ip)[0],
+	   ((uint8_t *)&ip)[1],
+	   ((uint8_t *)&ip)[2],
+	   ((uint8_t *)&ip)[3],
+	   err);
+
+    conn = netconn_new(NETCONN_TCP);
+    printf("netconn_new returned %p\n", conn);
+
+    err = netconn_connect(conn, &ip, 80);
+    printf("netconn_connect error %d\n", err);
+
+    header_len = snprintf(header_buf, sizeof header_buf,
+			  "GET /lwip_test HTTP/1.0\r\n"
+			  "Host: %s\r\n"
+			  "\r\n",
+			  host_str);
+
+    err = netconn_write(conn, header_buf, header_len, NETCONN_NOCOPY);
+    printf("netconn_write error %d\n", err);
+    for (;;) {
+	void *data;
+	char *p;
+	u16_t len;
+
+	buf = netconn_recv(conn);
+	if (!buf)
+	    break;
 
+	netbuf_data(buf, &data, &len);
+
+	p = data;
+	while (len--)
+	    putchar (*p++);
+
+	netbuf_delete(buf);
+    }
+	
+    printf("\n[End transmission]\n");
+
+    netconn_disconnect(conn);
+
+    for(;;)
+	asm volatile("hlt");
+}
 
 /*
  * Network-specific initialization
@@ -1005,6 +1067,7 @@ static void network_init(void)
 {
     struct bootp_t *bp = (struct bootp_t *)trackbuf;
     int pkt_len;
+    int i;
 
     *LocalDomain = 0;   /* No LocalDomain received */
 
@@ -1060,13 +1123,28 @@ static void network_init(void)
     if ((DHCPMagic & 1) == 0)
         DHCPMagic = 0;
 
-#if 1
+#if 1					/* new stuff */
+    dprintf("undi_tcpip_start...\n");
     extern err_t undi_tcpip_start(struct ip_addr *ipaddr,
 				  struct ip_addr *netmask,
 				  struct ip_addr *gw);
     undi_tcpip_start((struct ip_addr *)&IPInfo.myip,
 	    	     (struct ip_addr *)&IPInfo.netmask,
 		     (struct ip_addr *)&IPInfo.gateway);
+
+    for (i = 0; i < DNS_MAX_SERVERS; i++) {
+	/* Transfer the DNS information to lwip */
+	dprintf("DNS server %d = %d.%d.%d.%d\n",
+	       i,
+	       ((uint8_t *)&dns_server[i])[0],
+	       ((uint8_t *)&dns_server[i])[1],
+	       ((uint8_t *)&dns_server[i])[2],
+	       ((uint8_t *)&dns_server[i])[3]);
+	dns_setserver(i, (struct ip_addr *)&dns_server[i]);
+    }
+
+    dprintf("lwip_test...\n");
+    lwip_test();
 #else
     udp_init();
 #endif
diff --git a/core/lwip/src/include/lwipopts.h b/core/lwip/src/include/lwipopts.h
index 53d26e9..915d232 100644
--- a/core/lwip/src/include/lwipopts.h
+++ b/core/lwip/src/include/lwipopts.h
@@ -2,6 +2,13 @@
 #define __LWIPOPTS_H__
 
 #define SYS_LIGHTWEIGHT_PROT	1
-#define LWIP_NETIF_API 1
+#define LWIP_NETIF_API		1
+#define LWIP_DNS		1
+
+#define DNS_TABLE_SIZE		16
+#define DNS_MAX_SERVERS		4
+#define TCP_WND			32768
+#define TCP_MSS			4096
+#define TCP_SND_BUF		4096
 
 #endif /* __LWIPOPTS_H__ */
diff --git a/core/lwip/src/netif/undiif.c b/core/lwip/src/netif/undiif.c
index 4bfd48e..c5f9c9d 100644
--- a/core/lwip/src/netif/undiif.c
+++ b/core/lwip/src/netif/undiif.c
@@ -80,14 +80,38 @@ static struct netif undi_netif;
  * @param netif the already initialized lwip network interface structure
  *        for this undiif
  */
+extern uint8_t pxe_irq_vector;
+extern void pxe_isr(void);
+
+/* XXX: move this somewhere sensible */
+static void install_irq_vector(uint8_t irq, void (*isr)(void))
+{
+  unsigned int vec;
+
+  if (irq < 8)
+    vec = irq + 0x08;
+  else if (irq < 16)
+    vec = (irq - 8) + 0x70;
+  else
+    return;			/* ERROR */
+  
+  *(uint32_t *)(vec << 2) = (uint32_t)isr;
+}
+
 static void
 low_level_init(struct netif *netif)
 {
   static __lowmem t_PXENV_UNDI_GET_INFORMATION undi_info;
+  static __lowmem t_PXENV_UNDI_OPEN undi_open;
+  int i;
   /* struct undiif *undiif = netif->state; */
 
   pxe_call(PXENV_UNDI_GET_INFORMATION, &undi_info);
 
+  dprintf("UNDI: baseio %04x int %d MTU %d type %d\n",
+	 undi_info.BaseIo, undi_info.IntNumber, undi_info.MaxTranUnit,
+	 undi_info.HwType);
+
   /* set MAC hardware address length */
   netif->hwaddr_len = undi_info.HwAddrLen;
 
@@ -97,11 +121,22 @@ low_level_init(struct netif *netif)
   /* maximum transfer unit */
   netif->mtu = undi_info.MaxTranUnit;
 
+  dprintf("UNDI: hw address");
+  for (i = 0; i < netif->hwaddr_len; i++)
+      dprintf("%c%02x", i ? ':' : ' ', (uint8_t)netif->hwaddr[i]);
+  dprintf("\n");
+
   /* device capabilities */
   /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
   netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
 
-  /* Do whatever else is needed to initialize interface. */
+  /* Install the interrupt vector */
+  pxe_irq_vector = undi_info.IntNumber;
+  install_irq_vector(pxe_irq_vector, pxe_isr);
+
+  /* Open the UNDI stack - you'd think the BC would have done this... */
+  undi_open.PktFilter = 0x0003;	/* FLTR_DIRECTED | FLTR_BRDCST */
+  pxe_call(PXENV_UNDI_OPEN, &undi_open);
 }
 
 /**
@@ -152,16 +187,17 @@ low_level_output(struct netif *netif, struct pbuf *p)
     r += q->len;
   }
 
+  //printf("undiif_output, len = %d ", r - pkt_buf);
+
   do {
       memset(&pxe, 0, sizeof pxe);
 
       pxe.xmit.Protocol = 0;	/* XXX: P_UNKNOWN: MAC layer */
       pxe.xmit.XmitFlag = !memcmp(pkt_buf, eth_broadcast, sizeof eth_broadcast);
-      pxe.xmit.DestAddr = FAR_PTR(pkt_buf);
+      pxe.xmit.DestAddr = FAR_PTR(&pxe.tbd); /* This is what gPXE does?? */
       pxe.xmit.TBD = FAR_PTR(&pxe.tbd);
       pxe.tbd.ImmedLength = r - pkt_buf;
       pxe.tbd.Xmit = FAR_PTR(pkt_buf);
-      pxe.tbd.DataBlkCount = 0;
 
       pxe_call(PXENV_UNDI_TRANSMIT, &pxe.xmit);
   } while (pxe.xmit.Status == PXENV_STATUS_OUT_OF_RESOURCES);
@@ -202,6 +238,8 @@ low_level_input(t_PXENV_UNDI_ISR *isr)
      variable. */
   len = isr->FrameLength;
 
+  //printf("undiif_input, len = %d\n", len);
+
 #if ETH_PAD_SIZE
   len += ETH_PAD_SIZE; /* allow room for Ethernet padding */
 #endif
@@ -323,45 +361,15 @@ void undiif_input(t_PXENV_UNDI_ISR *isr)
  *         ERR_MEM if private data couldn't be allocated
  *         any other err_t on error
  */
-extern uint8_t pxe_irq_vector;
-extern void pxe_isr(void);
-
-/* XXX: move this somewhere sensible */
-static void install_irq_vector(uint8_t irq, void (*isr)(void))
-{
-  unsigned int vec;
-
-  if (irq < 8)
-    vec = irq + 0x08;
-  else if (irq < 16)
-    vec = (irq - 8) + 0x70;
-  else
-    return;			/* ERROR */
-  
-  *(uint32_t *)(vec << 2) = (uint32_t)isr;
-}
-
 static err_t
 undiif_init(struct netif *netif)
 {
-  static __lowmem t_PXENV_UNDI_GET_INFORMATION undi_info;
-
   LWIP_ASSERT("netif != NULL", (netif != NULL));
 #if LWIP_NETIF_HOSTNAME
   /* Initialize interface hostname */
   netif->hostname = "undi";
 #endif /* LWIP_NETIF_HOSTNAME */
 
-  pxe_call(PXENV_UNDI_GET_INFORMATION, &undi_info);
-
-  dprintf("UNDI: baseio %04x int %d MTU %d type %d\n",
-	  undi_info.BaseIo, undi_info.IntNumber, undi_info.MaxTranUnit,
-	  undi_info.HwType);
-
-  /* Install the interrupt vector */
-  pxe_irq_vector = undi_info.IntNumber;
-  install_irq_vector(pxe_irq_vector, pxe_isr);
-
   /*
    * Initialize the snmp variables and counters inside the struct netif.
    * The last argument should be replaced with your link speed, in units
@@ -389,11 +397,33 @@ err_t undi_tcpip_start(struct ip_addr *ipaddr,
 		       struct ip_addr *netmask,
 		       struct ip_addr *gw)
 {
+  err_t err;
+
   // Start the TCP/IP thread & init stuff
   tcpip_init(NULL, NULL);
 
   // This should be done *after* the threading system and receive thread
   // have both been started.
-  return netifapi_netif_add(&undi_netif, ipaddr, netmask, gw, NULL,
-			    undiif_init, ethernet_input);
+  dprintf("undi_netif: ip %d.%d.%d.%d netmask %d.%d.%d.%d gw %d.%d.%d.%d\n",
+	 ((uint8_t *)ipaddr)[0],
+	 ((uint8_t *)ipaddr)[1],
+	 ((uint8_t *)ipaddr)[2],
+	 ((uint8_t *)ipaddr)[3],
+	 ((uint8_t *)netmask)[0],
+	 ((uint8_t *)netmask)[1],
+	 ((uint8_t *)netmask)[2],
+	 ((uint8_t *)netmask)[3],
+	 ((uint8_t *)gw)[0],
+	 ((uint8_t *)gw)[1],
+	 ((uint8_t *)gw)[2],
+	 ((uint8_t *)gw)[3]);
+  err = netifapi_netif_add(&undi_netif, ipaddr, netmask, gw, NULL,
+			   undiif_init, ethernet_input);
+  if (err)
+    return err;
+
+  netif_set_up(&undi_netif);
+  netif_set_default(&undi_netif); /* Make this interface the default route */
+
+  return ERR_OK;
 }



More information about the Syslinux-commits mailing list