u08 udp_receive_packet( ip_header * p, u16 len ) { udp_header * udp = ( udp_header * ) __ip_payload( p ); udp_conn * conn; udp_sock sock; u16 port = __ntohs( udp->dest_port ); len; // todo: verify udp checksum conn = udp_find_conn_by_port( port ); if (!conn || !conn->handler) { // log_printf( "udp: no conn for port=%u\n", port ); return 0; } sock = (udp_sock)(conn - udp_conns); // log_printf( "udp: delivering datagram for port=%u to sock %u\n", port, sock ); conn->handler( sock, UDP_EVENT_PACKET, p->src_addr, __ntohs( udp->src_port ), (u08 const *)( udp + 1 ), __ip_payload_length( p ) - sizeof( udp_header ) ); return 0; }
u08 ipstack_receive_packet( u08 iface, u08 const * buf, u16 len ) { eth_header * eth = (eth_header *) buf; u16 etype = __ntohs( eth->ethertype ); len; switch( etype ) { case ethertype_ipv4: { ip_header * ip = (ip_header *) (eth + 1); arptab_insert( iface, ip->src_addr, eth->src ); return __ip_receive_packet( ip, len - sizeof( eth_header ) ); } case ethertype_arp: return handle_arp_packet( iface, (arp_header *) (eth + 1) ); } return 0; }
uint16_t ntohs(uint16_t ns) { return (__ntohs(ns)); }
WORD intel16 (WORD val) { return __ntohs (val); }
static int isolate_net (struct config_store * cfg, struct net_sb * sb) { int nkeys, keybuf_size = CONFIG_MAX; char k[CONFIG_MAX]; char * keybuf = __alloca(keybuf_size); while ((nkeys = get_config_entries(cfg, "net.rules", keybuf, keybuf_size)) == -ENAMETOOLONG) { keybuf_size *= 2; keybuf = __alloca(keybuf_size); } if (nkeys <= 0) goto add; const char * key = keybuf, * next = NULL; memcpy(k, "net.rules.", 10); for (int n = 0 ; n < nkeys ; key = next, n++) { for (next = key ; *next ; next++); next++; int key_len = next - key - 1; memcpy(k + 10, key, key_len); k[10 + key_len] = 0; set_config(cfg, k, NULL); } add: if (!sb) return 0; for (int i = 0 ; i < sb->nrules ; i++) { struct net_sb_rule * r = &sb->rules[i]; char u[CONFIG_MAX]; int ulen; int family = -1; undo: ulen = 0; for (int turn = 0 ; turn < 2 ; turn++) { struct sockaddr * addr = turn ? r->r_addr : r->l_addr; if (turn) u[ulen++] = ':'; if (!addr) { if (family == -1 || family == AF_INET) ulen += snprintf(u + ulen, CONFIG_MAX - ulen, "0.0.0.0:0-65535"); else ulen += snprintf(u + ulen, CONFIG_MAX - ulen, "[0:0:0:0:0:0:0:0]:0-65535]"); } else { if (addr->sa_family == AF_INET) { if (family == AF_INET6) goto next; family = AF_INET; struct sockaddr_in * saddr = (void *) addr; unsigned char * a = (void *) &saddr->sin_addr.s_addr; ulen += snprintf(u + ulen, CONFIG_MAX - ulen, "%d.%d.%d.%d:%u", a[0], a[1], a[2], a[3], __ntohs(saddr->sin_port)); continue; } if (addr->sa_family == AF_INET6) { if (family == AF_INET) goto next; if (turn && family == -1) { family = AF_INET6; goto undo; } family = AF_INET6; struct sockaddr_in6 * saddr = (void *) addr; unsigned short * a = (void *) &saddr->sin6_addr.s6_addr; ulen += snprintf(u + ulen, CONFIG_MAX - ulen, "[%d:%d:%d:%d:%d:%d:%d:%d]:%u", a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], __ntohs(saddr->sin6_port)); continue; } goto next; } } snprintf(k + 10, CONFIG_MAX - 10, "%d", i + 1); set_config(cfg, k, u); debug("added net rule: %s\n", u); next: continue; } return 0; }