Home | History | Annotate | Download | only in legacynet
      1 #include <syslinux/pxe_api.h>
      2 #include <com32.h>
      3 #include <core.h>
      4 #include <net.h>
      5 #include <pxe.h>
      6 #include <minmax.h>
      7 
      8 /* Common receive buffer */
      9 static __lowmem char packet_buf[PKTBUF_SIZE] __aligned(16);
     10 
     11 extern uint16_t get_port(void);
     12 extern void free_port(uint16_t);
     13 
     14 const struct url_scheme url_schemes[] = {
     15     { "tftp", tftp_open, 0 },
     16     { NULL, NULL, 0 }
     17 };
     18 
     19 /**
     20  * Open a socket
     21  *
     22  * @param:socket, the socket to open
     23  *
     24  * @out: error code, 0 on success, -1 on failure
     25  */
     26 int core_udp_open(struct pxe_pvt_inode *socket __unused)
     27 {
     28     struct net_private_tftp *priv = &socket->net.tftp;
     29 
     30     /* Allocate local UDP port number */
     31     priv->localport = get_port();
     32 
     33     return 0;
     34 }
     35 
     36 /**
     37  * Close a socket
     38  *
     39  * @param:socket, the socket to open
     40  */
     41 void core_udp_close(struct pxe_pvt_inode *socket)
     42 {
     43     struct net_private_tftp *priv = &socket->net.tftp;
     44 
     45     if (priv->localport)
     46 	free_port(priv->localport);
     47 }
     48 
     49 /**
     50  * Establish a connection on an open socket
     51  *
     52  * @param:socket, the open socket
     53  * @param:ip, the ip address
     54  * @param:port, the port number, host-byte order
     55  */
     56 void core_udp_connect(struct pxe_pvt_inode *socket, uint32_t ip,
     57 		      uint16_t port)
     58 {
     59     struct net_private_tftp *priv = &socket->net.tftp;
     60 
     61     socket->tftp_remoteport = htons(port);
     62     priv->remoteip = ip;
     63 
     64 }
     65 
     66 /**
     67  * Tear down a connection on an open socket
     68  *
     69  * @param:socket, the open socket
     70  */
     71 void core_udp_disconnect(struct pxe_pvt_inode *socket __unused)
     72 {
     73 }
     74 
     75 /**
     76  * Read data from the network stack
     77  *
     78  * @param:socket, the open socket
     79  * @param:buf, location of buffer to store data
     80  * @param:buf_len, size of buffer
     81 
     82  * @out: src_ip, ip address of the data source
     83  * @out: src_port, port number of the data source, host-byte order
     84  */
     85 int core_udp_recv(struct pxe_pvt_inode *socket, void *buf, uint16_t *buf_len,
     86 		  uint32_t *src_ip, uint16_t *src_port)
     87 {
     88     static __lowmem struct s_PXENV_UDP_READ  udp_read;
     89     struct net_private_tftp *priv = &socket->net.tftp;
     90     uint16_t bytes;
     91     int err;
     92 
     93     udp_read.status      = 0;
     94     udp_read.buffer      = FAR_PTR(packet_buf);
     95     udp_read.buffer_size = PKTBUF_SIZE;
     96     udp_read.dest_ip     = IPInfo.myip;
     97     udp_read.d_port      = priv->localport;
     98 
     99     err = pxe_call(PXENV_UDP_READ, &udp_read);
    100     if (err)
    101 	return err;
    102 
    103     if (udp_read.status)
    104 	return udp_read.status;
    105 
    106     bytes = min(udp_read.buffer_size, *buf_len);
    107     memcpy(buf, packet_buf, bytes);
    108 
    109     *src_ip = udp_read.src_ip;
    110     *src_port = ntohs(udp_read.s_port);
    111     *buf_len = bytes;
    112 
    113     return 0;
    114 }
    115 
    116 /**
    117  * Send a UDP packet.
    118  *
    119  * @param:socket, the open socket
    120  * @param:data, data buffer to send
    121  * @param:len, size of data bufer
    122  */
    123 void core_udp_send(struct pxe_pvt_inode *socket, const void *data, size_t len)
    124 {
    125     static __lowmem struct s_PXENV_UDP_WRITE udp_write;
    126     struct net_private_tftp *priv = &socket->net.tftp;
    127     void *lbuf;
    128     uint16_t tid;
    129 
    130     lbuf = lmalloc(len);
    131     if (!lbuf)
    132 	return;
    133 
    134     memcpy(lbuf, data, len);
    135 
    136     tid = priv->localport;   /* TID(local port No) */
    137     udp_write.buffer    = FAR_PTR(lbuf);
    138     udp_write.ip        = priv->remoteip;
    139     udp_write.gw        = gateway(udp_write.ip);
    140     udp_write.src_port  = tid;
    141     udp_write.dst_port  = socket->tftp_remoteport;
    142     udp_write.buffer_size = len;
    143 
    144     pxe_call(PXENV_UDP_WRITE, &udp_write);
    145 
    146     lfree(lbuf);
    147 }
    148 
    149 /**
    150  * Send a UDP packet to a destination
    151  *
    152  * @param:socket, the open socket
    153  * @param:data, data buffer to send
    154  * @param:len, size of data bufer
    155  * @param:ip, the ip address
    156  * @param:port, the port number, host-byte order
    157  */
    158 void core_udp_sendto(struct pxe_pvt_inode *socket, const void *data, size_t len,
    159 		     uint32_t ip, uint16_t port)
    160 {
    161     static __lowmem struct s_PXENV_UDP_WRITE udp_write;
    162     struct net_private_tftp *priv = &socket->net.tftp;
    163     void *lbuf;
    164     uint16_t tid;
    165 
    166     lbuf = lmalloc(len);
    167     if (!lbuf)
    168 	return;
    169 
    170     memcpy(lbuf, data, len);
    171 
    172     tid = priv->localport;   /* TID(local port No) */
    173     udp_write.buffer    = FAR_PTR(lbuf);
    174     udp_write.ip        = ip;
    175     udp_write.gw        = gateway(udp_write.ip);
    176     udp_write.src_port  = tid;
    177     udp_write.dst_port  = htons(port);
    178     udp_write.buffer_size = len;
    179 
    180     pxe_call(PXENV_UDP_WRITE, &udp_write);
    181 
    182     lfree(lbuf);
    183 }
    184 
    185 
    186 /**
    187  * Network stack-specific initialization
    188  *
    189  * Initialize UDP stack
    190  */
    191 void net_core_init(void)
    192 {
    193     int err;
    194     static __lowmem struct s_PXENV_UDP_OPEN udp_open;
    195     udp_open.src_ip = IPInfo.myip;
    196     err = pxe_call(PXENV_UDP_OPEN, &udp_open);
    197     if (err || udp_open.status) {
    198         printf("Failed to initialize UDP stack ");
    199         printf("%d\n", udp_open.status);
    200 	kaboom();
    201     }
    202 }
    203 
    204 void probe_undi(void)
    205 {
    206 }
    207 
    208 void pxe_init_isr(void)
    209 {
    210 }
    211 
    212 int reset_pxe(void)
    213 {
    214     static __lowmem struct s_PXENV_UDP_CLOSE udp_close;
    215     int err = 0;
    216 
    217     pxe_idle_cleanup();
    218 
    219     pxe_call(PXENV_UDP_CLOSE, &udp_close);
    220 
    221     return err;
    222 }
    223