]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Initial Implementation of TFTP protocol and new protocol structs.
authorManoel R. Abranches <mrabran@br.ibm.com>
Tue, 27 Apr 2010 21:05:35 +0000 (18:05 -0300)
committerManoel R. Abranches <mrabran@br.ibm.com>
Tue, 27 Apr 2010 21:05:35 +0000 (18:05 -0300)
23 files changed:
conf/powerpc-ieee1275.rmk
include/grub/net.h
include/grub/net/arp.h [new file with mode: 0644]
include/grub/net/device.h [new file with mode: 0644]
include/grub/net/ethernet.h [new file with mode: 0644]
include/grub/net/ieee1275/interface.h [new file with mode: 0644]
include/grub/net/interface.h [new file with mode: 0644]
include/grub/net/ip.h [new file with mode: 0644]
include/grub/net/netbuff.h [new file with mode: 0644]
include/grub/net/protocol.h [new file with mode: 0644]
include/grub/net/tftp.h [new file with mode: 0644]
include/grub/net/type_net.h [new file with mode: 0644]
include/grub/net/udp.h [new file with mode: 0644]
net/arp.c [new file with mode: 0644]
net/device.c [new file with mode: 0644]
net/ethernet.c [new file with mode: 0644]
net/ieee1275/interface.c [new file with mode: 0644]
net/interface.c [new file with mode: 0644]
net/ip.c [new file with mode: 0644]
net/netbuff.c [new file with mode: 0644]
net/protocol.c [new file with mode: 0644]
net/tftp.c [new file with mode: 0644]
net/udp.c [new file with mode: 0644]

index be95b30ba56b2557413bd9f5bed041b805c42734..14d04f93edbc117951769833a502bb3051fbce3f 100644 (file)
@@ -3,7 +3,10 @@
 
 # Images.
 
-kernel_img_HEADERS += ieee1275/ieee1275.h
+<<<<<<< TREE
+kernel_img_HEADERS += ieee1275/ieee1275.h \
+       command.h i18n.h env_private.h net/ip.h net/udp.h net/ethernet.h net/arp.h net/tftp.h\
+        net/ieee1275/interface.h net/type_net.h net.h net/interface.h net/protocol.h net/netbuff.h
 
 # Programs
 pkglib_PROGRAMS = kernel.img
@@ -20,7 +23,8 @@ kernel_img_SOURCES = kern/powerpc/ieee1275/startup.S kern/ieee1275/cmain.c \
        kern/ieee1275/openfw.c disk/ieee1275/ofdisk.c           \
        kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c       \
        kern/generic/millisleep.c kern/time.c                            \
-       symlist.c kern/$(target_cpu)/cache.S
+       symlist.c kern/$(target_cpu)/cache.S net/ip.c net/tftp.c net/udp.c net/ethernet.c net/arp.c     \
+        net/ieee1275/interface.c net/interface.c net/protocol.c net/netbuff.c
 kernel_img_CFLAGS = $(COMMON_CFLAGS)
 kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
 kernel_img_LDFLAGS += $(COMMON_LDFLAGS) -Wl,-N,-S,-Ttext,0x200000,-Bstatic
index 4ca873f7481f28ac8cde539a3845a4fbf654e367..75efd51d64391eb13d4a7deaf45a853f09b473ab 100644 (file)
 #include <grub/types.h>
 #include <grub/err.h>
 #include <grub/list.h>
+#include <grub/net/netbuff.h>
 
 struct grub_net_card;
 
 struct grub_net_card_driver
 {
-  grub_err_t (*send) (struct grub_net_card *dev, void *buf,
-                     grub_size_t buflen);
-  grub_size_t (*recv) (struct grub_net_card *dev, void *buf,
-                      grub_size_t buflen);  
+  grub_err_t (*send) (struct grub_net_card *dev,struct grub_net_buff *nb);
+  grub_size_t (*recv) (struct grub_net_card *dev,struct grub_net_buff *nb);  
+};
+
+struct grub_net_addr
+{
+  grub_uint8_t *addr;
+  grub_size_t len; 
 };
 
 struct grub_net_card
@@ -38,6 +43,12 @@ struct grub_net_card
   struct grub_net_card *next;
   char *name;
   struct grub_net_card_driver *driver;
+  /*transport layer address*/
+  struct grub_net_addr *tla;
+  /*internet layer address*/
+  struct grub_net_addr *ila;
+  /*link layer address*/
+  struct grub_net_addr *lla;
   void *data;
 };
 
diff --git a/include/grub/net/arp.h b/include/grub/net/arp.h
new file mode 100644 (file)
index 0000000..0ac2ec8
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef GRUB_NET_ARP_HEADER
+#define GRUB_NET_ARP_HEADER    1
+
+#include <grub/net/ethernet.h>
+struct arprequest {
+    grub_int16_t hwtype;        /* hardware type (must be ARPHRD_ETHER) */
+    grub_int16_t protocol;      /* protocol type (must be ETH_P_IP) */
+    grub_int8_t hwlen;            /* hardware address length (must be 6) */
+    grub_int8_t protolen;         /* protocol address length (must be 4) */
+    grub_uint16_t opcode;        /* ARP opcode */
+    grub_uint8_t shwaddr[6];     /* sender's hardware address */
+    grub_uint32_t sipaddr;     /* sender's IP address */
+    grub_uint8_t thwaddr[6];     /* target's hardware address */
+    grub_uint32_t tipaddr;     /* target's IP address */
+}__attribute__ ((packed));
+
+
+struct arp_pkt{
+  struct etherhdr ether;
+  struct arprequest arpr;
+} __attribute__ ((packed));
+
+#endif 
diff --git a/include/grub/net/device.h b/include/grub/net/device.h
new file mode 100644 (file)
index 0000000..9f1b9bf
--- /dev/null
@@ -0,0 +1,7 @@
+struct grub_net_card
+{
+  struct grub_net_card *next;
+  char *name;
+  struct grub_net_card_driver *driver;
+  void *data;
+};
diff --git a/include/grub/net/ethernet.h b/include/grub/net/ethernet.h
new file mode 100644 (file)
index 0000000..46aa04f
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef GRUB_NET_ETHERNET_HEADER
+#define GRUB_NET_ETHERNET_HEADER       1
+#include <grub/misc.h>
+struct etherhdr {
+  grub_uint8_t dst[6];
+  grub_uint8_t src[6];
+  grub_uint16_t type;
+} __attribute__ ((packed))  ;
+
+void ethernet_ini(void);
+void ethernet_fini(void);
+#endif 
diff --git a/include/grub/net/ieee1275/interface.h b/include/grub/net/ieee1275/interface.h
new file mode 100644 (file)
index 0000000..edc242c
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef GRUB_IEEE1275_INTERFACE_HEADER
+#define GRUB_IEEE1275_INTERFACE_HEADER 1
+
+#include <grub/misc.h>
+#include <grub/ieee1275/ieee1275.h>
+#include <grub/ieee1275/ofnet.h>
+
+grub_ofnet_t EXPORT_VAR(grub_net);
+
+grub_bootp_t EXPORT_VAR(bootp_pckt);
+grub_uint32_t get_server_ip(void);
+grub_uint32_t get_client_ip(void);
+grub_uint8_t* get_server_mac (void);
+grub_uint8_t* get_client_mac (void);
+
+int send_card_buffer (void *buffer,int buff_len);
+int get_card_buffer (void *buffer,int buff_len);
+int card_open (void);
+int card_close (void);
+
+#endif 
diff --git a/include/grub/net/interface.h b/include/grub/net/interface.h
new file mode 100644 (file)
index 0000000..0e11c86
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef GRUB_INTERFACE_HEADER
+#define GRUB_INTERFACE_HEADER
+#include <grub/net.h>
+#include <grub/net/protocol.h>
+/*
+extern  struct grub_net_topprotocol; 
+
+struct grub_net_interface
+{
+  struct grub_net_card *card;
+  struct grub_net_topprotocol* topprot; 
+  struct grub_net_addr *tla;
+  struct grub_net_addr *ila;
+  struct grub_net_addr *lla;
+};
+*/
+#endif
diff --git a/include/grub/net/ip.h b/include/grub/net/ip.h
new file mode 100644 (file)
index 0000000..e1f45dc
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef GRUB_NET_IP_HEADER
+#define GRUB_NET_IP_HEADER     1
+#include <grub/misc.h>
+
+
+struct iphdr {
+  grub_uint8_t verhdrlen;
+  grub_uint8_t service;
+  grub_uint16_t len;
+  grub_uint16_t ident;
+  grub_uint16_t frags;
+  grub_uint8_t ttl;
+  grub_uint8_t protocol;
+  grub_uint16_t chksum;
+  grub_uint32_t src;
+  grub_uint32_t  dest;
+} __attribute__ ((packed)) ;
+
+#define IP_UDP          17              /* UDP protocol */
+#define IP_BROADCAST    0xFFFFFFFF
+
+grub_uint16_t ipchksum(void *ipv, int len);
+void ipv4_ini(void);
+void ipv4_fini(void);
+#endif 
diff --git a/include/grub/net/netbuff.h b/include/grub/net/netbuff.h
new file mode 100644 (file)
index 0000000..7d63be1
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef GRUB_NETBUFF_HEADER
+#define GRUB_NETBUFF_HEADER
+
+#include <grub/misc.h>
+
+#define NETBUFF_ALIGN 2048
+#define NETBUFFMINLEN 64
+
+struct grub_net_buff
+{
+  /*Pointer to the start of the buffer*/
+  char *head;
+  /*Pointer to the data */
+  char *data;
+  /*Pointer to the tail */
+  char *tail;
+  /*Pointer to the end of the buffer*/
+  char *end;
+};
+
+grub_err_t grub_netbuff_put (struct grub_net_buff *net_buff ,grub_size_t len);
+grub_err_t grub_netbuff_unput (struct grub_net_buff *net_buff ,grub_size_t len);
+grub_err_t grub_netbuff_push (struct grub_net_buff *net_buff ,grub_size_t len);
+grub_err_t grub_netbuff_pull (struct grub_net_buff *net_buff ,grub_size_t len);
+grub_err_t grub_netbuff_reserve (struct grub_net_buff *net_buff ,grub_size_t len);
+struct grub_net_buff * grub_netbuff_alloc ( grub_size_t len );
+#endif
diff --git a/include/grub/net/protocol.h b/include/grub/net/protocol.h
new file mode 100644 (file)
index 0000000..2c97948
--- /dev/null
@@ -0,0 +1,50 @@
+#ifndef GRUB_PROTOCOL_HEADER
+#define GRUB_PROTOCOL_HEADER
+#include <grub/err.h>
+#include <grub/net/protocol.h>
+#include <grub/net/netbuff.h>
+#include <grub/net.h>
+struct protocol_operations;
+struct grub_net_protocol;
+struct grub_net_interface;
+
+struct grub_net_protocol
+{
+  struct grub_net_protocol *next;
+  char *name;
+  grub_err_t (*open) (struct grub_net_interface* inf,
+             struct grub_net_protocol *prot, struct grub_net_buff *nb);
+  grub_err_t (*open_confirm) (struct grub_net_interface *inf,
+             struct grub_net_protocol *prot, struct grub_net_buff *nb);
+  grub_err_t (*get_payload) (struct grub_net_interface *inf,
+             struct grub_net_protocol *prot, struct grub_net_buff *nb);
+  grub_err_t (*get_payload_confirm) (struct grub_net_interface* inf,
+             struct grub_net_protocol *prot, struct grub_net_buff *nb);
+  grub_err_t (*close) (struct grub_net_interface *inf,
+             struct grub_net_protocol *prot, struct grub_net_buff *nb);
+  grub_err_t (*send) (struct grub_net_interface *inf ,
+             struct grub_net_protocol *prot, struct grub_net_buff *nb);
+  grub_err_t (*recv) (struct grub_net_interface *inf ,
+             struct grub_net_protocol *prot, struct grub_net_buff *nb);
+};
+
+typedef struct grub_net_protocol *grub_net_protocol_t;
+
+struct grub_net_interface
+{
+  struct grub_net_card *card;
+  struct grub_net_protocol* prot;
+  char *path;
+  char *username;
+  char *password;
+  /*transport layer addres*/ 
+  struct grub_net_addr *tla;
+  /*internet layer addres*/ 
+  struct grub_net_addr *ila;
+  /*link layer addres*/ 
+  struct grub_net_addr *lla;
+};
+
+void grub_protocol_register (grub_net_protocol_t prot);
+void grub_protocol_unregister (grub_net_protocol_t prot);
+#endif
diff --git a/include/grub/net/tftp.h b/include/grub/net/tftp.h
new file mode 100644 (file)
index 0000000..4148096
--- /dev/null
@@ -0,0 +1,74 @@
+#ifndef GRUB_NET_TFTP_HEADER
+#define GRUB_NET_TFTP_HEADER   1
+
+#include <grub/misc.h>
+#include <grub/net/ethernet.h>
+#include <grub/net/udp.h>
+
+/* IP port for the MTFTP server used for Intel's PXE */
+#define MTFTP_SERVER_PORT 75
+#define MTFTP_CLIENT_PORT 76
+
+#define TFTP_DEFAULTSIZE_PACKET 512
+#define TFTP_MAX_PACKET 1432
+
+/* IP port for the TFTP server */
+#define TFTP_SERVER_PORT 69
+#define TFTP_CLIENT_PORT 2000
+
+
+/* We define these based on what's in arpa/tftp.h. We just like our
+ *  names better, cause they're clearer */
+#define TFTP_RRQ 1
+#define TFTP_WRQ 2
+#define TFTP_DATA 3
+#define TFTP_ACK 4
+#define TFTP_ERROR 5
+#define TFTP_OACK 6
+
+#define TFTP_CODE_EOF 1
+#define TFTP_CODE_MORE 2
+#define TFTP_CODE_ERROR 3
+#define TFTP_CODE_BOOT 4
+#define TFTP_CODE_CFG 5
+
+#define TFTP_EUNDEF 0                   /* not defined */
+#define TFTP_ENOTFOUND 1                /* file not found */
+#define TFTP_EACCESS 2                  /* access violation */
+#define TFTP_ENOSPACE 3                 /* disk full or allocation exceeded */
+#define TFTP_EBADOP 4                   /* illegal TFTP operation */
+#define TFTP_EBADID 5                   /* unknown transfer ID */
+#define TFTP_EEXISTS 6                  /* file already exists */
+#define TFTP_ENOUSER 7                  /* no such user */
+#define TFTP_DEFAULT_FILENAME   "kernel"
+
+
+
+
+
+ /*  * own here because this is cleaner, and maps to the same data layout.
+ *   */
+struct tftphdr {
+  grub_uint16_t opcode;
+  union {
+    grub_int8_t rrq[TFTP_DEFAULTSIZE_PACKET];
+    struct {
+      grub_uint16_t block;
+      grub_int8_t download[TFTP_MAX_PACKET];
+    } data;
+    struct {
+      grub_uint16_t block;
+    } ack;
+    struct {
+      grub_uint16_t errcode;
+      grub_int8_t errmsg[TFTP_DEFAULTSIZE_PACKET];
+    } err;
+    struct {
+      grub_int8_t data[TFTP_DEFAULTSIZE_PACKET+2];
+    } oack;
+  } u;
+} __attribute__ ((packed)) ;
+
+void tftp_ini(void);
+void tftp_fini(void);
+#endif 
diff --git a/include/grub/net/type_net.h b/include/grub/net/type_net.h
new file mode 100644 (file)
index 0000000..33f2d80
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef GRUB_TYPES_NET_HEADER
+#define GRUB_TYPES_NET_HEADER  1
+
+#define UDP_PCKT 0x11
+#define IP_PCKT 0x0800
+
+#endif 
diff --git a/include/grub/net/udp.h b/include/grub/net/udp.h
new file mode 100644 (file)
index 0000000..dbfcece
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef GRUB_NET_UDP_HEADER
+#define GRUB_NET_UDP_HEADER    1
+#include <grub/misc.h>
+/*
+typedef enum
+  {
+    GRUB_PROT_TFTP
+  } protocol_type;
+*/
+
+#define GRUB_PROT_TFTP 1 
+
+struct udphdr {
+  grub_uint16_t src;
+  grub_uint16_t dst;
+  grub_uint16_t len;
+  grub_uint16_t chksum;
+} __attribute__ ((packed));
+
+void udp_ini(void);
+void udp_fini(void);
+#endif 
diff --git a/net/arp.c b/net/arp.c
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/net/device.c b/net/device.c
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/net/ethernet.c b/net/ethernet.c
new file mode 100644 (file)
index 0000000..fc64803
--- /dev/null
@@ -0,0 +1,54 @@
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/net/ethernet.h>
+#include <grub/net/ip.h>
+#include <grub/net/arp.h>
+#include <grub/net/ieee1275/interface.h>
+#include <grub/net/netbuff.h>
+#include <grub/net/protocol.h>
+
+static grub_err_t 
+send_ethernet_packet (struct grub_net_interface *inf, struct grub_net_protocol *prot __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;
+  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->type = 0x0800;
+  
+  return  inf->card->driver->send(inf->card,nb);
+}
+
+static struct grub_net_protocol grub_ethernet_protocol =
+{
+  .name = "udp",
+  .send = send_ethernet_packet
+};
+
+void ethernet_ini(void)
+{
+  grub_protocol_register (&grub_ethernet_protocol);
+}
+
+void ethernet_fini(void)
+{
+  grub_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));
+  
+
+
+}*/
diff --git a/net/ieee1275/interface.c b/net/ieee1275/interface.c
new file mode 100644 (file)
index 0000000..5a246ff
--- /dev/null
@@ -0,0 +1,80 @@
+#include <grub/net/ieee1275/interface.h>
+#include <grub/mm.h>
+
+grub_uint32_t get_server_ip (void)
+{
+  return bootp_pckt->siaddr;
+}
+
+grub_uint32_t get_client_ip (void)
+{
+  return bootp_pckt->yiaddr;
+}
+
+grub_uint8_t* get_server_mac (void)
+{
+  grub_uint8_t *mac; 
+  mac = grub_malloc (6 * sizeof(grub_uint8_t));
+  mac[0] = 0x00 ;
+  mac[1] = 0x11 ;
+  mac[2] = 0x25 ; 
+  mac[3] = 0xca ;  
+  mac[4] = 0x1f ;  
+  mac[5] = 0x01 ;  
+
+  return mac;
+
+}
+
+grub_uint8_t* get_client_mac (void)
+{
+  grub_uint8_t *mac;
+  
+  mac = grub_malloc (6 * sizeof (grub_uint8_t));
+  mac[0] = 0x0a ;
+  mac[1] = 0x11 ;
+  mac[2] = 0xbd ;
+  mac[3] = 0xe3 ; 
+  mac[4] = 0xe3 ;   
+  mac[5] = 0x04 ;
+
+  return mac;
+}  
+
+static grub_ieee1275_ihandle_t handle;
+int card_open (void)
+{
+
+  grub_ieee1275_open (grub_net->dev , &handle);
+    return 1;//error
+
+}
+int card_close (void)
+{
+
+  if (handle)
+    grub_ieee1275_close (handle);
+  return 0;
+}
+
+
+int send_card_buffer (void *buffer,int buff_len)
+{
+  
+  int actual; 
+
+  grub_ieee1275_write (handle,buffer,buff_len,&actual);
+  return actual; 
+}
+
+int get_card_buffer (void *buffer,int buff_len)
+{
+
+  int actual; 
+
+  grub_ieee1275_read (handle,buffer,buff_len,&actual);
+  
+  return actual; 
+}
diff --git a/net/interface.c b/net/interface.c
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/net/ip.c b/net/ip.c
new file mode 100644 (file)
index 0000000..c669ff6
--- /dev/null
+++ b/net/ip.c
@@ -0,0 +1,95 @@
+#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/mm.h>
+
+struct grub_net_protocol *grub_ipv4_prot;
+
+grub_uint16_t
+ipchksum(void *ipv, int len)
+{
+    grub_uint16_t *ip = (grub_uint16_t *)ipv;
+    grub_uint32_t sum = 0;
+    
+    
+    len >>= 1;
+    while (len--) {
+        sum += *(ip++);
+        if (sum > 0xFFFF)
+            sum -= 0xFFFF;
+    }
+
+    return((~sum) & 0x0000FFFF);
+}
+
+
+static grub_err_t 
+send_ip_packet (struct grub_net_interface *inf, struct grub_net_protocol *prot, struct grub_net_buff *nb  )
+{
+  
+  struct iphdr *iph;
+  grub_err_t err;
+  
+  if((err = grub_netbuff_push(nb,sizeof(*iph)) ) != GRUB_ERR_NONE)
+    return err;    
+  iph = (struct iphdr *) nb->data;   
+
+  /*FIXME dont work in litte endian machines*/
+  //grub_uint8_t ver = 4;
+  //grub_uint8_t hdrlen = sizeof (struct iphdr)/4;  
+  iph->verhdrlen = (4<<4 | 5);
+  iph->service = 0;
+  iph->len = sizeof(*iph);
+  iph->ident = 0x2b5f;
+  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->chksum = 0 ;
+  iph->chksum = ipchksum((void *)nb->head, sizeof(*iph));
+  
+  
+  return prot->next->send(inf,prot->next,nb); 
+}
+
+static struct grub_net_protocol grub_ipv4_protocol =
+{
+ .name = "ipv4",
+ .send = send_ip_packet,
+ .recv = NULL
+};
+
+void ipv4_ini(void)
+{
+  grub_protocol_register (&grub_ipv4_protocol);
+}
+
+void ipv4_fini(void)
+{
+  grub_protocol_unregister (&grub_ipv4_protocol);
+}
+
+/*
+int read_ip_packet (void *buffer,int *bufflen)
+{
+  struct iphdr iph;
+  iph.protocol = 0;
+
+  while ( iph.protocol != IP_UDP)
+  {
+    read_ethernet_packet(buffer,bufflen,IP_PROTOCOL);
+    grub_memcpy (&iph,buffer,sizeof (iph));
+  }
+
+  buffer += sizeof (iph);
+  *buff_len -= sizeof (iph);
+
+}*/
diff --git a/net/netbuff.c b/net/netbuff.c
new file mode 100644 (file)
index 0000000..342260f
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2010 Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/net/netbuff.h>
+
+
+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_ERR_NONE; 
+}
+
+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_ERR_NONE; 
+}
+
+grub_err_t grub_netbuff_push (struct grub_net_buff *net_buff ,grub_size_t len)
+{
+  net_buff->data -= len;
+  if (net_buff->data < net_buff->head)
+    return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of the packet range.");
+  return GRUB_ERR_NONE; 
+}
+
+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_ERR_NONE; 
+}
+
+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_ERR_NONE; 
+}
+
+struct grub_net_buff * grub_netbuff_alloc ( grub_size_t len )
+{
+  if (len < NETBUFFMINLEN) 
+    len = NETBUFFMINLEN;
+  len = ALIGN_UP (len,NETBUFF_ALIGN);
+  return (struct grub_net_buff *) grub_memalign (len,NETBUFF_ALIGN); 
+}
diff --git a/net/protocol.c b/net/protocol.c
new file mode 100644 (file)
index 0000000..a6117dc
--- /dev/null
@@ -0,0 +1,21 @@
+#include <grub/net/protocol.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;
+}
+
+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;
+    }
+}
diff --git a/net/tftp.c b/net/tftp.c
new file mode 100644 (file)
index 0000000..fdca184
--- /dev/null
@@ -0,0 +1,102 @@
+#include <grub/misc.h>
+#include <grub/net/tftp.h>
+#include <grub/net/udp.h>
+#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>
+
+/*send read request*/
+static grub_err_t 
+send_tftp_rr (struct grub_net_interface *inf, struct grub_net_protocol *prot,struct grub_net_buff *nb)
+{
+  /*Start TFTP header*/
+  
+  struct tftphdr *tftph; 
+  char *rrq;
+  int rrqlen;
+  int hdrlen; 
+  grub_err_t err; 
+  
+  if((err = grub_netbuff_push (nb,sizeof(*tftph))) != GRUB_ERR_NONE)
+    return err;
+
+  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;
+  /*passar opcoes como parametro ou usar default?*/
+  
+  grub_strcpy (rrq,"octet");
+  rrqlen += grub_strlen ("octet") + 1;
+  rrq +=  grub_strlen ("octet") + 1;
+
+  grub_strcpy (rrq,"blksize");
+  rrqlen += grub_strlen("blksize") + 1;
+  rrq +=  grub_strlen ("blksize") + 1;
+
+  grub_strcpy (rrq,"1024");
+  rrqlen += grub_strlen ("1024") + 1;
+  rrq +=  grub_strlen ("1024") + 1;
+  
+  grub_strcpy (rrq,"tsize");
+  rrqlen += grub_strlen ("tsize") + 1;
+  rrq +=  grub_strlen ("tsize") + 1;
+
+  grub_strcpy (rrq,"0");
+  rrqlen += grub_strlen ("0") + 1;
+  rrq +=  grub_strlen ("0") + 1;
+  hdrlen = sizeof (tftph->opcode) + rrqlen;
+  grub_netbuff_unput (nb,nb->tail - (nb->data+hdrlen)); 
+
+  return prot->next->send(inf,prot->next,nb); 
+}
+
+/*
+int send_tftp_ack(int block, int port){
+  
+  tftp_t pckt;
+  int pcktlen;
+  pckt.opcode =  TFTP_ACK;
+  pckt.u.ack.block = block;
+  pcktlen = sizeof (pckt.opcode) + sizeof (pckt.u.ack.block);
+  
+  port = 4; 
+  return 0;// send_udp_packet (&pckt,pcktlen,TFTP_CLIENT_PORT,port);
+}
+
+*/
+
+static struct grub_net_protocol grub_tftp_protocol = 
+{
+   .name = "tftp",
+   .open = send_tftp_rr
+  
+};
+
+void tftp_ini(void)
+{
+  grub_protocol_register (&grub_tftp_protocol);
+}
+
+void tftp_fini(void)
+{
+  grub_protocol_unregister (&grub_tftp_protocol);
+}
+/*
+int read_tftp_pckt (grub_uint16_t port, void *buffer, int &buff_len){
+  
+  
+  read_udp_packet (port,buffer,buff_len);
+
+  
+}*/
diff --git a/net/udp.c b/net/udp.c
new file mode 100644 (file)
index 0000000..600eec5
--- /dev/null
+++ b/net/udp.c
@@ -0,0 +1,59 @@
+#include <grub/net/udp.h>
+#include <grub/net/ip.h>
+#include <grub/net/type_net.h>
+#include <grub/net/netbuff.h>
+#include <grub/net/protocol.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_protocol *prot, struct grub_net_buff *nb)
+{
+
+  struct udphdr *udph;
+  grub_err_t err; 
+  
+  if((err = grub_netbuff_push (nb,sizeof(*udph)) ) != GRUB_ERR_NONE)
+    return err;
+  
+  udph = (struct udphdr *) nb->data;    
+  udph->src = *((grub_uint16_t *) inf->card->tla->addr); 
+  udph->dst = *((grub_uint16_t *) inf->tla->addr);
+  /*no chksum*/
+  udph->chksum = 0;  
+  udph->len = sizeof (sizeof (*udph)) + nb->end - nb->head;
+  
+  return prot->next->send(inf,prot->next,nb); 
+}
+
+static struct grub_net_protocol grub_udp_protocol =
+{
+  .name = "udp",
+  .send = send_udp_packet
+};
+
+void udp_ini(void)
+{
+  grub_protocol_register (&grub_udp_protocol);
+}
+
+void udp_fini(void)
+{
+  grub_protocol_unregister (&grub_udp_protocol);
+}
+
+/*
+int read_udp_packet (grub_uint16_t port,void *buffer,int *buff_len)
+{
+  
+  struct udphdr udph;
+  udph.dst = 0;
+
+  while ( udph.dst != port)
+  {
+    read_ip_packet (buffer,bufflen);
+    grub_memcpy (&udph,buffer,sizeof (udph));
+  }  
+
+  buffer += sizeof (udph);
+  *buff_len -= sizeof (udph);
+
+}*/