void process_tick(float dt) { dt += pending_dt; pending_dt = 0; while (dt > 1.0f/60) { #ifdef MULTIPLAYER if (is_server) { server_net_tick_pre_physics(); process_tick_raw(1.0f/60); server_net_tick_post_physics(); } else { client_view_physics(player_id, &client_player_input, dt); client_net_tick(); } #else client_view_physics(player_id, &client_player_input, dt); process_tick_raw(1.0f/60); #endif dt -= 1.0f/60; } pending_dt += dt; #if 0 if (is_server) { while (net_receive(&client_player_input, sizeof(client_player_input)) >= 0) ; } else { while (net_receive(&o, sizeof(o)) >= 0) { obj[player_id].position = o.position; obj[player_id].velocity = o.velocity; } } #endif }
static inline void receive_and_reply(struct net_context *recv, struct net_context *mcast_recv) { struct net_buf *buf; buf = net_receive(recv, TICKS_UNLIMITED); if (buf) { prepare_reply("unicast ", buf); if (net_reply(recv, buf)) { ip_buf_unref(buf); } return; } buf = net_receive(mcast_recv, TICKS_UNLIMITED); if (buf) { prepare_reply("multicast ", buf); if (net_reply(mcast_recv, buf)) { ip_buf_unref(buf); } return; } }
static int smsc95xx_rx_fixup(struct usbnet *dev, void *buf, int len) { while (len > 0) { u32 header, align_count; unsigned char *packet; u16 size; memcpy(&header, buf, sizeof(header)); le32_to_cpus(&header); buf += 4 + NET_IP_ALIGN; len -= 4 + NET_IP_ALIGN; packet = buf; /* get the packet length */ size = (u16)((header & RX_STS_FL_) >> 16); align_count = (4 - ((size + NET_IP_ALIGN) % 4)) % 4; if (header & RX_STS_ES_) { netif_dbg(dev, rx_err, dev->net, "Error header=0x%08x\n", header); } else { /* ETH_FRAME_LEN + 4(CRC) + 2(COE) + 4(Vlan) */ if (size > (ETH_FRAME_LEN + 12)) { netif_dbg(dev, rx_err, dev->net, "size err header=0x%08x\n", header); return 0; } /* last frame in this batch */ if (len == size) { net_receive(&dev->edev, buf, len - 4); return 1; } net_receive(&dev->edev, packet, len - 4); } len -= size; /* padding bytes before the next frame starts */ if (len) len -= align_count; } if (len < 0) { netdev_warn(dev->net, "invalid rx length<0 %d\n", len); return 0; } return 1; }
/* input function: DCC GET received data */ static void sig_dccget_receive(DCC_REC *dcc) { int ret; g_return_if_fail(dcc != NULL); for (;;) { ret = net_receive(dcc->handle, dcc->databuf, dcc->databufsize); if (ret == 0) break; if (ret < 0) { /* socket closed - transmit complete, or other side died.. */ signal_emit("dcc closed", 1, dcc); dcc_destroy(dcc); return; } write(dcc->fhandle, dcc->databuf, ret); dcc->transfd += ret; } /* send number of total bytes received */ if (dcc->count_pos <= 0) dcc_get_send_received(dcc); signal_emit("dcc transfer update", 1, dcc); }
/* Get a data block via Ethernet */ int eth_rx (void) { int i; unsigned short rxlen; unsigned short *addr; unsigned short status; status = get_reg (PP_RER); if ((status & PP_RER_RxOK) == 0) return 0; status = CS8900_RTDATA; /* stat */ rxlen = CS8900_RTDATA; /* len */ #ifdef DEBUG if (rxlen > PKTSIZE_ALIGN + PKTALIGN) printf ("packet too big!\n"); #endif for (addr = (unsigned short *) &RxBuf[0], i = rxlen >> 1; i > 0; i--) *addr++ = CS8900_RTDATA; if (rxlen & 1) *addr++ = CS8900_RTDATA; /* Pass the packet up to the protocol layers. */ //NetReceive (NetRxPackets[0], rxlen); net_receive( &RxBuf[0], rxlen ); return rxlen; }
void slip_receive(cpu_state_t* state) { uint8_t c = serial_recv(); if(!in_progress) { if(c != END) return; buf = (uint8_t*)kmalloc(sizeof(uint8_t) * BUFSIZE); in_progress = true; return; } if((c == END && in_progress) || bufpos >= BUFSIZE) { in_progress = false; // TODO IPv6 support net_receive(mydev, NET_PROTO_RAW, bufpos, buf); bufpos = -1; } switch(c) { case ESC: c = serial_recv(); if(c == ESC_END) c = END; else if(c == ESC_ESC) c = ESC; default: buf[bufpos++] = c; } }
int main(int argc, char *argv[]) { #ifdef TCP int s = net_connect_tcp("0","2334",1); #else int s = net_connect_udp("2334",1); #endif if (s < 0) { printf("Failed to serve (%d)\n",s); return 0; } printf("%d serving...\n",s); #ifdef TCP int c = net_accept(s); if (c < 0) { printf("Client not found (%d)\n",c); return 0; } printf("Connected %d\n",c); char *str = net_receive(c); if (str == NULL) printf("Receive error (%d)\n",errno); else printf("Received: %s\nSending: %s\n",str,"Goodbye Cruel World"); char *msg = "Goodbye Cruel World"; if (net_send(c,msg,strlen(msg)+1) < 0) printf("Send error (%d)\n",errno); closesocket(c); #else net_bounce(s); #endif closesocket(s); printf("Session terminated\n"); }
void *pv_messclient_receive(){ NET_CHANNEL *chan = NULL; message_buf rbuf; struct str_user_data * p_user_data; chan = net_openchannel (DRIVER,user_data.local_IP_udp_port); if (!chan) { fprintf (stderr,"Error opening channel.\n"); exit(ERROR); } while(1){ while (net_query (chan)){ /* If so, receive them and print them out. */ if (net_receive (chan,&rbuf,sizeof(rbuf), NULL) > 0){ p_user_data = (struct str_user_data *)( rbuf.mtext + 1 ); /* Print the message */ printf("\n# Received from IP : %s PID : %d : %s\n", p_user_data->local_IP,p_user_data->pid,rbuf.mtext+1+sizeof(struct str_user_data)); /*Write the init massage again */ printf("# IP : %s PID :%d :", user_data.local_IP, user_data.pid ); fflush(stdout); }/*if*/ }/*while*/ }/*while (1)*/ net_closechannel (chan); return OK; }
/* input function: DCC SEND - received some data */ static void dcc_send_read_size(SEND_DCC_REC *dcc) { guint32 bytes; int ret; ret = net_receive(dcc->handle, dcc->count_buf+dcc->count_pos, 4-dcc->count_pos); if (ret == -1) { dcc_close(DCC(dcc)); return; } dcc->count_pos += ret; if (dcc->count_pos != 4) return; bytes = ntohl(*((guint32 *) dcc->count_buf)); dcc->count_pos = 0; if (dcc->waitforend && bytes == (dcc->transfd & 0xffffffff)) { /* file is sent */ dcc->gotalldata = TRUE; dcc_close(DCC(dcc)); } }
static void sig_bot_read(BOT_REC *bot) { BOTNET_REC *botnet; char tmpbuf[1024], *str; int ret, recvlen, reconnect; botnet = bot->botnet; for (;;) { recvlen = bot->handle == -1 ? -1 : net_receive(bot->handle, tmpbuf, sizeof(tmpbuf)); ret = line_split(tmpbuf, recvlen, &str, (LINEBUF_REC **) &bot->buffer); if (ret == 0) break; if (ret == -1) { /* connection lost */ reconnect = !bot->disconnect && bot->uplink; bot_destroy(bot); if (reconnect) { /* wasn't intentional disconnection from our uplink, reconnect */ botnet_connect(botnet); } break; } fprintf(stderr, "%s\r\n", str); signal_emit("botnet event", 2, bot, str); } }
/* input function: DCC GET received data */ static void sig_dccget_receive(GET_DCC_REC *dcc) { char buffer[512]; int ret; for (;;) { ret = net_receive(dcc->handle, buffer, sizeof(buffer)); if (ret == 0) break; if (ret < 0) { /* socket closed - transmit complete, or other side died.. */ dcc_close(DCC(dcc)); return; } write(dcc->fhandle, buffer, ret); dcc->transfd += ret; } /* send number of total bytes received */ if (dcc->count_pos <= 0) dcc_get_send_received(dcc); signal_emit("dcc transfer update", 1, dcc); }
int main(int argc, char *argv[]) { #ifdef TCP int s = net_connect_tcp(NULL,"2334",0); #else int s = net_connect_udp("2334",0); #endif if (s < 0) { printf("Failed to connect (%d)\n",s); return 0; } printf("Connected to %d\nSending: %s\n",s,"Hello World"); int r; char *msg = "Hello World"; if (r = net_send(s,msg,strlen(msg)+1) < 0) { printf("Send error (%d, %d)\n",r,errno); return 0; } char *str; if ((str = net_receive(s)) == NULL) printf("Receive error (%d)\n",errno); else printf("Received: %s\n",str); closesocket(s); printf("Session terminated\n"); }
/* input function: DCC SERVER received some data.. */ static void dcc_server_input(SERVER_DCC_REC *dcc) { char tmpbuf[512], *str; int recvlen, ret; g_return_if_fail(IS_DCC_SERVER(dcc)); do { recvlen = net_receive(dcc->handle, tmpbuf, sizeof(tmpbuf)); ret = line_split(tmpbuf, recvlen, &str, &dcc->readbuf); if (ret == -1) { /* connection lost */ dcc_close(DCC(dcc)); break; } if (ret > 0) { dcc->transfd += ret; signal_emit("dcc server message", 2, dcc, str); } if (dcc->connection_established) { /* We set handle to NULL first because the new (chat/get) is using the same */ /* handle and we don't want dcc_close to disconnect it.*/ dcc->handle = NULL; dcc_close(DCC(dcc)); break; } } while (ret > 0); }
static void server_input(struct login_proxy *proxy) { unsigned char buf[OUTBUF_THRESHOLD]; ssize_t ret, ret2; proxy->last_io = ioloop_time; if (o_stream_get_buffer_used_size(proxy->client_output) > OUTBUF_THRESHOLD) { /* client's output buffer is already quite full. don't send more until we're below threshold. */ io_remove(&proxy->server_io); return; } ret = net_receive(proxy->server_fd, buf, sizeof(buf)); if (ret < 0) { login_proxy_free_errno(&proxy, errno, TRUE); return; } o_stream_cork(proxy->client_output); ret2 = o_stream_send(proxy->client_output, buf, ret); o_stream_uncork(proxy->client_output); if (ret2 != ret) login_proxy_free_ostream(&proxy, proxy->client_output, FALSE); }
static int cs8900_recv(struct eth_device *dev) { struct cs8900_priv *priv = (struct cs8900_priv *)dev->priv; int len = 0; u16 status; u16 *addr; int i; status = cs8900_ior(priv, PP_REG_RXEVENT); if ((status & RXEVENT_RXOK) == 0) { /* No packet received. */ return 0; } status = readw(priv->regs + CS8900_RTDATA0); len = readw(priv->regs + CS8900_RTDATA0); for (addr = (u16 *) NetRxPackets[0], i = len >> 1; i > 0; i--) { *addr++ = readw(priv->regs + CS8900_RTDATA0); } if (len & 1) { *addr++ = readw(priv->regs + CS8900_RTDATA0); } net_receive(NetRxPackets[0], len); return len; }
static int dwc_ether_rx(struct eth_device *dev) { struct dw_eth_dev *priv = dev->priv; u32 desc_num = priv->rx_currdescnum; struct dmamacdescr *desc_p = &priv->rx_mac_descrtable[desc_num]; u32 status = desc_p->txrx_status; int length = 0; /* Check if the owner is the CPU */ if (status & DESC_RXSTS_OWNBYDMA) return 0; length = (status & DESC_RXSTS_FRMLENMSK) >> \ DESC_RXSTS_FRMLENSHFT; net_receive(desc_p->dmamac_addr, length); /* * Make the current descriptor valid again and go to * the next one */ dma_inv_range((unsigned long)desc_p->dmamac_addr, (unsigned long)desc_p->dmamac_addr + length); desc_p->txrx_status |= DESC_RXSTS_OWNBYDMA; /* Test the wrap-around condition. */ if (++desc_num >= CONFIG_RX_DESCR_NUM) desc_num = 0; priv->rx_currdescnum = desc_num; return length; }
static int ar231x_eth_recv(struct eth_device *edev) { struct ar231x_eth_priv *priv = edev->priv; while (1) { struct ar231x_descr *rxdsc = priv->next_rxdsc; u32 status = rxdsc->status; /* owned by DMA? */ if (status & DMA_RX_OWN) break; /* Pick only packets what we can handle: * - only complete packet per buffer * (First and Last at same time) * - drop multicast */ if (!priv->kill_rx_ring && ((status & DMA_RX_MASK) == DMA_RX_FSLS)) { u16 length = ((status >> DMA_RX_LEN_SHIFT) & 0x3fff) - CRC_LEN; net_receive(edev, (void *)rxdsc->buffer_ptr, length); } /* Clean descriptor. now it is owned by DMA. */ priv->next_rxdsc = (struct ar231x_descr *)rxdsc->next_dsc_ptr; ar231x_flash_rxdsc(rxdsc); }
static int netx_eth_rx (struct eth_device *edev) { struct netx_eth_priv *priv = (struct netx_eth_priv *)edev->priv; int xcno = priv->xcno; unsigned int val, frameno, seg, len; if(!PFIFO_REG( PFIFO_FILL_LEVEL(IND_FIFO_PORT_LO(xcno)))) { return 0; } val = PFIFO_REG( PFIFO_BASE(IND_FIFO_PORT_LO(xcno)) ); frameno = (val & FIFO_PTR_FRAMENO_MASK) >> FIFO_PTR_FRAMENO_SHIFT; seg = (val & FIFO_PTR_SEGMENT_MASK) >> FIFO_PTR_SEGMENT_SHIFT; len = (val & FIFO_PTR_FRAMELEN_MASK) >> FIFO_PTR_FRAMELEN_SHIFT; /* get data */ memcpy((void*)NetRxPackets[0], (void *)(SRAM_BASE(seg) + frameno * 1560), len); /* pass to barebox */ net_receive(NetRxPackets[0], len); PFIFO_REG(PFIFO_BASE(EMPTY_PTR_FIFO(xcno))) = FIFO_PTR_SEGMENT(seg) | FIFO_PTR_FRAMENO(frameno); return 0; }
void do_client() { char obuffer[1024] = {0}, ibuffer[1024] = {0}; int obuffer_offset = 0, stop = 0; fflush (stdout); /* get anything out of the buffer */ conio_init(); show_buffer (obuffer, obuffer_offset); do { if (net_query (chan)) { int col = 10; int x = net_receive (chan, ibuffer, 1024, NULL); if (x<0) strcpy (ibuffer, "!!! (local) error reading packet"); else ibuffer[x] = 0; switch (ibuffer[0]) { case '*': col = 9; break; case '+': case '-': col = 11; break; case '!': col = 12; break; } write_to_window (ibuffer, col); show_buffer (obuffer, obuffer_offset); if (!strcmp (ibuffer, "*** go away")) stop = 1; if (!strcmp (ibuffer, "*** server shutting down")) stop = 1; } if (conio_kbhit()) { char ch = conio_getch(); switch (ch) { case 7: case 8: if (obuffer_offset) obuffer[--obuffer_offset] = 0; show_buffer (obuffer, obuffer_offset); break; case 13: net_send (chan, obuffer, strlen (obuffer)); obuffer[obuffer_offset = 0] = 0; show_buffer (obuffer, obuffer_offset); break; default: obuffer[obuffer_offset] = ch; obuffer[++obuffer_offset] = 0; show_buffer (obuffer, obuffer_offset); break; } } } while (!stop); erase_buffer(); conio_exit(); }
void init() { char temp[1024], nick[1024], addr[1024], newaddr[NET_MAX_ADDRESS_LENGTH]; NET_DRIVERLIST drv; drv = net_driverlist_create(); net_driverlist_clear (drv); net_driverlist_add (drv, netdriver); if (!net_initdrivers (drv)) { printf("Error initialising driver.\n"); exit (1); } printf ("Enter target address: "); fgets (addr, 1024, stdin); while (strchr(addr,'\n')) *strchr(addr,'\n')=0; printf ("Enter nickname: "); fgets (nick, 10, stdin); while (strchr(nick,'\n')) *strchr(nick,'\n')=0; if (!(chan = net_openchannel (netdriver, NULL))) { printf ("Unable to open channel.\n"); exit (2); } printf ("Connecting to %s...\n", addr); net_assigntarget (chan, addr); sprintf (temp, "%c%s", CHAT_MAGIC, nick); net_send (chan, temp, strlen (temp)); while ((!net_query (chan))/* && !conio_kbhit()*/); if (0/*conio_kbhit()*/) { conio_getch(); printf ("Aborted.\n"); exit (3); } { int x = net_receive (chan, temp, 1024, newaddr); if (x == -1) { printf ("Receive error.\n"); exit (5); } temp[x] = 0; } if (strcmp (temp, "OK")) { printf ("Connection refused.\n"); exit (4); } printf ("Connection accepted, redirecting... "); fflush (stdout); net_assigntarget (chan, newaddr); printf ("done.\n"); }
/* poll_listen: * Here we check for an incoming connection, and if there is one we * fill in `newconn' with our data pointer for it and the addresses, * and return nonzero. Otherwise return 0. */ static int poll_listen (NET_CONN *conn, NET_CONN *newconn) { struct conn_data_t *data; char buffer[12], buffer2[8+NET_MAX_ADDRESS_LENGTH] = { 0, 0, 0, 0, 0, 0, 0, 0 }; char addr[NET_MAX_ADDRESS_LENGTH]; int x; int count = 32; /* maximum number of packets to process */ while (net_query (((struct conn_data_t *)conn->data)->chan) && count-- > 0) { if ((net_receive (((struct conn_data_t *)conn->data)->chan, buffer, 12, addr) == 12) && !memcmp (buffer, "connect", 8)) { newconn->data = data = malloc (sizeof *data); if (!data) continue; if (create_queues (newconn)) { free (data); continue; } data->conns = NULL; x = get_channel ( ((struct conn_data_t *)conn->data)->conns, addr, (buffer[8] << 24) + (buffer[9] << 16) + (buffer[10] << 8) + buffer[11], conn->type, NULL, &data->chan, data ); if (x) { data->referer = conn->data; /* tell new channel where to send in future */ net_assigntarget (data->chan, addr); /* send reply now with address of new channel, through * listening conn so it can get through NATs */ net_assigntarget (((struct conn_data_t *)conn->data)->chan, addr); strcpy (buffer2+8, net_getlocaladdress (data->chan)); net_send (((struct conn_data_t *)conn->data)->chan, buffer2, 8+NET_MAX_ADDRESS_LENGTH); } if (x >= 0) { destroy_queues (newconn); free (data); continue; } strcpy (newconn->peer_addr, addr); return 1; } } return 0; }
static int macb_recv(struct eth_device *edev) { struct macb_device *macb = edev->priv; unsigned int rx_tail = macb->rx_tail; void *buffer; int length; int wrapped = 0; u32 status; // printf("%s\n", __func__); for (;;) { if (!(macb->rx_ring[rx_tail].addr & RXADDR_USED)) return -1; status = macb->rx_ring[rx_tail].ctrl; if (status & RXBUF_FRAME_START) { if (rx_tail != macb->rx_tail) reclaim_rx_buffers(macb, rx_tail); wrapped = 0; } if (status & RXBUF_FRAME_END) { buffer = macb->rx_buffer + 128 * macb->rx_tail; length = status & RXBUF_FRMLEN_MASK; if (wrapped) { unsigned int headlen, taillen; headlen = 128 * (CFG_MACB_RX_RING_SIZE - macb->rx_tail); taillen = length - headlen; memcpy((void *)NetRxPackets[0], buffer, headlen); memcpy((void *)NetRxPackets[0] + headlen, macb->rx_buffer, taillen); buffer = (void *)NetRxPackets[0]; } net_receive(buffer, length); if (++rx_tail >= CFG_MACB_RX_RING_SIZE) rx_tail = 0; reclaim_rx_buffers(macb, rx_tail); } else { if (++rx_tail >= CFG_MACB_RX_RING_SIZE) { wrapped = 1; rx_tail = 0; } } barrier(); } return 0; }
int tap_eth_rx (struct eth_device *edev) { struct tap_priv *priv = edev->priv; int length; length = linux_read_nonblock(priv->fd, NetRxPackets[0], PKTSIZE); if (length > 0) net_receive(NetRxPackets[0], length); return 0; }
static void sig_disconnect(NET_DISCONNECT_REC *rec) { char buf[128]; int ret; /* check if there's any data waiting in socket */ while ((ret = net_receive(rec->handle, buf, sizeof(buf))) > 0) ; if (ret == -1) { /* socket was closed */ net_disconnect_remove(rec); } }
static size_t mcp_receive_packet(mcp_packet_t *packet) { byte buf[3]; // three bytes to obtain packet size + ID size_t len = net_receive(mcp_socket, buf, 3); if (len == 3) { packet->len = *(word *)buf; packet->id = net_get_data(buf, sizeof(word), byte); size_t data_len = packet->len - MCP_HEADER_SIZE; if (data_len) { packet->data = (byte *) malloc(data_len); len += net_receive(mcp_socket, packet->data, data_len); if (len != packet->len) { free(packet->data); return -1; } } if (setting("Verbose")->b_var) { ui_console_lock(); print("[MCP] received:\n\n"); mcp_dump_packet(*packet); print("\n"); ui_console_unlock(); } return packet->len; } else { return -1; } }
static inline bool wait_reply(const char *name, struct net_context *ctx, int ipsum_len, int pos) { struct net_buf *buf; bool fail = false; int expected_len = ipsum_len - pos; /* Wait for the answer */ buf = net_receive(ctx, WAIT_TICKS); if (buf) { if (ip_buf_appdatalen(buf) != expected_len) { PRINT("%s: received %d bytes, expected %d\n", name, ip_buf_appdatalen(buf), expected_len); fail = true; goto free_buf; } /* In this test we reverse the received bytes. * We could just pass the data back as is but * this way it is possible to see how the app * can manipulate the received data. */ reverse(ip_buf_appdata(buf), ip_buf_appdatalen(buf)); /* Did we get all the data back? */ if (memcmp(lorem_ipsum + pos, ip_buf_appdata(buf), expected_len)) { PRINT("%s: received data mismatch.\n", name); fail = true; goto free_buf; } PRINT("%s: received %d bytes\n", __func__, expected_len); free_buf: ip_buf_unref(buf); } else { PRINT("%s: expected data, got none\n", name); fail = true; } return fail; }
static void sig_disconnect(NET_DISCONNECT_REC *rec) { char buf[512]; int count, ret; /* check if there's any data waiting in socket. read max. 5kB so if server just keeps sending us stuff we won't get stuck */ count = 0; do { ret = net_receive(rec->handle, buf, sizeof(buf)); if (ret == -1) { /* socket was closed */ net_disconnect_remove(rec); } count++; } while (ret == sizeof(buf) && count < 10); }
static int arc_emac_recv(struct eth_device *edev) { struct arc_emac_priv *priv = edev->priv; unsigned int work_done; for (work_done = 0; work_done < RX_BD_NUM; work_done++) { unsigned int *last_rx_bd = &priv->last_rx_bd; struct arc_emac_bd *rxbd = &priv->rxbd[*last_rx_bd]; unsigned int pktlen, info = le32_to_cpu(rxbd->info); if (unlikely((info & OWN_MASK) == FOR_EMAC)) break; /* * Make a note that we saw a packet at this BD. * So next time, driver starts from this + 1 */ *last_rx_bd = (*last_rx_bd + 1) % RX_BD_NUM; if (unlikely((info & FIRST_OR_LAST_MASK) != FIRST_OR_LAST_MASK)) { /* * We pre-allocate buffers of MTU size so incoming * packets won't be split/chained. */ printk(KERN_DEBUG "incomplete packet received\n"); /* Return ownership to EMAC */ rxbd->info = cpu_to_le32(FOR_EMAC | PKTSIZE); continue; } pktlen = info & LEN_MASK; /* invalidate current receive buffer */ dma_inv_range((unsigned long)rxbd->data, (unsigned long)rxbd->data + pktlen); net_receive(edev, (unsigned char *)rxbd->data, pktlen); rxbd->info = cpu_to_le32(FOR_EMAC | PKTSIZE); } return work_done; }
int tcp_rx(struct net_context *ctx, uint8_t *buf, size_t *read_bytes, size_t size) { struct net_buf *nbuf; int rc; nbuf = net_receive(ctx, TCP_RX_TIMEOUT); rc = -EIO; if (nbuf != NULL) { *read_bytes = ip_buf_appdatalen(nbuf); if (*read_bytes > size) { rc = -ENOMEM; } else { memcpy(buf, ip_buf_appdata(nbuf), *read_bytes); rc = 0; } ip_buf_unref(nbuf); } return rc; }
/* Copied from tyndur */ static void receiveData(struct rtl8139_card *card) { while (1) { uint8_t command = int_in8(card, REG_COMMAND); if (command & CR_BUFFER_IS_EMPTY) break; char *rxBuffer = card->rxBuffer + card->rxBufferOffset; uint16_t pHeader = *((uint16_t *)rxBuffer); rxBuffer += 2; if ((pHeader & 1) == 0) break; uint16_t length = *((uint16_t *)rxBuffer); rxBuffer += 2; card->rxBufferOffset += 4; if (length >= sizeof(ether_frame_hdr_t)) { uint8_t *data = kmalloc(length - 4); if ((card->rxBufferOffset + length - 4) >= RX_BUFFER_SIZE) { memcpy(data, rxBuffer, RX_BUFFER_SIZE - card->rxBufferOffset); memcpy(data + RX_BUFFER_SIZE - card->rxBufferOffset, card->rxBuffer, (length - 4) - (RX_BUFFER_SIZE - card->rxBufferOffset)); } else memcpy(data, rxBuffer, length - 4); net_receive(card->netDevice, NET_PROTO_ETH, length - 4, data); } card->rxBufferOffset += length; card->rxBufferOffset = (card->rxBufferOffset + 3) & ~0x3; card->rxBufferOffset %= RX_BUFFER_SIZE; } }