]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Adaptation for the new protocols and interface structs.
authorManoel R. Abranches <mrabran@br.ibm.com>
Mon, 21 Jun 2010 22:15:45 +0000 (19:15 -0300)
committerManoel R. Abranches <mrabran@br.ibm.com>
Mon, 21 Jun 2010 22:15:45 +0000 (19:15 -0300)
implementation of receive in the protocols.
Also all unwanted packets are discarded.

commands/net.c
include/grub/net.h
net/ethernet.c
net/interface.c
net/ip.c
net/netbuff.c
net/protocol.c
net/tftp.c
net/udp.c

index 288ba4c2a2df6506924c9690c3c78dde6ef72f71..b8ceb36f4c665a10b980b2c0aea3dae4ec105722 100644 (file)
 #include <grub/command.h>
 
 struct grub_net_route *grub_net_routes = NULL;
-struct grub_net_network_level_interface *grub_net_network_level_interfaces = NULL;
+struct grub_net_network_layer_interface *grub_net_network_layer_interfaces = NULL;
 struct grub_net_card *grub_net_cards = NULL;
-struct grub_net_network_level_protocol *grub_net_network_level_protocols = NULL;
+struct grub_net_network_layer_protocol *grub_net_network_layer_protocols = NULL;
 
 grub_err_t
-grub_net_resolve_address (struct grub_net_network_level_protocol **prot,
+grub_net_resolve_address (struct grub_net_network_layer_protocol **prot,
                          char *name,
-                         grub_net_network_level_address_t *addr)
+                         grub_net_network_layer_address_t *addr)
 {
   FOR_NET_NETWORK_LEVEL_PROTOCOLS (*prot)
     {
@@ -50,15 +50,15 @@ grub_net_resolve_address (struct grub_net_network_level_protocol **prot,
 }
 
 grub_err_t
-grub_net_route_address (grub_net_network_level_address_t addr,
-                       grub_net_network_level_address_t *gateway,
-                       struct grub_net_network_level_interface **interf)
+grub_net_route_address (grub_net_network_layer_address_t addr,
+                       grub_net_network_layer_address_t *gateway,
+                       struct grub_net_network_layer_interface **interf)
 {
   struct grub_net_route *route;
   int depth = 0;
   int routecnt = 0;
-  struct grub_net_network_level_protocol *prot = NULL;
-  grub_net_network_level_address_t curtarget = addr;
+  struct grub_net_network_layer_protocol *prot = NULL;
+  grub_net_network_layer_address_t curtarget = addr;
 
   *gateway = addr;
 
@@ -96,7 +96,7 @@ static grub_err_t
 grub_cmd_deladdr (struct grub_command *cmd __attribute__ ((unused)),
                  int argc, char **args)
 {
-  struct grub_net_network_level_interface *inter;
+  struct grub_net_network_layer_interface *inter;
 
   if (argc != 4)
     return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
@@ -107,8 +107,8 @@ grub_cmd_deladdr (struct grub_command *cmd __attribute__ ((unused)),
   if (inter == NULL)
     return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("address not found"));
 
-  inter->protocol->fini (inter);
-  grub_net_network_level_interface_unregister (inter);
+//  inter->protocol->fini (inter);
+  grub_net_network_layer_interface_unregister (inter);
   grub_free (inter->name);
   grub_free (inter);
 
@@ -120,10 +120,10 @@ grub_cmd_addaddr (struct grub_command *cmd __attribute__ ((unused)),
                  int argc, char **args)
 {
   struct grub_net_card *card;
-  struct grub_net_network_level_protocol *prot;
+  struct grub_net_network_layer_protocol *prot;
   grub_err_t err;
-  grub_net_network_level_address_t addr;
-  struct grub_net_network_level_interface *inter;
+  grub_net_network_layer_address_t addr;
+  struct grub_net_network_layer_interface *inter;
 
   if (argc != 4)
     return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("four arguments expected"));
@@ -154,14 +154,14 @@ grub_cmd_addaddr (struct grub_command *cmd __attribute__ ((unused)),
   grub_memcpy (&(inter->address), &addr, sizeof (inter->address));
   inter->card = card;
 
-  err = prot->init (inter);
// err = prot->init (inter);
   if (err)
     {
       grub_free (inter->name);
       grub_free (inter);
       return err;
     }
-  grub_net_network_level_interface_register (inter);
+  grub_net_network_layer_interface_register (inter);
 
   return GRUB_ERR_NONE;
 }
@@ -192,7 +192,7 @@ static grub_err_t
 grub_cmd_addroute (struct grub_command *cmd __attribute__ ((unused)),
                  int argc, char **args)
 {
-  struct grub_net_network_level_protocol *prot;
+  struct grub_net_network_layer_protocol *prot;
   struct grub_net_route *route;
 
   if (argc < 3)
@@ -247,7 +247,7 @@ grub_cmd_addroute (struct grub_command *cmd __attribute__ ((unused)),
     }
   else
     {
-      struct grub_net_network_level_interface *inter;
+      struct grub_net_network_layer_interface *inter;
       route->is_gateway = 0;
 
       FOR_NET_NETWORK_LEVEL_INTERFACES (inter)
index f021f0e9c24e53f95839f081f00531c114dd5d87..abb8a316734078f96dba4f14f626f1b589323e69 100644 (file)
 #include <grub/err.h>
 #include <grub/list.h>
 #include <grub/net/netbuff.h>
+#include <grub/net/type_net.h>
+#include <grub/net/protocol.h>
 
 struct grub_net_card;
 
-typedef enum
-{
- GRUB_NET_TFTP_ID,
- GRUB_NET_UDP_ID,
- GRUB_NET_IPV4_ID,
- GRUB_NET_IPV6_ID,
- GRUB_NET_ETHERNET_ID,
- GRUB_NET_ARP_ID,
- GRUB_NET_DHCP_ID
-
-}protocol_type_t;
 
 struct grub_net_card_driver
 {
@@ -66,76 +57,36 @@ struct grub_net_card
   void *data;
 };
 
-struct grub_net_network_level_interface;
-
-typedef union grub_net_network_level_address
-{
-  grub_uint32_t ipv4;
-} grub_net_network_level_netaddress_t;
-
-typedef union grub_net_network_level_netaddress
-{
-  struct {
-    grub_uint32_t base;
-    int masksize; 
-  } ipv4;
-} grub_net_network_level_address_t;
+//struct grub_net_network_layer_interface;
 
-typedef enum grub_network_level_protocol_id 
+struct grub_net_network_layer_interface
 {
-  GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4
-} grub_network_level_protocol_id_t;
-
-struct grub_net_network_level_interface;
-
-struct grub_net_network_level_protocol
-{
-  struct grub_net_network_level_protocol *next;
-  char *name;
-  grub_network_level_protocol_id_t id;
-  grub_err_t (*ntoa) (char *name, grub_net_network_level_address_t *addr);
-  char * (*aton) (union grub_net_network_level_address addr);
-  grub_err_t (*net_ntoa) (char *name,
-                         grub_net_network_level_netaddress_t *addr);
-  char * (*net_aton) (grub_net_network_level_netaddress_t addr);
-  int (* match_net) (grub_net_network_level_netaddress_t net,
-                    grub_net_network_level_address_t addr);
-  grub_err_t (*init) (struct grub_net_network_level_interface *dev);
-  grub_err_t (*fini) (struct grub_net_network_level_interface *dev);
-  grub_err_t (*send) (struct grub_net_network_level_interface *dev, void *buf,
-                     grub_size_t buflen);
-  grub_size_t (*recv) (struct grub_net_network_level_interface *dev, void *buf,
-                      grub_size_t buflen);  
-};
-
-struct grub_net_network_level_interface
-{
-  struct grub_net_network_level_interface *next;
+  struct grub_net_network_layer_interface *next;
   char *name;
   /* Underlying protocol.  */
-  struct grub_net_network_level_protocol *protocol;
+  struct grub_net_network_layer_protocol *protocol;
   struct grub_net_card *card;
-  union grub_net_network_level_address address;
+  union grub_net_network_layer_address address;
   void *data;
 };
 
 struct grub_net_route
 {
   struct grub_net_route *next;
-  grub_net_network_level_netaddress_t target;
+  grub_net_network_layer_netaddress_t target;
   char *name;
-  struct grub_net_network_level_protocol *prot;
+  struct grub_net_network_layer_protocol *prot;
   int is_gateway;
   union
   {
-    struct grub_net_network_level_interface *interface;
-    grub_net_network_level_address_t gw;
+    struct grub_net_network_layer_interface *interface;
+    grub_net_network_layer_address_t gw;
   };
 };
 
 struct grub_net_session;
 
-struct grub_net_session_level_protocol
+struct grub_net_session_layer_protocol
 {
   void (*close) (struct grub_net_session *session);
   grub_ssize_t (*recv) (struct grub_net_session *session, void *buf,
@@ -146,7 +97,7 @@ struct grub_net_session_level_protocol
 
 struct grub_net_session
 {
-  struct grub_net_session_level_protocol *protocol;
+  struct grub_net_session_layer_protocol *protocol;
   void *data;
 };
 
@@ -170,23 +121,23 @@ grub_net_session_recv (struct grub_net_session *session, void *buf,
   return session->protocol->recv (session, buf, size);
 }
 
-extern struct grub_net_network_level_interface *grub_net_network_level_interfaces;
+struct grub_net_network_layer_interface *grub_net_network_layer_interfaces;
 
 static inline void
-grub_net_network_level_interface_register (struct grub_net_network_level_interface *inter)
+grub_net_network_layer_interface_register (struct grub_net_network_layer_interface *inter)
 {
-  grub_list_push (GRUB_AS_LIST_P (&grub_net_network_level_interfaces),
+  grub_list_push (GRUB_AS_LIST_P (&grub_net_network_layer_interfaces),
                  GRUB_AS_LIST (inter));
 }
 
 static inline void
-grub_net_network_level_interface_unregister (struct grub_net_network_level_interface *inter)
+grub_net_network_layer_interface_unregister (struct grub_net_network_layer_interface *inter)
 {
-  grub_list_remove (GRUB_AS_LIST_P (&grub_net_network_level_interfaces),
+  grub_list_remove (GRUB_AS_LIST_P (&grub_net_network_layer_interfaces),
                    GRUB_AS_LIST (inter));
 }
 
-#define FOR_NET_NETWORK_LEVEL_INTERFACES(var) for (var = grub_net_network_level_interfaces; var; var = var->next)
+#define FOR_NET_NETWORK_LEVEL_INTERFACES(var) for (var = grub_net_network_layer_interfaces; var; var = var->next)
 
 extern struct grub_net_route *grub_net_routes;
 
@@ -224,28 +175,13 @@ grub_net_card_unregister (struct grub_net_card *card)
 
 #define FOR_NET_CARDS(var) for (var = grub_net_cards; var; var = var->next)
 
-extern struct grub_net_network_level_protocol *grub_net_network_level_protocols;
-
-static inline void
-grub_net_network_level_protocol_register (struct grub_net_network_level_protocol *prot)
-{
-  grub_list_push (GRUB_AS_LIST_P (&grub_net_network_level_protocols),
-                 GRUB_AS_LIST (prot));
-}
-
-static inline void
-grub_net_network_level_protocol_unregister (struct grub_net_network_level_protocol *prot)
-{
-  grub_list_remove (GRUB_AS_LIST_P (&grub_net_network_level_protocols),
-                   GRUB_AS_LIST (prot));
-}
 
-#define FOR_NET_NETWORK_LEVEL_PROTOCOLS(var) for ((var) = grub_net_network_level_protocols; (var); (var) = (var)->next)
+#define FOR_NET_NETWORK_LEVEL_PROTOCOLS(var) for ((var) = grub_net_network_layer_protocols; (var); (var) = (var)->next)
 
 static inline grub_err_t
-grub_net_resolve_address_in_protocol (struct grub_net_network_level_protocol *prot,
+grub_net_resolve_address_in_protocol (struct grub_net_network_layer_protocol *prot,
                                      char *name,
-                                     grub_net_network_level_address_t *addr)
+                                     grub_net_network_layer_address_t *addr)
 {
   return prot->ntoa (name, addr);
 }
@@ -254,14 +190,14 @@ struct grub_net_session *
 grub_net_open_tcp (char *address, grub_uint16_t port);
 
 grub_err_t
-grub_net_resolve_address (struct grub_net_network_level_protocol **prot,
+grub_net_resolve_address (struct grub_net_network_layer_protocol **prot,
                          char *name,
-                         grub_net_network_level_address_t *addr);
+                         grub_net_network_layer_address_t *addr);
 
 grub_err_t
-grub_net_route_address (grub_net_network_level_address_t addr,
-                       grub_net_network_level_address_t *gateway,
-                       struct grub_net_network_level_interface **interf);
+grub_net_route_address (grub_net_network_layer_address_t addr,
+                       grub_net_network_layer_address_t *gateway,
+                       struct grub_net_network_layer_interface **interf);
 
 
 #endif /* ! GRUB_NET_HEADER */
index 8c13966c1b3cec1db9fa00536568e74541245c0a..a4bdbff5b618c4664323ba42bf03d1572c4cc7b8 100644 (file)
@@ -5,51 +5,85 @@
 #include <grub/net/arp.h>
 #include <grub/net/ieee1275/interface.h>
 #include <grub/net/netbuff.h>
-#include <grub/net/protocol.h>
 #include <grub/net/interface.h>
+#include <grub/net.h>
 
 static grub_err_t 
-send_ethernet_packet (struct grub_net_interface *inf,struct grub_net_protstack *protstack __attribute__ ((unused))
-  ,struct grub_net_buff *nb)
+send_ethernet_packet (struct grub_net_network_layer_interface *inf __attribute__ ((unused)),
+   struct grub_net_network_link_interface *net_link_inf __attribute__ ((unused)) ,struct grub_net_buff *nb)
 {
 
-  struct etherhdr *eth;
-  grub_err_t err; 
-  
-  if((err = grub_netbuff_push (nb,sizeof(*eth)) ) != GRUB_ERR_NONE)
-    return err;
+  struct etherhdr *eth; 
+   
+  grub_netbuff_push (nb,sizeof(*eth));
   eth = (struct etherhdr *) nb->data; 
-  grub_memcpy (eth->src,inf->card->lla->addr,6 * sizeof (grub_uint8_t )); 
-  grub_memcpy (eth->dst,inf->lla->addr,6 * sizeof (grub_uint8_t ));
+  eth->dst[0] =0x00;
+  eth->dst[1] =0x11;
+  eth->dst[2] =0x25;
+  eth->dst[3] =0xca;
+  eth->dst[4] =0x1f;
+  eth->dst[5] =0x01;
+  eth->src[0] =0x0a;
+  eth->src[1] =0x11;
+  eth->src[2] =0xbd;
+  eth->src[3] =0xe3;
+  eth->src[4] =0xe3;
+  eth->src[5] =0x04;
+
   eth->type = 0x0800;
-  
-  return  inf->card->driver->send(inf->card,nb);
+
+  return  send_card_buffer(nb);  
+//  return  inf->card->driver->send(inf->card,nb);
 }
 
-static struct grub_net_protocol grub_ethernet_protocol =
+
+static grub_err_t 
+recv_ethernet_packet (struct grub_net_network_layer_interface *inf __attribute__ ((unused)),
+   struct grub_net_network_link_interface *net_link_inf __attribute__ ((unused)) ,struct grub_net_buff *nb)
 {
-  .name = "udp",
-  .send = send_ethernet_packet
+  struct etherhdr *eth;
+ while (1)
+ {
+   get_card_packet (nb);
+   eth = (struct etherhdr *) nb->data; 
+   /*change for grub_memcmp*/
+   if( eth->src[0] == 0x00 &&  eth->src[1] == 0x11 &&  eth->src[2] == 0x25 && 
+               eth->src[3] == 0xca &&  eth->src[4] == 0x1f &&  eth->src[5] == 0x01 && eth->type == 0x800)
+   {
+     //grub_printf("ethernet eth->dst %x:%x:%x:%x:%x:%x\n",eth->dst[0],
+       //     eth->dst[1],eth->dst[2],eth->dst[3],eth->dst[4],eth->dst[5]);
+    // grub_printf("ethernet eth->src %x:%x:%x:%x:%x:%x\n",eth->src[0],eth->src[1],
+      //      eth->src[2],eth->src[3],eth->src[4],eth->src[5]);
+     //grub_printf("ethernet eth->type 0x%x\n",eth->type);
+     //grub_printf("out from ethernet\n");
+     grub_netbuff_pull(nb,sizeof(*eth));
+     return 0;
+   }
+ }
+/*  - get ethernet header
+  - verify if the next layer is the desired one.
+     - if not. get another packet.
+  - remove ethernet header from buffer*/
+  return 0; 
+}
+
+
+static struct grub_net_link_layer_protocol grub_ethernet_protocol =
+{
+  .name = "ethernet",
+  .id = GRUB_NET_ETHERNET_ID,
+  .send = send_ethernet_packet,
+  .recv = recv_ethernet_packet 
 };
 
 void ethernet_ini(void)
 {
-  grub_protocol_register (&grub_ethernet_protocol);
+  grub_net_link_layer_protocol_register (&grub_ethernet_protocol);
 }
 
 void ethernet_fini(void)
 {
-  grub_protocol_unregister (&grub_ethernet_protocol);
+  grub_net_link_layer_protocol_unregister (&grub_ethernet_protocol);
 }
-/*
-int read_ethernet_packet(buffer,bufflen, int type)
-{
-  
-  struct etherhdr eth;
-  eth.type = 0;
-  get_card_buffer (&eth,sizeof (eth));
-  
 
 
-}*/
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..bacabf4cb95d3e6edcaf91df94753498412fe0c3 100644 (file)
@@ -0,0 +1,38 @@
+/*#include <grub/net/interface.h>
+
+#define INTERFACE_REGISTER_FUNCTIONS(layerprevious,layernext) \
+struct grub_net_##layername_layer_protocol *grub_net_##layername_layer_protocols;\
+\
+void grub_net_##layerprevious_##layernext_interface_register (struct grub_net_##layername_layer_protocol *prot)\
+{\
+  grub_list_push (GRUB_AS_LIST_P (&grub_net_##layername_layer_protocols),\
+                 GRUB_AS_LIST (prot));\
+}\
+\
+void grub_net_##layerprevious_##layernext_interface_unregister (struct grub_net_##layername_layer_protocol *prot);\
+{\
+  grub_list_remove (GRUB_AS_LIST_P (&grub_net_##layername_layer_protocols),\
+                   GRUB_AS_LIST (prot));\
+}\
+
+INTERFACE_REGISTER_FUNCTIONS("application","transport");
+INTERFACE_REGISTER_FUNCTIONS("transport","network");
+INTERFACE_REGISTER_FUNCTIONS("network","link");
+INTERFACE_REGISTER_FUNCTIONS("link");*/
+
+#include <grub/mm.h>
+#include <grub/net/interface.h>
+struct grub_net_protocol_stack *grub_net_protocol_stacks;
+struct grub_net_protocol_stack 
+  *grub_net_protocol_stack_get (char *name)
+{
+ struct grub_net_protocol_stack *p;
+
+  for (p = grub_net_protocol_stacks; p; p = p->next)
+  {
+    if (!grub_strcmp(p->name,name))
+      return p;
+  }
+  
+  return  NULL; 
+}
index 6fe58adb0ab82c325335852c535c124c2929345c..5eaa74f903685bdb63de9620173b26da63105acb 100644 (file)
--- a/net/ip.c
+++ b/net/ip.c
@@ -1,11 +1,11 @@
 #include <grub/net/ip.h>
-#include <grub/net/type_net.h>
 #include <grub/net/ieee1275/interface.h>
 #include <grub/misc.h>
 #include <grub/net/ethernet.h>
-#include <grub/net/netbuff.h>
-#include <grub/net/protocol.h>
 #include <grub/net/interface.h>
+#include <grub/net/type_net.h>
+#include <grub/net.h>
+#include <grub/net/netbuff.h>
 #include <grub/mm.h>
 
 struct grub_net_protocol *grub_ipv4_prot;
@@ -29,14 +29,14 @@ ipchksum(void *ipv, int len)
 
 
 static grub_err_t 
-send_ip_packet (struct grub_net_interface *inf, struct grub_net_protstack *protstack, struct grub_net_buff *nb  )
+send_ip_packet (struct grub_net_network_layer_interface *inf,
+       struct grub_net_transport_network_interface *trans_net_inf, struct grub_net_buff *nb  )
 {
   
   struct iphdr *iph;
-  grub_err_t err;
+  static int id = 0x2400; 
   
-  if((err = grub_netbuff_push(nb,sizeof(*iph)) ) != GRUB_ERR_NONE)
-    return err;    
+  grub_netbuff_push(nb,sizeof(*iph)); 
   iph = (struct iphdr *) nb->data;   
 
   /*FIXME dont work in litte endian machines*/
@@ -44,38 +44,64 @@ send_ip_packet (struct grub_net_interface *inf, struct grub_net_protstack *prots
   //grub_uint8_t hdrlen = sizeof (struct iphdr)/4;  
   iph->verhdrlen = (4<<4 | 5);
   iph->service = 0;
-  iph->len = sizeof(*iph);
-  iph->ident = 0x2b5f;
+  iph->len = nb->tail - nb-> data;//sizeof(*iph);
+  iph->ident = ++id;
   iph->frags = 0;
   iph->ttl = 0xff;
   iph->protocol = 0x11;
-  //grub_memcpy(&(iph->src) ,inf->card->ila->addr,inf->card->ila->len);
-  iph->src =  *((grub_uint32_t *)inf->card->ila->addr);
-  //grub_memcpy(&(iph->dest) ,inf->ila->addr,inf->ila->len);
-  iph->dest =  *((grub_uint32_t *)inf->ila->addr);
+  iph->src = (grub_uint32_t) bootp_pckt -> yiaddr; //inf->address.ipv4; // *((grub_uint32_t *)inf->card->ila->addr);
+  iph->dest = (grub_uint32_t) bootp_pckt -> siaddr;//inf->address.ipv4;// *((grub_uint32_t *)inf->ila->addr);
   
   iph->chksum = 0 ;
-  iph->chksum = ipchksum((void *)nb->head, sizeof(*iph));
+  iph->chksum = ipchksum((void *)nb->data, sizeof(*iph));
   
+  return trans_net_inf->inner_layer->link_prot->send(inf,trans_net_inf->inner_layer,nb);
+  //return protstack->next->prot->send(inf,protstack->next,nb); 
+}
+
+static grub_err_t 
+recv_ip_packet (struct grub_net_network_layer_interface *inf,
+       struct grub_net_transport_network_interface *trans_net_inf, struct grub_net_buff *nb  )
+{
   
-  return protstack->next->prot->send(inf,protstack->next,nb); 
+  struct iphdr *iph;
+  while (1)
+  {
+    trans_net_inf->inner_layer->link_prot->recv(inf,trans_net_inf->inner_layer,nb);
+    iph = (struct iphdr *) nb->data;
+    if (iph->dest == 0x0908eaaa && iph->src ==  0x0908ea92 && iph->protocol == 0x11)
+    {
+      grub_netbuff_pull(nb,sizeof(*iph));
+      return 0; 
+    }
+  }
+/*  grub_printf("ip.src 0x%x\n",iph->src);
+  grub_printf("ip.dst 0x%x\n",iph->dest);
+  grub_printf("ip.len 0x%x\n",iph->len);
+  grub_printf("ip.protocol 0x%x\n",iph->protocol);
+  */
+  /* - get ip header
+   - verify if is the next layer is correct
+   -*/
+  return 0; 
 }
 
-static struct grub_net_protocol grub_ipv4_protocol =
+static struct grub_net_network_layer_protocol grub_ipv4_protocol =
 {
  .name = "ipv4",
+ .id = GRUB_NET_IPV4_ID,
  .send = send_ip_packet,
- .recv = NULL
+ .recv = recv_ip_packet
 };
 
 void ipv4_ini(void)
 {
-  grub_protocol_register (&grub_ipv4_protocol);
+  grub_net_network_layer_protocol_register (&grub_ipv4_protocol);
 }
 
 void ipv4_fini(void)
 {
-  grub_protocol_unregister (&grub_ipv4_protocol);
+  grub_net_network_layer_protocol_unregister (&grub_ipv4_protocol);
 }
 
 /*
index 342260f435b90a89ca7aaeb87ceafdd4efb79bb2..136d55bc41a78db5a5c480243368b4b9ef42918d 100644 (file)
@@ -26,7 +26,7 @@ grub_err_t grub_netbuff_put (struct grub_net_buff *net_buff ,grub_size_t len)
 {
   net_buff->tail += len;
   if (net_buff->tail > net_buff->end)
-    return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of the packet range.");
+    return grub_error (GRUB_ERR_OUT_OF_RANGE, "put out of the packet range.");
   return GRUB_ERR_NONE; 
 }
 
@@ -34,15 +34,20 @@ grub_err_t grub_netbuff_unput (struct grub_net_buff *net_buff ,grub_size_t len)
 {
   net_buff->tail -= len;
   if (net_buff->tail < net_buff->head)
-    return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of the packet range.");
+    return grub_error (GRUB_ERR_OUT_OF_RANGE, "unput out of the packet range.");
   return GRUB_ERR_NONE; 
 }
 
 grub_err_t grub_netbuff_push (struct grub_net_buff *net_buff ,grub_size_t len)
 {
   net_buff->data -= len;
+/*  grub_printf("push len =%d\n",len);
+  grub_printf("pack->head =%x\n",(unsigned int)net_buff->head);
+  grub_printf("pack->data =%x\n",(unsigned int)net_buff->data);
+  grub_printf("pack->tail =%x\n",(unsigned int)net_buff->tail);
+  grub_printf("pack->end =%x\n",(unsigned int)net_buff->end);*/
   if (net_buff->data < net_buff->head)
-    return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of the packet range.");
+    return grub_error (GRUB_ERR_OUT_OF_RANGE, "push out of the packet range.");
   return GRUB_ERR_NONE; 
 }
 
@@ -50,7 +55,7 @@ grub_err_t grub_netbuff_pull (struct grub_net_buff *net_buff ,grub_size_t len)
 {
   net_buff->data += len;
   if (net_buff->data > net_buff->end)
-    return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of the packet range.");
+    return grub_error (GRUB_ERR_OUT_OF_RANGE, "pull out of the packet range.");
   return GRUB_ERR_NONE; 
 }
 
@@ -59,14 +64,36 @@ grub_err_t grub_netbuff_reserve (struct grub_net_buff *net_buff ,grub_size_t len
   net_buff->data += len;
   net_buff->tail += len;
   if ((net_buff->tail > net_buff->end) || (net_buff->data > net_buff->end))
-    return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of the packet range.");
+    return grub_error (GRUB_ERR_OUT_OF_RANGE, "reserve out of the packet range.");
   return GRUB_ERR_NONE; 
 }
 
-struct grub_net_buff * grub_netbuff_alloc ( grub_size_t len )
+struct grub_net_buff *grub_netbuff_alloc ( grub_size_t len )
 {
+  struct grub_net_buff *nb;
+  void *data;
+
   if (len < NETBUFFMINLEN) 
     len = NETBUFFMINLEN;
+  
   len = ALIGN_UP (len,NETBUFF_ALIGN);
-  return (struct grub_net_buff *) grub_memalign (len,NETBUFF_ALIGN); 
+  data = grub_memalign (len + sizeof (*nb),NETBUFF_ALIGN); 
+  nb = (struct grub_net_buff *) ((int)data + len); 
+  nb->head = nb->data = nb->tail = data;
+  nb->end = (char *) nb; 
+  
+  return nb; 
+}
+
+grub_err_t grub_netbuff_free (struct grub_net_buff *net_buff)
+{
+  grub_free (net_buff);
+  return 0;
+   
+}
+
+grub_err_t grub_netbuff_clear (struct grub_net_buff *net_buff)
+{
+  net_buff->data = net_buff->tail = net_buff->head;
+  return 0;
 }
index a6117dc2cbbfafcc9dc59896d1c0c77e72c48b44..05d4471d2189619207085ba8c4e174fbac522fda 100644 (file)
@@ -1,21 +1,37 @@
 #include <grub/net/protocol.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
 
-static grub_net_protocol_t grub_net_protocols;
-
-void grub_protocol_register (grub_net_protocol_t prot)
-{
-  prot->next = grub_net_protocols;
-  grub_net_protocols = prot;
+#define PROTOCOL_REGISTER_FUNCTIONS(layername) \
+struct grub_net_##layername##_layer_protocol *grub_net_##layername##_layer_protocols;\
+\
+void grub_net_##layername##_layer_protocol_register (struct grub_net_##layername##_layer_protocol *prot)\
+{\
+  grub_list_push (GRUB_AS_LIST_P (&grub_net_##layername##_layer_protocols),\
+                 GRUB_AS_LIST (prot));\
+}\
+\
+void grub_net_##layername##_layer_protocol_unregister (struct grub_net_##layername##_layer_protocol *prot)\
+{\
+  grub_list_remove (GRUB_AS_LIST_P (&grub_net_##layername##_layer_protocols),\
+                   GRUB_AS_LIST (prot));\
+}\
+\
+struct grub_net_##layername##_layer_protocol \
+  *grub_net_##layername##_layer_protocol_get (grub_net_protocol_id_t id)\
+{\
+ struct grub_net_##layername##_layer_protocol *p;\
+\
+  for (p = grub_net_##layername##_layer_protocols; p; p = p->next)\
+  {\
+    if (p->id == id)\
+      return p;\
+  }\
+  \
+  return  NULL; \
 }
 
-void grub_protocol_unregister (grub_net_protocol_t prot)
-{
-  grub_net_protocol_t *p, q;
-
-  for (p = &grub_net_protocols, q = *p; q; p = &(q->next), q = q->next)
-    if (q == prot)
-    {
-       *p = q->next;
-       break;
-    }
-}
+PROTOCOL_REGISTER_FUNCTIONS(application);
+PROTOCOL_REGISTER_FUNCTIONS(transport);
+PROTOCOL_REGISTER_FUNCTIONS(network);
+PROTOCOL_REGISTER_FUNCTIONS(link);
index 3f481fe58325edfd0ccb1ded812101879bd1fc16..1f04ef47ea1858b5297a2cfbd8e7b2dd1f5ddb3d 100644 (file)
@@ -4,42 +4,94 @@
 #include <grub/net/ip.h>
 #include <grub/net/ethernet.h>
 #include <grub/net/netbuff.h>
-#include <grub/net/protocol.h>
 #include <grub/net/ieee1275/interface.h>
 #include <grub/ieee1275/ieee1275.h>
-#include <grub/time.h>
 #include <grub/net/interface.h>
+#include <grub/net/type_net.h>
+#include <grub/net.h>
+#include <grub/mm.h>
+
+int block,rrq_count=0;
+struct {
+  int block_size;
+  int size;
+} tftp_file;
+
+
+char *get_tok_val(char **tok, char **val, char **str_opt,char *end);
+void process_option(char *tok, char *val);
+
+char *get_tok_val(char **tok, char **val,char **str_opt,char *end)
+{
+  char *p = *str_opt;
+  *tok = p;
+  p += grub_strlen(p) + 1;
+
+  if(p > end)
+    return NULL;
+
+  *val = p;
+  p += grub_strlen(p) + 1;
+  *str_opt = p;
+  return *tok;
+}
+
+void process_option(char *tok, char *val)
+{
+  if (!grub_strcmp(tok,"blksize"))
+  {
+    tftp_file.block_size = grub_strtoul (val,NULL,0);
+    return;
+  }
+
+  if (!grub_strcmp(tok,"tsize"))
+  {
+    tftp_file.size = grub_strtoul (val,NULL,0);
+    return;
+  }
+
+}
+
+//void tftp_open (char *options);
 
 /*send read request*/
 static grub_err_t 
-send_tftp_rr (struct grub_net_interface *inf, struct grub_net_protstack *protstack,struct grub_net_buff *nb)
+tftp_open (struct grub_net_network_layer_interface *inf __attribute((unused)),
+   struct grub_net_protocol_stack *protstack,struct grub_net_buff *nb, char *filename)
 {
-  /*Start TFTP header*/
-  
   struct tftphdr *tftph; 
   char *rrq;
   int rrqlen;
   int hdrlen; 
-  grub_err_t err; 
+  struct udp_interf *udp_interf;
+  struct grub_net_application_transport_interface *app_interface = (struct grub_net_application_transport_interface *) protstack->interface;
   
-  if((err = grub_netbuff_push (nb,sizeof(*tftph))) != GRUB_ERR_NONE)
-    return err;
+  app_interface = (struct grub_net_application_transport_interface *) protstack->interface; 
+  grub_netbuff_push (nb,sizeof (*tftph));
 
+  udp_interf = (struct udp_interf *) app_interface->data;
+  udp_interf->src = TFTP_CLIENT_PORT + rrq_count++; 
+  grub_printf("open tfpt udp_port = %d\n",udp_interf->src); 
+  udp_interf->dst = TFTP_SERVER_PORT; 
   tftph = (struct tftphdr *) nb->data; 
   
   rrq = (char *) tftph->u.rrq;
   rrqlen = 0;
   
   tftph->opcode = TFTP_RRQ;
-  grub_strcpy (rrq,inf->path);
-  rrqlen += grub_strlen (inf->path) + 1;
-  rrq +=  grub_strlen (inf->path) + 1;
+  grub_strcpy (rrq,filename);
+  rrqlen += grub_strlen (filename) + 1;
+  rrq +=  grub_strlen (filename) + 1;
   /*passar opcoes como parametro ou usar default?*/
   
   grub_strcpy (rrq,"octet");
   rrqlen += grub_strlen ("octet") + 1;
   rrq +=  grub_strlen ("octet") + 1;
 
+  //grub_strcpy (rrq,"netascii");
+  //rrqlen += grub_strlen ("netascii") + 1;
+  //rrq +=  grub_strlen ("netascii") + 1;
+
   grub_strcpy (rrq,"blksize");
   rrqlen += grub_strlen("blksize") + 1;
   rrq +=  grub_strlen ("blksize") + 1;
@@ -59,39 +111,146 @@ send_tftp_rr (struct grub_net_interface *inf, struct grub_net_protstack *protsta
  
   grub_netbuff_unput (nb,nb->tail - (nb->data+hdrlen)); 
 
-  return protstack->next->prot->send(inf,protstack->next,nb); 
+  app_interface->trans_prot->send (inf,protstack->interface,nb);
+  /*Receive OACK*/
+  return app_interface->app_prot->recv(inf,protstack,nb);
 }
 
-/*
-int send_tftp_ack(int block, int port){
+static grub_err_t 
+tftp_receive (struct grub_net_network_layer_interface *inf __attribute((unused)),
+   struct grub_net_protocol_stack *protstack,struct grub_net_buff *nb)
+{
+  struct tftphdr *tftph;
+  char *token,*value,*temp; 
+  struct grub_net_application_transport_interface *app_interface =
+    (struct grub_net_application_transport_interface *) protstack->interface;
+
+  app_interface->trans_prot->recv (inf,protstack->interface,nb);
+   
+  tftph = (struct tftphdr *) nb->data;
+  switch (tftph->opcode)
+  {
+    case TFTP_OACK:
+      /*process oack packet*/
+      temp = (char *) tftph->u.oack.data;
+      while(get_tok_val(&token,&value,&temp,nb->tail))
+      {
+        grub_printf("tok = <%s> val = <%s>\n",token,value);
+        process_option(token,value);
+      }
+       
+      //buff_clean
+      nb->data = nb->tail;
+      grub_printf("OACK---------------------------------------------------------\n");
+      grub_printf("block_size=%d\n",tftp_file.block_size);
+      grub_printf("file_size=%d\n",tftp_file.size);
+      grub_printf("OACK---------------------------------------------------------\n");
+      block = 0;
+    break; 
+    case TFTP_DATA:
+      grub_netbuff_pull (nb,sizeof (tftph->opcode) + sizeof (tftph->u.data.block));
+      if (tftph->u.data.block == block + 1)
+        block  = tftph->u.data.block;
+      else
+        grub_netbuff_clear(nb); 
+    break; 
+    case TFTP_ERROR:
+      nb->data = nb->tail;
+    break;
+  }
   
-  tftp_t pckt;
-  int pcktlen;
-  pckt.opcode =  TFTP_ACK;
-  pckt.u.ack.block = block;
-  pcktlen = sizeof (pckt.opcode) + sizeof (pckt.u.ack.block);
+  return 0;// tftp_send_ack (inf,protstack,nb,tftph->u.data.block); 
+  /*remove  tftp header and return.
+  nb should now contain only the payload*/
+}
+
+static grub_err_t 
+tftp_send_ack (struct grub_net_network_layer_interface *inf __attribute((unused)),
+  struct grub_net_protocol_stack *protstack,struct grub_net_buff *nb)
+{
+  struct tftphdr *tftph; 
+  struct grub_net_application_transport_interface *app_interface = (struct grub_net_application_transport_interface *) protstack->interface;
   
-  port = 4; 
-  return 0;// send_udp_packet (&pckt,pcktlen,TFTP_CLIENT_PORT,port);
+  nb->data = nb->tail = nb->end;
+  grub_netbuff_push (nb,sizeof (tftph->opcode) + sizeof (tftph->u.ack.block));
+
+  tftph = (struct tftphdr *) nb->data; 
+  tftph->opcode = TFTP_ACK;
+  tftph->u.ack.block = block;
+
+  return app_interface->trans_prot->send (inf,protstack->interface,nb); 
 }
 
-*/
+static int tftp_file_size (struct grub_net_network_layer_interface* inf ,
+             struct grub_net_protocol_stack *protocol_stack , struct grub_net_buff *nb ,char *filename )
+{
+
+  tftp_open (inf, protocol_stack,nb, filename);
+  return tftp_file.size;
+}
 
-static struct grub_net_protocol grub_tftp_protocol = 
+static grub_err_t 
+tftp_close (struct grub_net_network_layer_interface *inf __attribute((unused)),
+  struct grub_net_protocol_stack *protstack __attribute((unused)),struct grub_net_buff *nb __attribute((unused)))
 {
-   .name = "tftp",
-   .open = send_tftp_rr
-  
+
+  return 0;
+}
+
+static struct grub_net_application_transport_interface grub_net_tftp_app_trans_interf;
+static struct grub_net_transport_network_interface grub_net_tftp_trans_net_interf;
+static struct grub_net_network_link_interface grub_net_tftp_net_link_interf;
+static struct grub_net_protocol_stack grub_net_tftp_stack =
+{
+  .name = "tftp",
+  .id = GRUB_NET_TFTP_ID,
+  .interface = (void *) &grub_net_tftp_app_trans_interf
+};
+
+static struct grub_net_application_layer_protocol grub_tftp_protocol = 
+{
+  .name = "tftp",
+  .id = GRUB_NET_TFTP_ID,
+  .open = tftp_open,
+  .recv = tftp_receive, 
+  .send_ack = tftp_send_ack,
+  .get_file_size = tftp_file_size, 
+  .close = tftp_close 
 };
 
+static struct udp_interf  tftp_udp_interf;
+
 void tftp_ini(void)
 {
-  grub_protocol_register (&grub_tftp_protocol);
+
+  ethernet_ini ();
+  ipv4_ini ();
+  udp_ini ();
+  grub_net_application_layer_protocol_register (&grub_tftp_protocol);
+  grub_net_stack_register (&grub_net_tftp_stack);
+  
+  grub_net_tftp_app_trans_interf.app_prot = &grub_tftp_protocol;
+  grub_net_tftp_app_trans_interf.trans_prot = grub_net_transport_layer_protocol_get (GRUB_NET_UDP_ID);
+  grub_net_tftp_app_trans_interf.inner_layer = &grub_net_tftp_trans_net_interf;
+  grub_net_tftp_app_trans_interf.data = &tftp_udp_interf;
+  
+  grub_net_tftp_trans_net_interf.trans_prot = grub_net_tftp_app_trans_interf.trans_prot;
+  grub_net_tftp_trans_net_interf.net_prot = grub_net_network_layer_protocol_get (GRUB_NET_IPV4_ID);
+  grub_net_tftp_trans_net_interf.inner_layer = &grub_net_tftp_net_link_interf;
+
+  grub_net_tftp_net_link_interf.net_prot = grub_net_tftp_trans_net_interf.net_prot;
+  grub_net_tftp_net_link_interf.link_prot = grub_net_link_layer_protocol_get (GRUB_NET_ETHERNET_ID) ;
+  
 }
 
 void tftp_fini(void)
 {
-  grub_protocol_unregister (&grub_tftp_protocol);
+
+    
+  grub_net_application_layer_protocol_unregister (&grub_tftp_protocol);
 }
 /*
 int read_tftp_pckt (grub_uint16_t port, void *buffer, int &buff_len){
index 2a4a7690b8c662beb4b0d4c058152ac74f7c8ca2..fb81aef93d19afcfe8f2e1550447c83a80eada4d 100644 (file)
--- a/net/udp.c
+++ b/net/udp.c
@@ -4,41 +4,84 @@
 #include <grub/net/netbuff.h>
 #include <grub/net/protocol.h>
 #include <grub/net/interface.h>
-/*Assumes that there is allocated memory to the header before the buffer address. */
+
 static grub_err_t 
-send_udp_packet (struct grub_net_interface *inf, struct grub_net_protstack *protstack, struct grub_net_buff *nb)
+send_udp_packet (struct grub_net_network_layer_interface *inf,
+    struct grub_net_application_transport_interface *app_trans_inf, struct grub_net_buff *nb)
 {
 
   struct udphdr *udph;
-  grub_err_t err; 
+  struct udp_interf *udp_interf;
   
-  if((err = grub_netbuff_push (nb,sizeof(*udph)) ) != GRUB_ERR_NONE)
-    return err;
+  grub_netbuff_push (nb,sizeof(*udph)); 
   
   udph = (struct udphdr *) nb->data;    
-  udph->src = *((grub_uint16_t *) inf->card->tla->addr); 
-  udph->dst = *((grub_uint16_t *) inf->tla->addr);
+  udp_interf = (struct udp_interf *) app_trans_inf->data;
+  udph->src = udp_interf->src;
+  udph->dst = udp_interf->dst;
+
   /*no chksum*/
   udph->chksum = 0;  
-  udph->len = sizeof (sizeof (*udph)) + nb->end - nb->head;
+  udph->len = nb->tail - nb->data;
+  
+  return app_trans_inf->inner_layer->net_prot->send(inf,app_trans_inf->inner_layer,nb);
+}
+
+static grub_err_t 
+receive_udp_packet (struct grub_net_network_layer_interface *inf,
+    struct grub_net_application_transport_interface *app_trans_inf, struct grub_net_buff *nb)
+{ 
   
-  return protstack->next->prot->send(inf,protstack->next,nb); 
+  struct udphdr *udph;
+  struct udp_interf *udp_interf;
+  udp_interf = (struct udp_interf *) app_trans_inf->data;
+
+  while(1)
+  {
+    app_trans_inf->inner_layer->net_prot->recv(inf,app_trans_inf->inner_layer,nb);
+    
+    udph = (struct udphdr *) nb->data;
+    //  grub_printf("udph->dst %d\n",udph->dst);  
+    //  grub_printf("udp_interf->src %d\n",udp_interf->src);  
+    if (udph->dst == udp_interf->src)
+    {
+      grub_netbuff_pull (nb,sizeof(*udph));
+      
+     // udp_interf->src = udph->dst;
+      udp_interf->dst = udph->src;
+    
+   //   grub_printf("udph->dst %d\n",udph->dst);  
+    //  grub_printf("udph->src %d\n",udph->src);  
+     // grub_printf("udph->len %d\n",udph->len);  
+     // grub_printf("udph->chksum %x\n",udph->chksum);  
+    
+    /* - get udp header..
+     - verify if is  in the desired port
+     - if not. get another packet
+     - remove udp header*/
+     
+      return 0;
+    }
+  }
 }
 
-static struct grub_net_protocol grub_udp_protocol =
+
+static struct grub_net_transport_layer_protocol grub_udp_protocol =
 {
   .name = "udp",
-  .send = send_udp_packet
+  .id = GRUB_NET_UDP_ID,
+  .send = send_udp_packet,
+  .recv = receive_udp_packet 
 };
 
 void udp_ini(void)
 {
-  grub_protocol_register (&grub_udp_protocol);
+  grub_net_transport_layer_protocol_register (&grub_udp_protocol);
 }
 
 void udp_fini(void)
 {
-  grub_protocol_unregister (&grub_udp_protocol);
+  grub_net_transport_layer_protocol_unregister (&grub_udp_protocol);
 }
 
 /*