// obs³u¿ pakiet void announce_handle_packet(unsigned char* data, unsigned int len) { // wype³nij pakiet (nazwa urz¹dzenia, adres MAC, sygnaturka) len = 0; // skonfigurowana nazwa urz¹dzenia config_t* config_get(); strcpy(config_ram.name, (char*)data+len); len += strlen((char*)data); // ³amanie wiersza memcpy_P(PSTR("\r\n"), data+len, 2); len += 2; // adres MAC (w formacie "human-readable") unsigned char *mac = nic_get_mac(); for (unsigned char i=0; i<6; i++) { data[len++] = dec2hex(mac[i] >> 4); data[len++] = dec2hex(mac[i] & 0x0f); if (i<5) data[len++] = '-'; } // ³amanie wiersza memcpy_P(PSTR("\r\n"), data+len, 2); len += 2; // sygnaturka strcpy_P(RS2ETH_SIGNATURE, (char*)data+len); len += strlen_P(RS2ETH_SIGNATURE); rs_dump(data, len); // utwórz "po³¹czenie" UDP (odpowiedŸ) struct uip_udp_conn* conn; conn = uip_udp_new(&uip_udp_conn->ripaddr, uip_udp_conn->rport); if (!conn) { return; } // wyœlij z portu konfiguracyjnego uip_udp_bind(conn, HTONS(ANNOUNCE_PORT)); // wyœlij uip_udp_send(len + 10); // czekaj na wys³anie nic_wait_for_send(); // zamknij po³¹czenia UDP (przychodz¹cy broadcast i wychodz¹cy unicast) uip_udp_remove(conn); uip_udp_remove(uip_udp_conn); }
// Finish with the UDP socket void UIPUDP::stop() { if (_uip_udp_conn) { flush(); uip_udp_remove(_uip_udp_conn); _uip_udp_conn->appstate.user = NULL; _uip_udp_conn=NULL; if (appdata.packet_in != NOBLOCK) { UIPEthernet.network.freeBlock(appdata.packet_in); appdata.packet_in = NOBLOCK; } uint8_t i = 0; memhandle* packet = &appdata.packets_in[0]; while (*packet != NOBLOCK && i < UIP_UDP_NUMPACKETS) { UIPEthernet.network.freeBlock(*packet); *packet++ = NOBLOCK; i++; } if (appdata.packet_out != NOBLOCK) { UIPEthernet.network.freeBlock(appdata.packet_out); appdata.packet_out = NOBLOCK; } } }
void ntp_conf(uip_ipaddr_t *ntpserver) { if (ntp_conn != NULL) uip_udp_remove(ntp_conn); ntp_conn = uip_udp_new(ntpserver, HTONS(NTP_PORT), ntp_newdata); }
///////////////////////////////////////////////////////////////////////////// // Initialize the OSC daemon ///////////////////////////////////////////////////////////////////////////// s32 OSC_SERVER_Init(u32 mode) { // disable send packet osc_send_packet = NULL; // remove open connection if(osc_conn != NULL) { uip_udp_remove(osc_conn); } // create new connection uip_ipaddr_t ripaddr; uip_ipaddr(ripaddr, ((OSC_REMOTE_IP)>>24) & 0xff, ((OSC_REMOTE_IP)>>16) & 0xff, ((OSC_REMOTE_IP)>> 8) & 0xff, ((OSC_REMOTE_IP)>> 0) & 0xff); if( (osc_conn=uip_udp_new(&ripaddr, HTONS(OSC_SERVER_PORT))) != NULL ) { uip_udp_bind(osc_conn, HTONS(OSC_SERVER_PORT)); #if DEBUG_VERBOSE_LEVEL >= 1 MIOS32_MIDI_SendDebugMessage("[OSC_SERVER] listen to %d.%d.%d.%d:%d\n", (osc_conn->ripaddr[0] >> 0) & 0xff, (osc_conn->ripaddr[0] >> 8) & 0xff, (osc_conn->ripaddr[1] >> 0) & 0xff, (osc_conn->ripaddr[1] >> 8) & 0xff, HTONS(osc_conn->rport)); #endif } else {
void smcp_plat_finalize(smcp_t self) { SMCP_EMBEDDED_SELF_HOOK; if(self->plat.udp_conn) { uip_udp_remove(self->plat.udp_conn); } }
/*---------------------------------------------------------------------------*/ void udpds_conf(u16_t *to_ip, u16_t to_port, u8_t interval) { if(udpds_conn != NULL) { uip_udp_remove(udpds_conn); } timer_set(&udpds_interval_timer, (CLOCK_CONF_SECOND * interval)); udpds_conn = uip_udp_new((uip_ipaddr_t *)to_ip, HTONS(to_port)); }
void coap_free_endpoint(coap_endpoint_t *ep) { if (ep) { if (ep->handle.conn) { uip_udp_remove((struct uip_udp_conn *)ep->handle.conn); } coap_free_contiki_endpoint(ep); } }
void NetworkSocket_Free(NetworkSocket ** networkSocket) { if (networkSocket && *networkSocket) { if ((*networkSocket)->Socket) uip_udp_remove((*networkSocket)->Socket); free(*networkSocket); *networkSocket = NULL; } }
static void tftpupdate_cleanup(void) { if (tftpupdate) { if (tftpupdate->s.conn) { uip_udp_remove(tftpupdate->s.conn); tftpupdate->s.conn = NULL; } free(tftpupdate); tftpupdate = NULL; } }
/*---------------------------------------------------------------------------*/ void resolv_conf(const u16_t *dnsserver) { uip_ipaddr_t da; if(resolv_conn != NULL) { uip_udp_remove(resolv_conn); } uip_ipaddr_copy(&da,dnsserver); resolv_conn = uip_udp_new(&da, UIP_HTONS(53),resolv_appcall); }
/*---------------------------------------------------------------------------*/ void coap_context_close(coap_context_t *coap_ctx) { if(coap_ctx == NULL || coap_ctx->is_used == 0) { /* Not opened */ return; } if(coap_ctx->buf && uip_udp_conn(coap_ctx->buf) != NULL) { uip_udp_remove(uip_udp_conn(coap_ctx->buf)); } coap_ctx->is_used = 0; }
/*---------------------------------------------------------------------------*/ int udp_socket_close(struct udp_socket *c) { if(c == NULL) { return -1; } if(c->udp_conn != NULL) { uip_udp_remove(c->udp_conn); return 1; } return -1; }
void dhcpc_configured(const struct dhcpc_state *s) { if(s == 0) { set_eeprom_addr(); return; } ewip(s->ipaddr, EE_IP4_ADDR); uip_sethostaddr(s->ipaddr); ewip(s->default_router, EE_IP4_GATEWAY); uip_setdraddr(s->default_router); ewip(s->netmask, EE_IP4_NETMASK); uip_setnetmask(s->netmask); //resolv_conf(s->dnsaddr); uip_udp_remove(s->conn); ip_initialized(); }
// Finish with the UDP socket void UIPUDP::stop() { if (_uip_udp_conn) { uip_udp_remove(_uip_udp_conn); _uip_udp_conn->appstate = NULL; _uip_udp_conn=NULL; Enc28J60Network::freeBlock(appdata.packet_in); Enc28J60Network::freeBlock(appdata.packet_next); Enc28J60Network::freeBlock(appdata.packet_out); memset(&appdata,0,sizeof(appdata)); } }
// Finish with the UDP socket void UIPUDP::stop() { if (_uip_udp_conn) { uip_udp_remove(_uip_udp_conn); _uip_udp_conn->appstate = NULL; _uip_udp_conn=NULL; UIPEthernetClass::network.freeBlock(appdata.packet_in); UIPEthernetClass::network.freeBlock(appdata.packet_next); UIPEthernetClass::network.freeBlock(appdata.packet_out); memset(&appdata,0,sizeof(appdata)); } }
/** * Function to send a packet to a destination host * @param ip ip address of packet destination host * @param port port to use at the destination/local hosts * @param data packet data pointer * @param len packet data length * \return 1 if packet successfully stored, 0 if connection not possible, -1 if packet not sent yet * @note * - The packet is not sent immediately. The information is stored in an * intermediate variable and sent in the next UDP polling event */ int udp_frame_send(uip_ipaddr_t ip, int port, char* data, int len) { int i; struct uip_udp_conn* conn; port = htons(port); if( len < 0 || data == NULL ) return 0; // Check if there is an existing connection for( i = 0; i < UIP_UDP_CONNS; i++ ) { if( uip_udp_conns[i].rport != port || uip_udp_conns[i].lport != port || !uip_ipaddr_cmp( uip_udp_conns[i].ripaddr, ip ) ) continue; if( udp_frame_pi[i].length > 0 ) return 0; udp_frame_pi[i].conn = &uip_udp_conn[i]; udp_frame_pi[i].data = data; udp_frame_pi[i].length = len; udp_frame_pi[i].age = 0; return 1; } // Create new connection conn = uip_udp_new( (uip_ipaddr_t*) ip, port ); if( conn == NULL ) { int oldest = 0; // remove oldest connection to create a new one for( i = 1; i < UIP_UDP_CONNS; i++ ) { if( udp_frame_pi[i].age > udp_frame_pi[oldest].age ) oldest = i; } uip_udp_remove( udp_frame_pi[oldest].conn ); conn = uip_udp_new( (uip_ipaddr_t*) ip, port ); if( conn == NULL ) return 0; } // Update connection ages and data uip_udp_bind( conn, port ); for( i = 0; i < UIP_UDP_CONNS; i++ ) { if( &uip_udp_conns[i] == conn ) { udp_frame_pi[i].conn = conn; udp_frame_pi[i].data = data; udp_frame_pi[i].length = len; udp_frame_pi[i].age = 0; }else{ if( udp_frame_pi[i].conn != NULL && udp_frame_pi[i].age < AGE_MAX ) udp_frame_pi[i].age++; // Update age of connections } } // Store packet information to be sent return 1; }
/*---------------------------------------------------------------------------*/ coap_context_t * coap_context_new(uip_ipaddr_t *my_addr, uint16_t port) { coap_context_t *ctx = NULL; int i; for(i = 0; i < MAX_CONTEXTS; i++) { if(!coap_contexts[i].is_used) { ctx = &coap_contexts[i]; break; } } if(ctx == NULL) { PRINTF("coap-context: no free contexts\n"); return NULL; } memset(ctx, 0, sizeof(coap_context_t)); /* initialize context */ ctx->dtls_context = dtls_new_context(ctx); if(ctx->dtls_context == NULL) { PRINTF("coap-context: failed to get DTLS context\n"); uip_udp_remove(uip_udp_conn(ctx->buf)); return NULL; } ctx->dtls_handler.write = send_to_peer; ctx->dtls_handler.read = get_from_peer; ctx->dtls_handler.event = event; dtls_set_handler(ctx->dtls_context, &ctx->dtls_handler); #ifdef NETSTACK_CONF_WITH_IPV6 memcpy(&ctx->my_addr.in6_addr, my_addr, sizeof(ctx->my_addr.in6_addr)); #else memcpy(&ctx->my_addr.in_addr, my_addr, sizeof(ctx->my_addr.in_addr)); #endif ctx->my_port = port; ctx->process = PROCESS_CURRENT(); ctx->is_used = 1; PRINTF("Secure listening on port %u\n", port); return ctx; }
// wyœlij pakiet powitalny (broadcast z aktualnymi ustawieniami) void udp_config_send_hello_packet(unsigned char* data) { // pakiet udp_config_packet *packet = (udp_config_packet*) data; // nag³ówek + dane packet->start = UDP_CONFIG_MAGIC; packet->type = UDP_CONFIG_TYPE_HELLO; memcpy(packet->mac, nic_get_mac(), 6); packet->length = udp_config_fill(packet->data); // wyœlij uip_udp_send(packet->length + 10); nic_wait_for_send(); // zamknij aktualne "po³¹czenie" UDP uip_udp_remove(uip_udp_conn); }
static void netUdpAppcallMutex(NetSock* sock) { if (uip_newdata()) { bool timeout = false; while (sock->state != NET_SOCK_READING && !timeout) { posMutexUnlock(sock->mutex); timeout = posFlagWait(sock->sockChange, MS(500)) == 0; posMutexLock(sock->mutex); } if (!timeout) { if (uip_datalen() > sock->max) sock->len = sock->max; else sock->len = uip_datalen(); memcpy(sock->buf, uip_appdata, sock->len); sock->state = NET_SOCK_READ_OK; posFlagSet(sock->uipChange, 0); } } if (uip_poll()) { if (sock->state == NET_SOCK_CLOSE) { uip_udp_remove(uip_udp_conn); netAppcallClose(sock, NET_SOCK_CLOSE_OK); } else if (sock->state == NET_SOCK_WRITING) { memcpy(uip_appdata, sock->buf, sock->len); uip_udp_send(sock->len); sock->state = NET_SOCK_WRITE_OK; posFlagSet(sock->uipChange, 0); } } }
static void dhcpd_address_assigned() { #ifdef USE_UDP if (app_conn) uip_udp_remove(app_conn); printf("setting up app connection "); app_conn = uip_udp_new(&dhcpd_client_ipaddr, HTONS(1208) /* remote port */); if (app_conn != NULL) { uip_udp_bind(app_conn, HTONS(1208) /* local port */); } bc_conn = uip_udp_new(&dhcpd_broadcast_ipaddr, HTONS(1208) /* remote port */); if (bc_conn != NULL) { uip_udp_bind(bc_conn, HTONS(1208) /* local port */); } #else // we can only close the current connection, so we can't do it here; must do it in a poll handler or something //if (app_conn) uip_close(app_conn); printf("setting up app connection "); app_conn = uip_connect(&dhcpd_client_ipaddr, HTONS(1208) /* remote port */); #endif }
void dhcp_set_static(void) { uip_ipaddr_t ip; (void) ip; /* Keep GCC quiet. */ /* Configure the IP address. */ #ifdef EEPROM_SUPPORT /* Please Note: ip and &ip are NOT the same (cpp hell) */ eeprom_restore_ip(ip, &ip); #else set_CONF_ETHERRAPE_IP(&ip); #endif uip_sethostaddr(&ip); /* Configure the netmask (IPv4). */ #ifdef EEPROM_SUPPORT /* Please Note: ip and &ip are NOT the same (cpp hell) */ eeprom_restore_ip(netmask, &ip); #else set_CONF_ETHERRAPE_IP4_NETMASK(&ip); #endif uip_setnetmask(&ip); /* Configure the default gateway */ #ifdef EEPROM_SUPPORT /* Please Note: ip and &ip are NOT the same (cpp hell) */ eeprom_restore_ip(gateway, &ip); #else set_CONF_ETHERRAPE_GATEWAY(&ip); #endif uip_setdraddr(&ip); /* Remove the bootp connection */ uip_udp_remove(uip_udp_conn); }
int dhcp_release(uip_ipaddr_t server_ip) { DhcpPacket release; // Set up the UDP connection. struct uip_udp_conn *conn = uip_udp_new(&server_ip, htonw(DhcpServerPort)); if (!conn) { printf("Failed to set up UDP connection.\n"); return 1; } uip_udp_bind(conn, htonw(DhcpClientPort)); // Prepare the DHCP release packet. dhcp_prep_packet(&release, rand()); uip_ipaddr_t my_ip; uip_gethostaddr(&my_ip); release.client_ip = (uip_ipaddr1(&my_ip) << 0) | (uip_ipaddr2(&my_ip) << 8) | (uip_ipaddr3(&my_ip) << 16) | (uip_ipaddr4(&my_ip) << 24); uint8_t *options = release.options; int remaining = sizeof(release.options); uint8_t byte = DhcpRelease; dhcp_add_option(&options, DhcpTagMessageType, &byte, sizeof(byte), &remaining); dhcp_add_option(&options, DhcpTagEndOfList, NULL, 0, &remaining); // Call uip_udp_packet_send directly since we won't get a reply. uip_udp_packet_send(conn, &release, sizeof(release)); dhcp_state = DhcpInit; uip_udp_remove(conn); return 0; }
void dhcp_net_main(void) { if(uip_newdata()) { switch (uip_udp_conn->appstate.dhcp.state) { case STATE_DISCOVERING: if (parse_msg() == DHCPOFFER) { send_request(); uip_flags &= ~UIP_NEWDATA; uip_udp_conn->appstate.dhcp.state = STATE_REQUESTING; uip_udp_conn->appstate.dhcp.retry_timer = 2; // retry uip_udp_conn->appstate.dhcp.retry_counter = 1; tick_sec = 0; } break; case STATE_REQUESTING: if (parse_msg() == DHCPACK) { uip_udp_conn->appstate.dhcp.state = STATE_CONFIGURED; uip_sethostaddr(uip_udp_conn->appstate.dhcp.ipaddr); uip_setdraddr(uip_udp_conn->appstate.dhcp.default_router); uip_setnetmask(uip_udp_conn->appstate.dhcp.netmask); #ifdef DNS_SUPPORT resolv_conf(uip_udp_conn->appstate.dhcp.dnsaddr); // eeprom_save(dns_server, &uip_udp_conn->appstate.dhcp.dnsaddr, IPADDR_LEN); #endif // eeprom_save(ip, &uip_udp_conn->appstate.dhcp.ipaddr, IPADDR_LEN); // eeprom_save(netmask, &uip_udp_conn->appstate.dhcp.netmask, IPADDR_LEN); // eeprom_save(gateway, &uip_udp_conn->appstate.dhcp.default_router, IPADDR_LEN); // eeprom_update_chksum(); /* Remove the bootp connection */ uip_udp_remove(uip_udp_conn); } break; } } else { // No data yet switch (uip_udp_conn->appstate.dhcp.state) { case STATE_INITIAL: case STATE_DISCOVERING: if (tick_sec>uip_udp_conn->appstate.dhcp.retry_timer) { send_discover(); uip_flags &= ~UIP_NEWDATA; uip_udp_conn->appstate.dhcp.state = STATE_DISCOVERING; if (uip_udp_conn->appstate.dhcp.retry_counter++>10) return dhcp_set_static(); uip_udp_conn->appstate.dhcp.retry_timer = 2 * uip_udp_conn->appstate.dhcp.retry_counter; // retry tick_sec = 0; } break; case STATE_REQUESTING: if (tick_sec>uip_udp_conn->appstate.dhcp.retry_timer) { send_request(); uip_flags &= ~UIP_NEWDATA; if (uip_udp_conn->appstate.dhcp.retry_counter++>10) return dhcp_set_static(); uip_udp_conn->appstate.dhcp.retry_timer = 2; // retry tick_sec = 0; } break; } } }
/*---------------------------------------------------------------------------*/ static void timeout_handler(void) { static int seq_id; char buf[MAX_PAYLOAD_LEN]; int i; uip_ip6addr_t *globaladdr = NULL; uint16_t dest_port = CETIC_6LBR_NODE_INFO_PORT; int has_dest = 0; rpl_dag_t *dag; uip_ds6_addr_t *addr_desc = uip_ds6_get_global(ADDR_PREFERRED); if(addr_desc != NULL) { globaladdr = &addr_desc->ipaddr; dag = rpl_get_any_dag(); if(dag) { uip_ipaddr_copy(&dest_addr, globaladdr); memcpy(&dest_addr.u8[8], &dag->dag_id.u8[8], sizeof(uip_ipaddr_t) / 2); has_dest = 1; } } if(has_dest) { if(client_conn == NULL) { PRINTF("UDP-CLIENT: address destination: "); PRINT6ADDR(&dest_addr); PRINTF("\n"); client_conn = udp_new(&dest_addr, UIP_HTONS(dest_port), NULL); if(client_conn != NULL) { PRINTF("Created a connection with the server "); PRINT6ADDR(&client_conn->ripaddr); PRINTF(" local/remote port %u/%u\n", UIP_HTONS(client_conn->lport), UIP_HTONS(client_conn->rport)); } else { PRINTF("Could not open connection\n"); } } else { if(memcmp(&client_conn->ripaddr, &dest_addr, sizeof(uip_ipaddr_t)) != 0) { PRINTF("UDP-CLIENT: new address destination: "); PRINT6ADDR(&dest_addr); PRINTF("\n"); uip_udp_remove(client_conn); client_conn = udp_new(&dest_addr, UIP_HTONS(dest_port), NULL); if(client_conn != NULL) { PRINTF("Created a connection with the server "); PRINT6ADDR(&client_conn->ripaddr); PRINTF(" local/remote port %u/%u\n", UIP_HTONS(client_conn->lport), UIP_HTONS(client_conn->rport)); } else { PRINTF("Could not open connection\n"); } } } if(client_conn != NULL) { PRINTF("Client sending to: "); PRINT6ADDR(&client_conn->ripaddr); i = sprintf(buf, "%d | ", ++seq_id); dag = rpl_get_any_dag(); if(dag && dag->instance->def_route) { add_ipaddr(buf + i, &dag->instance->def_route->ipaddr); } else { sprintf(buf + i, "(null)"); } PRINTF(" (msg: %s)\n", buf); uip_udp_packet_send(client_conn, buf, strlen(buf)); } else { PRINTF("No connection created\n"); } } else { PRINTF("No address configured\n"); } }
/*---------------------------------------------------------------------------*/ static PT_THREAD(handle_dhcp(void)) { PT_BEGIN(&s.pt); #if defined PORT_APP_MAPPER dhcpc_running = 1; #endif if (s.state == STATE_RENEW) goto send_request_section; /* try_again:*/ s.state = STATE_SENDING; s.ticks = CLOCK_SECOND; //sendString("\r\ndhcpc handle dhcp passed: STATE_SENDING"); do { send_discover(); timer_set(&s.timer, s.ticks); // NOTE: fixed as per http://www.mail-archive.com/[email protected]/msg00003.html PT_YIELD_UNTIL(&s.pt, uip_newdata() || timer_expired(&s.timer)); //sendString("Just got something\n\r"); if(uip_newdata()) { //sendString("Data\n\r"); if (parse_msg() == DHCPOFFER) { s.state = STATE_OFFER_RECEIVED; break; } } else { //sendString("Timeout\n\r"); if(s.ticks < CLOCK_SECOND * 60) { s.ticks *= 2; } else { s.ticks = CLOCK_SECOND; } } } while(s.state != STATE_OFFER_RECEIVED); //sendString("\r\ndhcpc handle dhcp passed: STATE_OFFER_RECEIVED"); s.ticks = CLOCK_SECOND; send_request_section: do { send_request(); timer_set(&s.timer, s.ticks); // NOTE: fixed as per http://www.mail-archive.com/[email protected]/msg00003.html PT_YIELD_UNTIL(&s.pt, uip_newdata() || timer_expired(&s.timer)); if(uip_newdata()) { msg_type = parse_msg(); if (msg_type == DHCPACK) { s.state = STATE_CONFIG_RECEIVED; break; } else if (msg_type == DHCPNAK) { s.state = STATE_FAIL; goto close_and_clean_up; } } else { if(s.ticks <= CLOCK_SECOND * 10) { s.ticks += CLOCK_SECOND; } else { PT_RESTART(&s.pt); //sendString("\r\ndhcpc handle RESTARTING!"); } } } while(s.state != STATE_CONFIG_RECEIVED); //sendString("\r\ndhcpc handle dhcp passed: STATE_CONFIG_RECEIVED"); #if DEBUG_SERIAL printf_P(PSTR("Got IP address %d.%d.%d.%d\r\n"), uip_ipaddr1(s.ipaddr), uip_ipaddr2(s.ipaddr), uip_ipaddr3(s.ipaddr), uip_ipaddr4(s.ipaddr)); printf_P(PSTR("Got netmask %d.%d.%d.%d\r\n"), uip_ipaddr1(s.netmask), uip_ipaddr2(s.netmask), uip_ipaddr3(s.netmask), uip_ipaddr4(s.netmask)); printf_P(PSTR("Got DNS server %d.%d.%d.%d\r\n"), uip_ipaddr1(s.dnsaddr), uip_ipaddr2(s.dnsaddr), uip_ipaddr3(s.dnsaddr), uip_ipaddr4(s.dnsaddr)); printf_P(PSTR("Got default router %d.%d.%d.%d\r\n"), uip_ipaddr1(s.default_router), uip_ipaddr2(s.default_router), uip_ipaddr3(s.default_router), uip_ipaddr4(s.default_router)); printf_P(PSTR("Lease expires in %ld seconds\r\n"), ntohs(s.lease_time[0])*65536ul + ntohs(s.lease_time[1])); #endif dhcpc_configured(&s); /* timer_stop(&s.timer);*/ /* * PT_END restarts the thread so we do this instead. Eventually we * should reacquire expired leases here. */ /* while(1) { PT_YIELD(&s.pt); } */ close_and_clean_up: #if defined PORT_APP_MAPPER dhcpc_running = 0; #endif // all done with the connection, clean up uip_udp_remove(s.conn); s.conn = NULL; //sendString("\r\ndhcpc handle dhcp passed: END"); PT_END(&s.pt); }
PROCESS_THREAD(tftpd_process, ev, data) { static struct etimer t; static tftp_header *h; static int len, block, ack; static int tries; static int fd = -1; #if WITH_EXEC static char *elf_err; #endif PROCESS_BEGIN(); etimer_set(&t, CLOCK_CONF_SECOND*3); PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER); setup_server(); #if WITH_EXEC elfloader_init(); #endif print_local_addresses(); while(1) { /* connection from client */ RECV_PACKET(h); len = 0; init_config(); if(h->op == uip_htons(TFTP_RRQ)) { connect_back(); PRINTF("< rrq for %s\n", h->filename); len += strlen(h->filename)+1; if(strcmp("octet", h->filename+len)) { send_error(EUNDEF, "only octet mode supported"); goto close_connection; } len += strlen(h->filename+len)+1; /* skip mode */ parse_opts(h->options+len, uip_datalen()-len-2); if(config.to_ack & OACK_ERROR) { send_error(EOPTNEG, ""); goto close_connection; } fd = cfs_open(h->filename, CFS_READ); if(fd<0) { send_error(ENOTFOUND, ""); goto close_connection; } block = 0; ack = 0; tries = TFTP_MAXTRIES; PRINTF("starting transfer...\n"); for(;;) { if(send_oack()) len = config.blksize; /* XXX hack to prevent loop exit*/ else len = send_data(fd, block+1); if(len<0) { send_error(EUNDEF, "read failed"); goto close_file; } RECV_PACKET_TIMEOUT(h,t); if(ev == PROCESS_EVENT_TIMER) { PRINTF("ack timed out, tries left: %d\n", tries); if(--tries<=0) goto close_file; continue; } if(h->op != uip_htons(TFTP_ACK)) { send_error(EBADOP, ""); goto close_file; } config.to_ack = 0; tries = TFTP_MAXTRIES; ack = uip_htons(h->block_nr); if(ack == block+1) block++; if(len < config.blksize && ack == block) goto done; } } else if(h->op == uip_htons(TFTP_WRQ)) { connect_back(); PRINTF("< wrq for %s\n", h->filename); len += strlen(h->filename)+1; strncpy(config.filename, h->filename, sizeof(config.filename)-1); if(strcmp("octet", h->filename+strlen(h->filename)+1)) { send_error(EUNDEF, "only octet mode supported"); goto close_connection; } len += strlen(h->filename+len)+1; /* skip mode */ parse_opts(h->options+len, uip_datalen()-len-2); if(config.to_ack & OACK_ERROR) { send_error(EOPTNEG, ""); goto close_connection; } cfs_remove(h->filename); fd = cfs_open(h->filename, CFS_WRITE); if(fd<0) { send_error(EACCESS, ""); goto close_connection; } block = 0; ack = 0; tries = TFTP_MAXTRIES; PRINTF("starting transfer...\n"); if(!send_oack()) send_ack(block); for(;;) { RECV_PACKET_TIMEOUT(h,t); if(ev == PROCESS_EVENT_TIMER) { PRINTF("data timed out, tries left: %d\n", tries); if(--tries<=0) goto close_file; len = config.blksize; /* XXX hack to prevent loop exit*/ goto resend_ack; } if(h->op != uip_htons(TFTP_DATA)) { send_error(EBADOP, ""); goto close_file; } config.to_ack = 0; tries = TFTP_MAXTRIES; ack = uip_htons(h->block_nr); if(ack != block+1) continue; /* else */ block++; len = recv_data(fd, block); if(len<0) { send_error(EUNDEF, "write failed"); goto close_file; } #if WITH_EXEC if(len < config.blksize) { if(config.exec) { if(exec_file(config.filename, &elf_err) != 0) { send_error(EUNDEF, elf_err); goto close_file; } } } #endif resend_ack: if(!send_oack()) send_ack(block); if(len < config.blksize) goto done; } } done: PRINTF("done.\n"); close_file: if(fd>=0) cfs_close(fd); fd = -1; close_connection: if(client_conn) uip_udp_remove(client_conn); client_conn = 0; PRINTF("connection closed.\n"); } PROCESS_END(); }
int dhcp_request(uip_ipaddr_t *next_ip, uip_ipaddr_t *server_ip, const char **bootfile) { DhcpPacket out, in; uint8_t byte; uint8_t *options; int remaining; uint8_t requested[] = { DhcpTagSubnetMask, DhcpTagDefaultRouter }; assert(DhcpMaxPacketSize >= DhcpMinPacketSize); uint16_t max_size = htonw(DhcpMaxPacketSize); uint8_t client_id[1 + sizeof(uip_ethaddr)]; client_id[0] = DhcpEthernet; memcpy(client_id + 1, &uip_ethaddr, sizeof(uip_ethaddr)); // Set up the UDP connection. uip_ipaddr_t addr; uip_ipaddr(&addr, 255,255,255,255); struct uip_udp_conn *conn = uip_udp_new(&addr, htonw(DhcpServerPort)); if (!conn) { printf("Failed to set up UDP connection.\n"); return 1; } uip_udp_bind(conn, htonw(DhcpClientPort)); // Send a DHCP discover packet. dhcp_prep_packet(&out, rand()); options = out.options; remaining = sizeof(out.options); byte = DhcpDiscover; dhcp_add_option(&options, DhcpTagMessageType, &byte, sizeof(byte), &remaining); dhcp_add_option(&options, DhcpTagClientIdentifier, client_id, sizeof(client_id), &remaining); dhcp_add_option(&options, DhcpTagParameterRequestList, requested, sizeof(requested), &remaining); dhcp_add_option(&options, DhcpTagMaximumDhcpMessageSize, &max_size, sizeof(max_size), &remaining); dhcp_add_option(&options, DhcpTagEndOfList, NULL, 0, &remaining); dhcp_send_packet(conn, "DHCP discover", &out, &in); // Extract the DHCP server id. uint32_t server_id; if (dhcp_process_options(&in, OptionOverloadNone, &dhcp_get_server, &server_id)) { printf("Failed to extract server id.\n"); return 1; } // We got an offer. Request it. dhcp_state = DhcpRequesting; dhcp_prep_packet(&out, rand()); options = out.options; remaining = sizeof(out.options); byte = DhcpRequest; dhcp_add_option(&options, DhcpTagMessageType, &byte, sizeof(byte), &remaining); dhcp_add_option(&options, DhcpTagClientIdentifier, client_id, sizeof(client_id), &remaining); dhcp_add_option(&options, DhcpTagRequestedIpAddress, &in.your_ip, sizeof(in.your_ip), &remaining); dhcp_add_option(&options, DhcpTagParameterRequestList, requested, sizeof(requested), &remaining); dhcp_add_option(&options, DhcpTagMaximumDhcpMessageSize, &max_size, sizeof(max_size), &remaining); dhcp_add_option(&options, DhcpTagServerIdentifier, &server_id, sizeof(server_id), &remaining); dhcp_add_option(&options, DhcpTagEndOfList, NULL, 0, &remaining); dhcp_send_packet(conn, "DHCP request", &out, &in); DhcpMessageType type; if (dhcp_process_options(&in, OptionOverloadNone, &dhcp_get_type, &type)) { printf("Failed to extract message type.\n"); dhcp_state = DhcpInit; return 1; } if (type == DhcpNak) { printf("DHCP request nak-ed by the server.\n"); dhcp_state = DhcpInit; return 1; } // The server acked, completing the transaction. dhcp_state = DhcpBound; uip_udp_remove(conn); // Apply the settings. if (dhcp_process_options(&in, OptionOverloadNone, &dhcp_apply_options, NULL)) { dhcp_state = DhcpInit; return 1; } int bootfile_size = sizeof(in.bootfile_name) + 1; char *file = xmalloc(bootfile_size); file[bootfile_size - 1] = 0; memcpy(file, in.bootfile_name, sizeof(in.bootfile_name)); *bootfile = file; uip_ipaddr(next_ip, in.server_ip >> 0, in.server_ip >> 8, in.server_ip >> 16, in.server_ip >> 24); uip_ipaddr(server_ip, server_id >> 0, server_id >> 8, server_id >> 16, server_id >> 24); uip_ipaddr_t my_ip; uip_ipaddr(&my_ip, in.your_ip >> 0, in.your_ip >> 8, in.your_ip >> 16, in.your_ip >> 24); uip_sethostaddr(&my_ip); return 0; }
void bootp_handle_reply(void) { int i; struct bootp *pk = uip_appdata; if(pk->bp_op != BOOTREPLY) return; /* ugh? shouldn't happen */ if(pk->bp_htype != HTYPE_ETHERNET) return; for(i = 0; i < 4; i ++) { if(pk->bp_xid[i] != uip_udp_conn->appstate.bootp.xid[i]) return; /* session id doesn't match */ if(pk->bp_vend[i] != replycookie[i]) return; /* reply cookie doesn't match */ } /* * looks like we have received a valid bootp reply, * prepare to override eeprom configuration */ uip_ipaddr_t ips[5]; memset(&ips, 0, sizeof(ips)); /* extract our ip addresses, subnet-mask and gateway ... */ memcpy(&ips[0], pk->bp_yiaddr, 4); uip_sethostaddr(&ips[0]); debug_printf ("BOOTP: configured new ip address %d.%d.%d.%d\n", ((unsigned char *) ips)[0], ((unsigned char *) ips)[1], ((unsigned char *) ips)[2], ((unsigned char *) ips)[3]); unsigned char *ptr = pk->bp_vend + 4; while(*ptr != 0xFF) { switch(* ptr) { case TAG_SUBNET_MASK: memcpy(&ips[1], &ptr[2], 4); uip_setnetmask(&ips[1]); break; case TAG_GATEWAY: memcpy(&ips[2], &ptr[2], 4); uip_setdraddr(&ips[2]); break; #ifdef DNS_SUPPORT case TAG_DOMAIN_SERVER: memcpy(&ips[3], &ptr[2], 4); resolv_conf(&ips[3]); break; #endif #ifdef NTP_SUPPORT case TAG_NTP_SERVER: /* This will set the ntp connection to the server set by the bootp * request */ memcpy(&ips[4], &ptr[2], 4); ntp_conf(&ips[4]); break; #endif } ptr = ptr + ptr[1] + 2; } /* Remove the bootp connection */ uip_udp_remove(uip_udp_conn); #ifdef BOOTP_TO_EEPROM_SUPPORT eeprom_save(ip, &ips[0], IPADDR_LEN); eeprom_save(netmask, &ips[1], IPADDR_LEN); eeprom_save(gateway, &ips[2], IPADDR_LEN); #ifdef DNS_SUPPORT eeprom_save(dns_server, &ips[3], IPADDR_LEN); #endif #ifdef NTP_SUPPORT eeprom_save(ntp_server, &ips[4], IPADDR_LEN); #endif #endif /* BOOTP_TO_EEPROM_SUPPORT */ #ifdef DYNDNS_SUPPORT dyndns_update(); #endif #if defined(TFTP_SUPPORT) && defined(BOOTLOADER_SUPPORT) if(pk->bp_file[0] == 0) return; /* no boot filename provided */ debug_putstr("load:"); debug_putstr(pk->bp_file); debug_putchar('\n'); /* create tftp connection, which will fire the download request */ uip_ipaddr_t ip; uip_ipaddr(&ip, pk->bp_siaddr[0], pk->bp_siaddr[1], pk->bp_siaddr[2], pk->bp_siaddr[3]); tftp_fire_tftpomatic(&ip, pk->bp_file); #endif /* TFTP_SUPPORT */ }
// obs³u¿ pakiet void udp_config_handle_packet(unsigned char* data, unsigned int len) { // otrzymany pakiet udp_config_packet *packet = (udp_config_packet*) data; // ignoruj niepoprawne pakiety if (packet->start != UDP_CONFIG_MAGIC) { return; } // ignoruj pakiety z ustawionym adresem MAC innego urz¹dzenia if (memcmp(packet->mac, nic_get_mac(), 6) != 0) { // MAC niezgodny, sprawdŸ czy nie ustawiono adresu broadcast MAC (ff:ff:ff:ff:ff:ff) for (i=0; i<6; i++) { if (packet->mac[i] != 0xFF) { return; } } } switch(packet->type) { // wyszukiwanie urz¹dzeñ case UDP_CONFIG_TYPE_DISCOVERY: // wyszukiwanie okreœlonego typu urz¹dzeñ if ( (packet->length == 1) && (packet->data[0] != UDP_CONFIG_DEVICE_TYPE) ) { // szukany inny typ urz¹dzenia return; } // formuj pakiet packet->type = UDP_CONFIG_TYPE_MY_CONFIG; len = udp_config_fill(packet->data); break; // identyfikacja wybranego urz¹dzenia case UDP_CONFIG_TYPE_IDENTIFY: // mrugaj naprzemiennie diodami RX/TX przez 3 sekundy udp_identify_timer = 30; packet->type = UDP_CONFIG_TYPE_IDENTIFY_OK; len = 0; break; // niepoprawny typ default: return; } // odeœlij pakiet struct uip_udp_conn* conn; conn = uip_udp_new(&uip_udp_conn->ripaddr, uip_udp_conn->rport); if (!conn) { return; } // wyœlij z portu, na którym pakiet zosta³ odebrany uip_udp_bind(conn, HTONS(UDP_CONFIG_PORT)); // nag³ówek packet->start = UDP_CONFIG_MAGIC; packet->length = len; // nadawca memcpy(packet->mac, nic_get_mac(), 6); // wyœlij uip_udp_send(len + 10); // czekaj na wys³anie nic_wait_for_send(); // zamknij po³¹czenia UDP (przychodz¹cy broadcast i wychodz¹cy unicast) uip_udp_remove(conn); uip_udp_remove(uip_udp_conn); }
void nabto_close_socket(nabto_socket_t* socket) { uip_udp_remove(*socket); *socket = NULL; }