Changes in / [8426912a:6610565b] in mainline
- Files:
-
- 27 added
- 14 deleted
- 51 edited
Legend:
- Unmodified
- Added
- Removed
-
boot/Makefile.common
r8426912a r6610565b 98 98 $(USPACE_PATH)/srv/fs/fat/fat \ 99 99 $(USPACE_PATH)/srv/taskmon/taskmon \ 100 $(USPACE_PATH)/srv/hw/netif/ne2000/ne2000 \ 100 $(USPACE_PATH)/srv/hw/netif/dp8390/dp8390 \ 101 $(USPACE_PATH)/srv/hw/bus/usb/hcd/virtual/vhcd \ 101 102 $(USPACE_PATH)/srv/net/netif/lo/lo \ 102 103 $(USPACE_PATH)/srv/net/nil/eth/eth \ … … 132 133 $(USPACE_PATH)/app/taskdump/taskdump \ 133 134 $(USPACE_PATH)/app/tester/tester \ 135 $(USPACE_PATH)/app/test_serial/test_serial \ 134 136 $(USPACE_PATH)/app/tetris/tetris \ 135 137 $(USPACE_PATH)/app/trace/trace \ 138 $(USPACE_PATH)/app/netstart/netstart \ 136 139 $(USPACE_PATH)/app/nettest1/nettest1 \ 137 140 $(USPACE_PATH)/app/nettest2/nettest2 \ -
kernel/arch/amd64/include/interrupt.h
r8426912a r6610565b 55 55 #define IRQ_PIC_SPUR 7 56 56 #define IRQ_MOUSE 12 57 #define IRQ_ NE2000 957 #define IRQ_DP8390 9 58 58 59 59 /* This one must have four least significant bits set to ones */ -
kernel/arch/amd64/src/amd64.c
r8426912a r6610565b 238 238 sysinfo_set_item_val(irqs_info, NULL, true); 239 239 240 sysinfo_set_item_val("netif. ne2000.inr", NULL, IRQ_NE2000);240 sysinfo_set_item_val("netif.dp8390.inr", NULL, IRQ_DP8390); 241 241 } 242 242 -
kernel/arch/ia32/include/interrupt.h
r8426912a r6610565b 55 55 #define IRQ_PIC_SPUR 7 56 56 #define IRQ_MOUSE 12 57 #define IRQ_ NE2000 557 #define IRQ_DP8390 5 58 58 59 59 /* This one must have four least significant bits set to ones */ -
kernel/arch/ia32/src/ia32.c
r8426912a r6610565b 196 196 sysinfo_set_item_val(irqs_info, NULL, true); 197 197 198 sysinfo_set_item_val("netif. ne2000.inr", NULL, IRQ_NE2000);198 sysinfo_set_item_val("netif.dp8390.inr", NULL, IRQ_DP8390); 199 199 } 200 200 -
kernel/arch/ia64/include/interrupt.h
r8426912a r6610565b 61 61 #define IRQ_KBD (0x01 + LEGACY_INTERRUPT_BASE) 62 62 #define IRQ_MOUSE (0x0c + LEGACY_INTERRUPT_BASE) 63 #define IRQ_ NE2000 (0x09 + LEGACY_INTERRUPT_BASE)63 #define IRQ_DP8390 (0x09 + LEGACY_INTERRUPT_BASE) 64 64 65 65 /** General Exception codes. */ -
kernel/arch/ia64/src/ia64.c
r8426912a r6610565b 222 222 #endif 223 223 224 sysinfo_set_item_val("netif. ne2000.inr", NULL, IRQ_NE2000);224 sysinfo_set_item_val("netif.dp8390.inr", NULL, IRQ_DP8390); 225 225 226 226 sysinfo_set_item_val("ia64_iospace", NULL, true); -
kernel/generic/include/ddi/ddi.h
r8426912a r6610565b 54 54 extern sysarg_t sys_physmem_map(sysarg_t, sysarg_t, sysarg_t, sysarg_t); 55 55 extern sysarg_t sys_iospace_enable(ddi_ioarg_t *); 56 extern sysarg_t sys_interrupt_enable(int irq, int enable); 56 57 57 58 /* -
kernel/generic/include/syscall/syscall.h
r8426912a r6610565b 82 82 SYS_PHYSMEM_MAP, 83 83 SYS_IOSPACE_ENABLE, 84 SYS_INTERRUPT_ENABLE, 84 85 85 86 SYS_SYSINFO_GET_TAG, -
kernel/generic/src/ddi/ddi.c
r8426912a r6610565b 258 258 } 259 259 260 /** Disable or enable specified interrupts. 261 * 262 * @param irq the interrupt to be enabled/disabled. 263 * @param enable if true enable the interrupt, disable otherwise. 264 * 265 * @retutn Zero on success, error code otherwise. 266 */ 267 sysarg_t sys_interrupt_enable(int irq, int enable) 268 { 269 /* FIXME: this needs to be generic code, or better not be in kernel at all. */ 270 #if 0 271 cap_t task_cap = cap_get(TASK); 272 if (!(task_cap & CAP_IRQ_REG)) 273 return EPERM; 274 275 if (irq < 0 || irq > 16) { 276 return EINVAL; 277 } 278 279 uint16_t irq_mask = (uint16_t)(1 << irq); 280 if (enable) { 281 trap_virtual_enable_irqs(irq_mask); 282 } else { 283 trap_virtual_disable_irqs(irq_mask); 284 } 285 286 #endif 287 return 0; 288 } 289 260 290 /** @} 261 291 */ -
kernel/generic/src/mm/slab.c
r8426912a r6610565b 806 806 } 807 807 808 /** Go through all caches and reclaim what is possible */ 808 /** Go through all caches and reclaim what is possible 809 * 810 * Interrupts must be disabled before calling this function, 811 * otherwise memory allocation from interrupts can deadlock. 812 * 813 */ 809 814 size_t slab_reclaim(unsigned int flags) 810 815 { 811 irq_spinlock_lock(&slab_cache_lock, true);816 irq_spinlock_lock(&slab_cache_lock, false); 812 817 813 818 size_t frames = 0; … … 819 824 } 820 825 821 irq_spinlock_unlock(&slab_cache_lock, true);826 irq_spinlock_unlock(&slab_cache_lock, false); 822 827 823 828 return frames; -
kernel/generic/src/syscall/syscall.c
r8426912a r6610565b 171 171 (syshandler_t) sys_physmem_map, 172 172 (syshandler_t) sys_iospace_enable, 173 (syshandler_t) sys_interrupt_enable, 173 174 174 175 /* Sysinfo syscalls */ -
uspace/Makefile
r8426912a r6610565b 82 82 srv/hw/char/i8042 \ 83 83 srv/hw/char/s3c24xx_uart \ 84 srv/hw/netif/ ne2000 \84 srv/hw/netif/dp8390 \ 85 85 srv/net/netif/lo \ 86 86 srv/net/il/arp \ -
uspace/app/trace/syscalls.c
r8426912a r6610565b 73 73 [SYS_PHYSMEM_MAP] = { "physmem_map", 4, V_ERRNO }, 74 74 [SYS_IOSPACE_ENABLE] = { "iospace_enable", 1, V_ERRNO }, 75 [SYS_INTERRUPT_ENABLE] = { "interrupt_enable", 2, V_ERRNO }, 75 76 76 77 [SYS_SYSINFO_GET_TAG] = { "sysinfo_get_tag", 2, V_INTEGER }, -
uspace/doc/doxygroups.h
r8426912a r6610565b 43 43 44 44 /** 45 * @defgroup ne2000 NE2000 network interfaceservice45 * @defgroup dp8390 Generic DP8390 network interface family service 46 46 * @ingroup netif 47 47 */ 48 49 /** 50 * @defgroup ne2k NE2000 network interface family 51 * @ingroup dp8390 52 */ 48 53 49 54 /** -
uspace/drv/ns8250/ns8250.c
r8426912a r6610565b 431 431 { 432 432 ns8250_dev_data_t *data = (ns8250_dev_data_t *) dev->driver_data; 433 int res; 434 435 /* Enable interrupt globally. */ 436 res = interrupt_enable(data->irq); 437 if (res != EOK) 438 return res; 433 439 434 440 /* Enable interrupt on the serial port. */ -
uspace/lib/c/generic/ddi.c
r8426912a r6610565b 96 96 } 97 97 98 /** Enable an interrupt. 99 * 100 * @param irq the interrupt. 101 * 102 * @return Zero on success, negative error code otherwise. 103 */ 104 int interrupt_enable(int irq) 105 { 106 return __SYSCALL2(SYS_INTERRUPT_ENABLE, (sysarg_t) irq, 1); 107 } 108 109 /** Disable an interrupt. 110 * 111 * @param irq the interrupt. 112 * 113 * @return Zero on success, negative error code otherwise. 114 */ 115 int interrupt_disable(int irq) 116 { 117 return __SYSCALL2(SYS_INTERRUPT_ENABLE, (sysarg_t) irq, 0); 118 } 119 98 120 /** Enable PIO for specified I/O range. 99 121 * -
uspace/lib/c/generic/devman.c
r8426912a r6610565b 79 79 } 80 80 81 if (flags & IPC_FLAG_BLOCKING) {81 if (flags & IPC_FLAG_BLOCKING) 82 82 devman_phone_client = async_connect_me_to_blocking( 83 83 PHONE_NS, SERVICE_DEVMAN, DEVMAN_CLIENT, 0); 84 } else {84 else 85 85 devman_phone_client = async_connect_me_to(PHONE_NS, 86 86 SERVICE_DEVMAN, DEVMAN_CLIENT, 0); 87 }88 87 89 88 fibril_mutex_unlock(&devman_phone_mutex); -
uspace/lib/c/include/ddi.h
r8426912a r6610565b 42 42 extern int iospace_enable(task_id_t, void *, unsigned long); 43 43 extern int pio_enable(void *, size_t, void **); 44 extern int interrupt_enable(int); 45 extern int interrupt_disable(int); 44 46 45 47 #endif -
uspace/lib/c/include/ipc/il.h
r8426912a r6610565b 33 33 /** @file 34 34 * Internetwork layer modules messages. 35 * @see il_ remote.h35 * @see il_interface.h 36 36 * @see ip_interface.h 37 37 */ … … 45 45 /** Internet layer modules messages. */ 46 46 typedef enum { 47 /** New device message. 48 * @see ip_device_req() 49 */ 50 NET_IL_DEVICE = NET_IL_FIRST, 47 51 /** Device state changed message. 48 52 * @see il_device_state_msg() 49 53 */ 50 NET_IL_DEVICE_STATE = NET_IL_FIRST, 51 54 NET_IL_DEVICE_STATE, 52 55 /** Device MTU changed message. 53 56 * @see il_mtu_changed_msg() 54 57 */ 55 58 NET_IL_MTU_CHANGED, 56 59 /** Packet size message. 60 * @see il_packet_size_req() 61 */ 62 NET_IL_PACKET_SPACE, 57 63 /** Packet received message. 58 64 * @see il_received_msg() 59 65 */ 60 NET_IL_RECEIVED 66 NET_IL_RECEIVED, 67 /** Packet send message. 68 * @see il_send_msg() 69 */ 70 NET_IL_SEND 61 71 } il_messages; 62 72 -
uspace/lib/c/include/ipc/ip.h
r8426912a r6610565b 47 47 /** IP module messages. */ 48 48 typedef enum { 49 /** New device message.50 * @see ip_device_req()51 */52 NET_IP_DEVICE = NET_IP_FIRST,53 54 49 /** Adds the routing entry. 55 50 * @see ip_add_route() 56 51 */ 57 NET_IP_ADD_ROUTE ,52 NET_IP_ADD_ROUTE = NET_IP_FIRST, 58 53 59 54 /** Gets the actual route information. … … 70 65 * @see ip_set_default_gateway() 71 66 */ 72 NET_IP_SET_GATEWAY, 73 74 /** Packet size message. 75 * @see ip_packet_size_req() 76 */ 77 NET_IP_PACKET_SPACE, 78 79 /** Packet send message. 80 * @see ip_send_msg() 81 */ 82 NET_IP_SEND 67 NET_IP_SET_GATEWAY 83 68 } ip_messages; 84 69 -
uspace/lib/c/include/ipc/services.h
r8426912a r6610565b 54 54 SERVICE_NETWORKING, 55 55 SERVICE_LO, 56 SERVICE_ NE2000,56 SERVICE_DP8390, 57 57 SERVICE_ETHERNET, 58 58 SERVICE_NILDUMMY, -
uspace/lib/net/Makefile
r8426912a r6610565b 43 43 netif/netif_skel.c \ 44 44 nil/nil_remote.c \ 45 nil/nil_skel.c \ 46 il/il_remote.c \ 47 il/il_skel.c \ 45 il/il_interface.c \ 48 46 il/ip_remote.c \ 49 47 il/ip_client.c \ … … 52 50 tl/icmp_client.c \ 53 51 tl/socket_core.c \ 54 tl/tl_common.c \ 55 tl/tl_remote.c \ 56 tl/tl_skel.c 52 tl/tl_interface.c \ 53 tl/tl_common.c 57 54 58 55 include $(USPACE_PREFIX)/Makefile.common -
uspace/lib/net/generic/protocol_map.c
r8426912a r6610565b 50 50 switch (nil) { 51 51 case SERVICE_ETHERNET: 52 case SERVICE_ NE2000:52 case SERVICE_DP8390: 53 53 switch (il) { 54 54 case SERVICE_IP: … … 76 76 switch (nil) { 77 77 case SERVICE_ETHERNET: 78 case SERVICE_ NE2000:78 case SERVICE_DP8390: 79 79 switch (protocol) { 80 80 case ETH_P_IP: … … 139 139 switch (nil) { 140 140 case SERVICE_ETHERNET: 141 case SERVICE_ NE2000:141 case SERVICE_DP8390: 142 142 return HW_ETHER; 143 143 default: -
uspace/lib/net/il/ip_remote.c
r8426912a r6610565b 36 36 * 37 37 * @see ip_interface.h 38 * @see il_ remote.h38 * @see il_interface.h 39 39 * 40 40 */ … … 121 121 services_t service) 122 122 { 123 return generic_device_req_remote(ip_phone, NET_I P_DEVICE, device_id, 0,123 return generic_device_req_remote(ip_phone, NET_IL_DEVICE, device_id, 0, 124 124 service); 125 125 } … … 188 188 packet_dimension_t *packet_dimension) 189 189 { 190 return generic_packet_size_req_remote(ip_phone, NET_I P_PACKET_SPACE,190 return generic_packet_size_req_remote(ip_phone, NET_IL_PACKET_SPACE, 191 191 device_id, packet_dimension); 192 192 } … … 228 228 services_t sender, services_t error) 229 229 { 230 return generic_send_msg_remote(ip_phone, NET_I P_SEND, device_id,230 return generic_send_msg_remote(ip_phone, NET_IL_SEND, device_id, 231 231 packet_get_id(packet), sender, error); 232 232 } -
uspace/lib/net/include/nil_remote.h
r8426912a r6610565b 37 37 #include <net/device.h> 38 38 #include <net/packet.h> 39 #include <generic.h>40 39 41 #define nil_bind_service(service, device_id, me, receiver) \ 42 bind_service(service, device_id, me, 0, receiver) 43 44 #define nil_packet_size_req(nil_phone, device_id, packet_dimension) \ 45 generic_packet_size_req_remote(nil_phone, NET_NIL_PACKET_SPACE, \ 46 device_id, packet_dimension) 47 48 #define nil_get_addr_req(nil_phone, device_id, address, data) \ 49 generic_get_addr_req(nil_phone, NET_NIL_ADDR, device_id, address, data) 50 51 #define nil_get_broadcast_addr_req(nil_phone, device_id, address, data) \ 52 generic_get_addr_req(nil_phone, NET_NIL_BROADCAST_ADDR, device_id, \ 53 address, data) 54 55 #define nil_send_msg(nil_phone, device_id, packet, sender) \ 56 generic_send_msg_remote(nil_phone, NET_NIL_SEND, device_id, \ 57 packet_get_id(packet), sender, 0) 58 59 #define nil_device_req(nil_phone, device_id, mtu, netif_service) \ 60 generic_device_req_remote(nil_phone, NET_NIL_DEVICE, device_id, mtu, \ 61 netif_service) 62 63 extern int nil_device_state_msg(int, device_id_t, int); 64 extern int nil_received_msg(int, device_id_t, packet_t *, services_t); 40 extern int nil_device_state_msg_remote(int, device_id_t, int); 41 extern int nil_received_msg_remote(int, device_id_t, packet_t *, services_t); 65 42 66 43 #endif -
uspace/lib/net/netif/netif_skel.c
r8426912a r6610565b 33 33 /** @file 34 34 * Network interface module skeleton implementation. 35 * @see netif _skel.h35 * @see netif.h 36 36 */ 37 37 … … 52 52 #include <adt/measured_strings.h> 53 53 #include <net/device.h> 54 #include <nil_interface.h> 54 55 #include <netif_skel.h> 55 #include <nil_remote.h>56 56 57 57 DEVICE_MAP_IMPLEMENT(netif_device_map, netif_device_t); … … 130 130 if (result > NETIF_NULL) { 131 131 int phone = device->nil_phone; 132 fibril_rwlock_write_unlock(&netif_globals.lock); 132 133 nil_device_state_msg(phone, device_id, result); 133 fibril_rwlock_write_unlock(&netif_globals.lock);134 134 return EOK; 135 135 } … … 166 166 if (result > NETIF_NULL) { 167 167 int phone = device->nil_phone; 168 fibril_rwlock_write_unlock(&netif_globals.lock); 168 169 nil_device_state_msg(phone, device_id, result); 169 fibril_rwlock_write_unlock(&netif_globals.lock);170 170 return EOK; 171 171 } -
uspace/lib/net/nil/nil_remote.c
r8426912a r6610565b 33 33 /** @file 34 34 * Network interface layer interface implementation for remote modules. 35 * @see nil_ remote.h35 * @see nil_interface.h 36 36 */ 37 37 38 38 #include <nil_remote.h> 39 #include <nil_interface.h> 39 40 #include <generic.h> 40 41 #include <net/device.h> 41 42 #include <net/packet.h> 42 43 #include <packet_client.h> 44 43 45 #include <ipc/nil.h> 44 46 45 47 /** Notify the network interface layer about the device state change. 46 48 * 47 * @param[in] nil_phone Network interface layer phone. 48 * @param[in] device_id Device identifier. 49 * @param[in] state New device state. 50 * 51 * @return EOK on success. 52 * @return Other error codes as defined for each specific module 53 * device state function. 54 * 49 * @param[in] nil_phone The network interface layer phone. 50 * @param[in] device_id The device identifier. 51 * @param[in] state The new device state. 52 * @return EOK on success. 53 * @return Other error codes as defined for each specific module 54 * device state function. 55 55 */ 56 int nil_device_state_msg (int nil_phone, device_id_t device_id, int state)56 int nil_device_state_msg_remote(int nil_phone, device_id_t device_id, int state) 57 57 { 58 58 return generic_device_state_msg_remote(nil_phone, NET_NIL_DEVICE_STATE, … … 65 65 * upper layers. 66 66 * 67 * @param[in] nil_phone Network interface layer phone. 68 * @param[in] device_id Source device identifier. 69 * @param[in] packet Received packet or the received packet queue. 70 * @param[in] target Target service. Ignored parameter. 71 * 72 * @return EOK on success. 73 * @return Other error codes as defined for each specific module 74 * received function. 75 * 67 * @param[in] nil_phone The network interface layer phone. 68 * @param[in] device_id The source device identifier. 69 * @param[in] packet The received packet or the received packet queue. 70 * @param target The target service. Ignored parameter. 71 * @return EOK on success. 72 * @return Other error codes as defined for each specific module 73 * received function. 76 74 */ 77 int nil_received_msg (int nil_phone, device_id_t device_id,75 int nil_received_msg_remote(int nil_phone, device_id_t device_id, 78 76 packet_t *packet, services_t target) 79 77 { -
uspace/lib/net/tl/tl_common.c
r8426912a r6610565b 42 42 #include <ip_remote.h> 43 43 #include <ip_interface.h> 44 #include <tl_ remote.h>44 #include <tl_interface.h> 45 45 46 46 #include <net/socket_codes.h> -
uspace/srv/net/cfg/ne2k
r8426912a r6610565b 3 3 NAME=ne2k 4 4 5 NETIF= ne20005 NETIF=dp8390 6 6 NIL=eth 7 7 IL=ip … … 17 17 IP_ADDR=10.0.2.15 18 18 IP_ROUTING=yes 19 IP_NETMASK=255.255.255. 019 IP_NETMASK=255.255.255.240 20 20 IP_BROADCAST=10.0.2.255 21 21 IP_GATEWAY=10.0.2.2 -
uspace/srv/net/il/arp/Makefile
r8426912a r6610565b 34 34 35 35 SOURCES = \ 36 arp.c 36 arp.c \ 37 arp_module.c 37 38 38 39 include $(USPACE_PREFIX)/Makefile.common -
uspace/srv/net/il/arp/arp.c
r8426912a r6610565b 36 36 */ 37 37 38 #include "arp.h" 39 #include "arp_header.h" 40 #include "arp_oc.h" 41 #include "arp_module.h" 42 38 43 #include <async.h> 39 44 #include <malloc.h> 40 45 #include <mem.h> 41 46 #include <fibril_synch.h> 42 #include <assert.h>43 47 #include <stdio.h> 44 48 #include <str.h> … … 50 54 #include <ipc/arp.h> 51 55 #include <ipc/il.h> 52 #include <ipc/nil.h>53 56 #include <byteorder.h> 54 57 #include <errno.h> 58 55 59 #include <net/modules.h> 56 60 #include <net/device.h> 57 61 #include <net/packet.h> 58 #include <nil_remote.h> 62 63 #include <nil_interface.h> 59 64 #include <protocol_map.h> 60 65 #include <packet_client.h> 61 66 #include <packet_remote.h> 62 #include <il_ remote.h>63 #include <il_ skel.h>64 #include "arp.h" 67 #include <il_interface.h> 68 #include <il_local.h> 69 65 70 66 71 /** ARP module name. */ … … 68 73 69 74 /** Number of microseconds to wait for an ARP reply. */ 70 #define ARP_TRANS_WAIT 1000000 71 72 /** @name ARP operation codes definitions */ 73 /*@{*/ 74 75 /** REQUEST operation code. */ 76 #define ARPOP_REQUEST 1 77 78 /** REPLY operation code. */ 79 #define ARPOP_REPLY 2 80 81 /*@}*/ 82 83 /** Type definition of an ARP protocol header. 84 * @see arp_header 85 */ 86 typedef struct arp_header arp_header_t; 87 88 /** ARP protocol header. */ 89 struct arp_header { 90 /** 91 * Hardware type identifier. 92 * @see hardware.h 93 */ 94 uint16_t hardware; 95 96 /** Protocol identifier. */ 97 uint16_t protocol; 98 /** Hardware address length in bytes. */ 99 uint8_t hardware_length; 100 /** Protocol address length in bytes. */ 101 uint8_t protocol_length; 102 103 /** 104 * ARP packet type. 105 * @see arp_oc.h 106 */ 107 uint16_t operation; 108 } __attribute__ ((packed)); 75 #define ARP_TRANS_WAIT 1000000 109 76 110 77 /** ARP global data. */ … … 121 88 trans->hw_addr = NULL; 122 89 } 123 124 90 fibril_condvar_broadcast(&trans->cv); 125 91 } … … 128 94 { 129 95 int count; 130 96 arp_trans_t *trans; 97 131 98 for (count = arp_addr_count(addresses) - 1; count >= 0; count--) { 132 arp_trans_t *trans = arp_addr_items_get_index(&addresses->values, 133 count); 99 trans = arp_addr_items_get_index(&addresses->values, count); 134 100 if (trans) 135 101 arp_clear_trans(trans); … … 137 103 } 138 104 139 /** Clear the device specific data. 140 * 141 * @param[in] device Device specific data. 105 106 /** Clears the device specific data. 107 * 108 * @param[in] device The device specific data. 142 109 */ 143 110 static void arp_clear_device(arp_device_t *device) 144 111 { 145 112 int count; 146 113 arp_proto_t *proto; 114 147 115 for (count = arp_protos_count(&device->protos) - 1; count >= 0; 148 116 count--) { 149 arp_proto_t *proto = arp_protos_get_index(&device->protos, 150 count); 151 117 proto = arp_protos_get_index(&device->protos, count); 152 118 if (proto) { 153 119 if (proto->addr) 154 120 free(proto->addr); 155 156 121 if (proto->addr_data) 157 122 free(proto->addr_data); 158 159 123 arp_clear_addr(&proto->addresses); 160 124 arp_addr_destroy(&proto->addresses); 161 125 } 162 126 } 163 164 127 arp_protos_clear(&device->protos); 165 128 } … … 168 131 { 169 132 int count; 170 133 arp_device_t *device; 134 171 135 fibril_mutex_lock(&arp_globals.lock); 172 136 for (count = arp_cache_count(&arp_globals.cache) - 1; count >= 0; 173 137 count--) { 174 arp_device_t *device = arp_cache_get_index(&arp_globals.cache, 175 count); 176 138 device = arp_cache_get_index(&arp_globals.cache, count); 177 139 if (device) { 178 140 arp_clear_device(device); 179 141 if (device->addr_data) 180 142 free(device->addr_data); 181 182 143 if (device->broadcast_data) 183 144 free(device->broadcast_data); 184 145 } 185 146 } 186 187 147 arp_cache_clear(&arp_globals.cache); 188 148 fibril_mutex_unlock(&arp_globals.lock); 189 149 printf("Cache cleaned\n"); 190 150 return EOK; 191 151 } … … 194 154 services_t protocol, measured_string_t *address) 195 155 { 156 arp_device_t *device; 157 arp_proto_t *proto; 158 arp_trans_t *trans; 159 196 160 fibril_mutex_lock(&arp_globals.lock); 197 198 arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id); 161 device = arp_cache_find(&arp_globals.cache, device_id); 199 162 if (!device) { 200 163 fibril_mutex_unlock(&arp_globals.lock); 201 164 return ENOENT; 202 165 } 203 204 arp_proto_t *proto = arp_protos_find(&device->protos, protocol); 166 proto = arp_protos_find(&device->protos, protocol); 205 167 if (!proto) { 206 168 fibril_mutex_unlock(&arp_globals.lock); 207 169 return ENOENT; 208 170 } 209 210 arp_trans_t *trans = arp_addr_find(&proto->addresses, address->value, 211 address->length); 171 trans = arp_addr_find(&proto->addresses, address->value, address->length); 212 172 if (trans) 213 173 arp_clear_trans(trans); 214 215 174 arp_addr_exclude(&proto->addresses, address->value, address->length); 216 217 175 fibril_mutex_unlock(&arp_globals.lock); 218 176 return EOK; 219 177 } 220 178 179 221 180 static int arp_clear_device_req(int arp_phone, device_id_t device_id) 222 181 { 182 arp_device_t *device; 183 223 184 fibril_mutex_lock(&arp_globals.lock); 224 225 arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id); 185 device = arp_cache_find(&arp_globals.cache, device_id); 226 186 if (!device) { 227 187 fibril_mutex_unlock(&arp_globals.lock); 228 188 return ENOENT; 229 189 } 230 231 190 arp_clear_device(device); 232 191 printf("Device %d cleared\n", device_id); 233 192 fibril_mutex_unlock(&arp_globals.lock); 234 193 return EOK; 235 194 } 236 195 237 /** Create new protocol specific data. 238 * 239 * Allocate and return the needed memory block as the proto parameter. 240 * 241 * @param[out] proto Allocated protocol specific data. 242 * @param[in] service Protocol module service. 243 * @param[in] address Actual protocol device address. 244 * 245 * @return EOK on success. 246 * @return ENOMEM if there is not enough memory left. 247 * 196 /** Creates new protocol specific data. 197 * 198 * Allocates and returns the needed memory block as the proto parameter. 199 * 200 * @param[out] proto The allocated protocol specific data. 201 * @param[in] service The protocol module service. 202 * @param[in] address The actual protocol device address. 203 * @return EOK on success. 204 * @return ENOMEM if there is not enough memory left. 248 205 */ 249 206 static int arp_proto_create(arp_proto_t **proto, services_t service, 250 207 measured_string_t *address) 251 208 { 209 int rc; 210 252 211 *proto = (arp_proto_t *) malloc(sizeof(arp_proto_t)); 253 212 if (!*proto) … … 258 217 (*proto)->addr_data = address->value; 259 218 260 intrc = arp_addr_initialize(&(*proto)->addresses);219 rc = arp_addr_initialize(&(*proto)->addresses); 261 220 if (rc != EOK) { 262 221 free(*proto); … … 267 226 } 268 227 269 /** Process the received ARP packet. 270 * 271 * Update the source hardware address if the source entry exists or the packet 228 /** Registers the device. 229 * 230 * Creates new device entry in the cache or updates the protocol address if the 231 * device with the device identifier and the driver service exists. 232 * 233 * @param[in] device_id The device identifier. 234 * @param[in] service The device driver service. 235 * @param[in] protocol The protocol service. 236 * @param[in] address The actual device protocol address. 237 * @return EOK on success. 238 * @return EEXIST if another device with the same device identifier 239 * and different driver service exists. 240 * @return ENOMEM if there is not enough memory left. 241 * @return Other error codes as defined for the 242 * measured_strings_return() function. 243 */ 244 static int arp_device_message(device_id_t device_id, services_t service, 245 services_t protocol, measured_string_t *address) 246 { 247 arp_device_t *device; 248 arp_proto_t *proto; 249 hw_type_t hardware; 250 int index; 251 int rc; 252 253 fibril_mutex_lock(&arp_globals.lock); 254 255 /* An existing device? */ 256 device = arp_cache_find(&arp_globals.cache, device_id); 257 258 if (device) { 259 if (device->service != service) { 260 printf("Device %d already exists\n", device->device_id); 261 fibril_mutex_unlock(&arp_globals.lock); 262 return EEXIST; 263 } 264 proto = arp_protos_find(&device->protos, protocol); 265 if (proto) { 266 free(proto->addr); 267 free(proto->addr_data); 268 proto->addr = address; 269 proto->addr_data = address->value; 270 } else { 271 rc = arp_proto_create(&proto, protocol, address); 272 if (rc != EOK) { 273 fibril_mutex_unlock(&arp_globals.lock); 274 return rc; 275 } 276 index = arp_protos_add(&device->protos, proto->service, 277 proto); 278 if (index < 0) { 279 fibril_mutex_unlock(&arp_globals.lock); 280 free(proto); 281 return index; 282 } 283 printf("New protocol added:\n\tdevice id\t= " 284 "%d\n\tproto\t= %d", device_id, protocol); 285 } 286 } else { 287 hardware = hardware_map(service); 288 if (!hardware) 289 return ENOENT; 290 291 /* Create a new device */ 292 device = (arp_device_t *) malloc(sizeof(arp_device_t)); 293 if (!device) { 294 fibril_mutex_unlock(&arp_globals.lock); 295 return ENOMEM; 296 } 297 device->hardware = hardware; 298 device->device_id = device_id; 299 rc = arp_protos_initialize(&device->protos); 300 if (rc != EOK) { 301 fibril_mutex_unlock(&arp_globals.lock); 302 free(device); 303 return rc; 304 } 305 rc = arp_proto_create(&proto, protocol, address); 306 if (rc != EOK) { 307 fibril_mutex_unlock(&arp_globals.lock); 308 free(device); 309 return rc; 310 } 311 index = arp_protos_add(&device->protos, proto->service, proto); 312 if (index < 0) { 313 fibril_mutex_unlock(&arp_globals.lock); 314 arp_protos_destroy(&device->protos); 315 free(device); 316 return index; 317 } 318 device->service = service; 319 320 /* Bind the new one */ 321 device->phone = nil_bind_service(device->service, 322 (sysarg_t) device->device_id, SERVICE_ARP, 323 arp_globals.client_connection); 324 if (device->phone < 0) { 325 fibril_mutex_unlock(&arp_globals.lock); 326 arp_protos_destroy(&device->protos); 327 free(device); 328 return EREFUSED; 329 } 330 331 /* Get packet dimensions */ 332 rc = nil_packet_size_req(device->phone, device_id, 333 &device->packet_dimension); 334 if (rc != EOK) { 335 fibril_mutex_unlock(&arp_globals.lock); 336 arp_protos_destroy(&device->protos); 337 free(device); 338 return rc; 339 } 340 341 /* Get hardware address */ 342 rc = nil_get_addr_req(device->phone, device_id, &device->addr, 343 &device->addr_data); 344 if (rc != EOK) { 345 fibril_mutex_unlock(&arp_globals.lock); 346 arp_protos_destroy(&device->protos); 347 free(device); 348 return rc; 349 } 350 351 /* Get broadcast address */ 352 rc = nil_get_broadcast_addr_req(device->phone, device_id, 353 &device->broadcast_addr, &device->broadcast_data); 354 if (rc != EOK) { 355 fibril_mutex_unlock(&arp_globals.lock); 356 free(device->addr); 357 free(device->addr_data); 358 arp_protos_destroy(&device->protos); 359 free(device); 360 return rc; 361 } 362 363 rc = arp_cache_add(&arp_globals.cache, device->device_id, 364 device); 365 if (rc != EOK) { 366 fibril_mutex_unlock(&arp_globals.lock); 367 free(device->addr); 368 free(device->addr_data); 369 free(device->broadcast_addr); 370 free(device->broadcast_data); 371 arp_protos_destroy(&device->protos); 372 free(device); 373 return rc; 374 } 375 printf("%s: Device registered (id: %d, type: 0x%x, service: %d," 376 " proto: %d)\n", NAME, device->device_id, device->hardware, 377 device->service, protocol); 378 } 379 fibril_mutex_unlock(&arp_globals.lock); 380 381 return EOK; 382 } 383 384 /** Initializes the ARP module. 385 * 386 * @param[in] client_connection The client connection processing function. 387 * The module skeleton propagates its own one. 388 * @return EOK on success. 389 * @return ENOMEM if there is not enough memory left. 390 */ 391 int arp_initialize(async_client_conn_t client_connection) 392 { 393 int rc; 394 395 fibril_mutex_initialize(&arp_globals.lock); 396 fibril_mutex_lock(&arp_globals.lock); 397 arp_globals.client_connection = client_connection; 398 rc = arp_cache_initialize(&arp_globals.cache); 399 fibril_mutex_unlock(&arp_globals.lock); 400 401 return rc; 402 } 403 404 /** Updates the device content length according to the new MTU value. 405 * 406 * @param[in] device_id The device identifier. 407 * @param[in] mtu The new mtu value. 408 * @return ENOENT if device is not found. 409 * @return EOK on success. 410 */ 411 static int arp_mtu_changed_message(device_id_t device_id, size_t mtu) 412 { 413 arp_device_t *device; 414 415 fibril_mutex_lock(&arp_globals.lock); 416 device = arp_cache_find(&arp_globals.cache, device_id); 417 if (!device) { 418 fibril_mutex_unlock(&arp_globals.lock); 419 return ENOENT; 420 } 421 device->packet_dimension.content = mtu; 422 fibril_mutex_unlock(&arp_globals.lock); 423 printf("arp - device %d changed mtu to %zu\n\n", device_id, mtu); 424 return EOK; 425 } 426 427 /** Processes the received ARP packet. 428 * 429 * Updates the source hardware address if the source entry exists or the packet 272 430 * is targeted to my protocol address. 273 * 274 * Respond to the ARP request if the packet is the ARP request and is 431 * Responses to the ARP request if the packet is the ARP request and is 275 432 * targeted to my address. 276 433 * 277 * @param[in] device_id Source device identifier. 278 * @param[in,out] packet Received packet. 279 * 280 * @return EOK on success and the packet is no longer needed. 281 * @return One on success and the packet has been reused. 282 * @return EINVAL if the packet is too small to carry an ARP 283 * packet. 284 * @return EINVAL if the received address lengths differs from 285 * the registered values. 286 * @return ENOENT if the device is not found in the cache. 287 * @return ENOENT if the protocol for the device is not found in 288 * the cache. 289 * @return ENOMEM if there is not enough memory left. 290 * 434 * @param[in] device_id The source device identifier. 435 * @param[in,out] packet The received packet. 436 * @return EOK on success and the packet is no longer needed. 437 * @return One on success and the packet has been reused. 438 * @return EINVAL if the packet is too small to carry an ARP 439 * packet. 440 * @return EINVAL if the received address lengths differs from 441 * the registered values. 442 * @return ENOENT if the device is not found in the cache. 443 * @return ENOENT if the protocol for the device is not found in 444 * the cache. 445 * @return ENOMEM if there is not enough memory left. 291 446 */ 292 447 static int arp_receive_message(device_id_t device_id, packet_t *packet) 293 448 { 449 size_t length; 450 arp_header_t *header; 451 arp_device_t *device; 452 arp_proto_t *proto; 453 arp_trans_t *trans; 454 uint8_t *src_hw; 455 uint8_t *src_proto; 456 uint8_t *des_hw; 457 uint8_t *des_proto; 294 458 int rc; 295 459 296 size_tlength = packet_get_data_length(packet);460 length = packet_get_data_length(packet); 297 461 if (length <= sizeof(arp_header_t)) 298 462 return EINVAL; 299 300 arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id);463 464 device = arp_cache_find(&arp_globals.cache, device_id); 301 465 if (!device) 302 466 return ENOENT; 303 304 arp_header_t *header = (arp_header_t *) packet_get_data(packet);467 468 header = (arp_header_t *) packet_get_data(packet); 305 469 if ((ntohs(header->hardware) != device->hardware) || 306 470 (length < sizeof(arp_header_t) + header->hardware_length * 2U + … … 308 472 return EINVAL; 309 473 } 310 311 arp_proto_t *proto = arp_protos_find(&device->protos,474 475 proto = arp_protos_find(&device->protos, 312 476 protocol_unmap(device->service, ntohs(header->protocol))); 313 477 if (!proto) 314 478 return ENOENT; 315 316 uint8_t *src_hw = ((uint8_t *) header) + sizeof(arp_header_t); 317 uint8_t *src_proto = src_hw + header->hardware_length; 318 uint8_t *des_hw = src_proto + header->protocol_length; 319 uint8_t *des_proto = des_hw + header->hardware_length; 320 321 arp_trans_t *trans = arp_addr_find(&proto->addresses, src_proto, 479 480 src_hw = ((uint8_t *) header) + sizeof(arp_header_t); 481 src_proto = src_hw + header->hardware_length; 482 des_hw = src_proto + header->protocol_length; 483 des_proto = des_hw + header->hardware_length; 484 trans = arp_addr_find(&proto->addresses, src_proto, 322 485 header->protocol_length); 323 324 if ((trans) && (trans->hw_addr)) { 325 /* Translation exists */ 486 /* Exists? */ 487 if (trans && trans->hw_addr) { 326 488 if (trans->hw_addr->length != header->hardware_length) 327 489 return EINVAL; 328 329 490 memcpy(trans->hw_addr->value, src_hw, trans->hw_addr->length); 330 491 } 331 332 492 /* Is my protocol address? */ 333 493 if (proto->addr->length != header->protocol_length) … … 335 495 336 496 if (!bcmp(proto->addr->value, des_proto, proto->addr->length)) { 497 /* Not already updated? */ 337 498 if (!trans) { 338 /* Update the translation */339 499 trans = (arp_trans_t *) malloc(sizeof(arp_trans_t)); 340 500 if (!trans) 341 501 return ENOMEM; 342 343 502 trans->hw_addr = NULL; 344 503 fibril_condvar_initialize(&trans->cv); … … 350 509 } 351 510 } 352 353 511 if (!trans->hw_addr) { 354 512 trans->hw_addr = measured_string_create_bulk(src_hw, … … 360 518 fibril_condvar_broadcast(&trans->cv); 361 519 } 362 363 520 if (ntohs(header->operation) == ARPOP_REQUEST) { 364 521 header->operation = htons(ARPOP_REPLY); … … 381 538 } 382 539 } 383 540 384 541 return EOK; 385 542 } 386 543 387 /** Update the device content length according to the new MTU value. 388 * 389 * @param[in] device_id Device identifier. 390 * @param[in] mtu New MTU value. 391 * 392 * @return ENOENT if device is not found. 393 * @return EOK on success. 394 * 395 */ 396 static int arp_mtu_changed_message(device_id_t device_id, size_t mtu) 397 { 398 fibril_mutex_lock(&arp_globals.lock); 399 400 arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id); 401 if (!device) { 402 fibril_mutex_unlock(&arp_globals.lock); 544 545 /** Returns the hardware address for the given protocol address. 546 * 547 * Sends the ARP request packet if the hardware address is not found in the 548 * cache. 549 * 550 * @param[in] device_id The device identifier. 551 * @param[in] protocol The protocol service. 552 * @param[in] target The target protocol address. 553 * @param[out] translation Where the hardware address of the target is stored. 554 * @return EOK on success. 555 * @return EAGAIN if the caller should try again. 556 * @return Other error codes in case of error. 557 */ 558 static int 559 arp_translate_message(device_id_t device_id, services_t protocol, 560 measured_string_t *target, measured_string_t **translation) 561 { 562 arp_device_t *device; 563 arp_proto_t *proto; 564 arp_trans_t *trans; 565 size_t length; 566 packet_t *packet; 567 arp_header_t *header; 568 bool retry = false; 569 int rc; 570 571 restart: 572 if (!target || !translation) 573 return EBADMEM; 574 575 device = arp_cache_find(&arp_globals.cache, device_id); 576 if (!device) 403 577 return ENOENT; 404 } 405 406 device->packet_dimension.content = mtu; 407 408 fibril_mutex_unlock(&arp_globals.lock); 409 410 printf("%s: Device %d changed MTU to %zu\n", NAME, device_id, mtu); 411 412 return EOK; 413 } 414 415 /** Process IPC messages from the registered device driver modules 416 * 417 * @param[in] iid Message identifier. 418 * @param[in,out] icall Message parameters. 419 * 420 */ 421 static void arp_receiver(ipc_callid_t iid, ipc_call_t *icall) 422 { 423 packet_t *packet; 424 int rc; 425 426 while (true) { 427 switch (IPC_GET_IMETHOD(*icall)) { 428 case NET_IL_DEVICE_STATE: 429 /* Do nothing - keep the cache */ 430 ipc_answer_0(iid, (sysarg_t) EOK); 431 break; 432 433 case NET_IL_RECEIVED: 434 rc = packet_translate_remote(arp_globals.net_phone, &packet, 435 IPC_GET_PACKET(*icall)); 436 if (rc == EOK) { 437 fibril_mutex_lock(&arp_globals.lock); 438 do { 439 packet_t *next = pq_detach(packet); 440 rc = arp_receive_message(IPC_GET_DEVICE(*icall), packet); 441 if (rc != 1) { 442 pq_release_remote(arp_globals.net_phone, 443 packet_get_id(packet)); 444 } 445 446 packet = next; 447 } while (packet); 448 fibril_mutex_unlock(&arp_globals.lock); 449 } 450 ipc_answer_0(iid, (sysarg_t) rc); 451 break; 452 453 case NET_IL_MTU_CHANGED: 454 rc = arp_mtu_changed_message(IPC_GET_DEVICE(*icall), 455 IPC_GET_MTU(*icall)); 456 ipc_answer_0(iid, (sysarg_t) rc); 457 break; 458 459 default: 460 ipc_answer_0(iid, (sysarg_t) ENOTSUP); 461 } 462 463 iid = async_get_call(icall); 464 } 465 } 466 467 /** Register the device. 468 * 469 * Create new device entry in the cache or update the protocol address if the 470 * device with the device identifier and the driver service exists. 471 * 472 * @param[in] device_id Device identifier. 473 * @param[in] service Device driver service. 474 * @param[in] protocol Protocol service. 475 * @param[in] address Actual device protocol address. 476 * 477 * @return EOK on success. 478 * @return EEXIST if another device with the same device identifier 479 * and different driver service exists. 480 * @return ENOMEM if there is not enough memory left. 481 * @return Other error codes as defined for the 482 * measured_strings_return() function. 483 * 484 */ 485 static int arp_device_message(device_id_t device_id, services_t service, 486 services_t protocol, measured_string_t *address) 487 { 488 int index; 489 int rc; 490 491 fibril_mutex_lock(&arp_globals.lock); 492 493 /* An existing device? */ 494 arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id); 495 if (device) { 496 if (device->service != service) { 497 printf("%s: Device %d already exists\n", NAME, 498 device->device_id); 499 fibril_mutex_unlock(&arp_globals.lock); 500 return EEXIST; 501 } 502 503 arp_proto_t *proto = arp_protos_find(&device->protos, protocol); 504 if (proto) { 505 free(proto->addr); 506 free(proto->addr_data); 507 proto->addr = address; 508 proto->addr_data = address->value; 509 } else { 510 rc = arp_proto_create(&proto, protocol, address); 511 if (rc != EOK) { 512 fibril_mutex_unlock(&arp_globals.lock); 513 return rc; 514 } 515 516 index = arp_protos_add(&device->protos, proto->service, 517 proto); 518 if (index < 0) { 519 fibril_mutex_unlock(&arp_globals.lock); 520 free(proto); 521 return index; 522 } 523 524 printf("%s: New protocol added (id: %d, proto: %d)\n", NAME, 525 device_id, protocol); 526 } 527 } else { 528 hw_type_t hardware = hardware_map(service); 529 if (!hardware) 578 579 proto = arp_protos_find(&device->protos, protocol); 580 if (!proto || (proto->addr->length != target->length)) 581 return ENOENT; 582 583 trans = arp_addr_find(&proto->addresses, target->value, target->length); 584 if (trans) { 585 if (trans->hw_addr) { 586 *translation = trans->hw_addr; 587 return EOK; 588 } 589 if (retry) 590 return EAGAIN; 591 rc = fibril_condvar_wait_timeout(&trans->cv, &arp_globals.lock, 592 ARP_TRANS_WAIT); 593 if (rc == ETIMEOUT) 530 594 return ENOENT; 531 532 /* Create new device */ 533 device = (arp_device_t *) malloc(sizeof(arp_device_t)); 534 if (!device) { 535 fibril_mutex_unlock(&arp_globals.lock); 536 return ENOMEM; 537 } 538 539 device->hardware = hardware; 540 device->device_id = device_id; 541 rc = arp_protos_initialize(&device->protos); 542 if (rc != EOK) { 543 fibril_mutex_unlock(&arp_globals.lock); 544 free(device); 545 return rc; 546 } 547 548 arp_proto_t *proto; 549 rc = arp_proto_create(&proto, protocol, address); 550 if (rc != EOK) { 551 fibril_mutex_unlock(&arp_globals.lock); 552 free(device); 553 return rc; 554 } 555 556 index = arp_protos_add(&device->protos, proto->service, proto); 557 if (index < 0) { 558 fibril_mutex_unlock(&arp_globals.lock); 559 arp_protos_destroy(&device->protos); 560 free(device); 561 return index; 562 } 563 564 device->service = service; 565 566 /* Bind */ 567 device->phone = nil_bind_service(device->service, 568 (sysarg_t) device->device_id, SERVICE_ARP, 569 arp_receiver); 570 if (device->phone < 0) { 571 fibril_mutex_unlock(&arp_globals.lock); 572 arp_protos_destroy(&device->protos); 573 free(device); 574 return EREFUSED; 575 } 576 577 /* Get packet dimensions */ 578 rc = nil_packet_size_req(device->phone, device_id, 579 &device->packet_dimension); 580 if (rc != EOK) { 581 fibril_mutex_unlock(&arp_globals.lock); 582 arp_protos_destroy(&device->protos); 583 free(device); 584 return rc; 585 } 586 587 /* Get hardware address */ 588 rc = nil_get_addr_req(device->phone, device_id, &device->addr, 589 &device->addr_data); 590 if (rc != EOK) { 591 fibril_mutex_unlock(&arp_globals.lock); 592 arp_protos_destroy(&device->protos); 593 free(device); 594 return rc; 595 } 596 597 /* Get broadcast address */ 598 rc = nil_get_broadcast_addr_req(device->phone, device_id, 599 &device->broadcast_addr, &device->broadcast_data); 600 if (rc != EOK) { 601 fibril_mutex_unlock(&arp_globals.lock); 602 free(device->addr); 603 free(device->addr_data); 604 arp_protos_destroy(&device->protos); 605 free(device); 606 return rc; 607 } 608 609 rc = arp_cache_add(&arp_globals.cache, device->device_id, 610 device); 611 if (rc != EOK) { 612 fibril_mutex_unlock(&arp_globals.lock); 613 free(device->addr); 614 free(device->addr_data); 615 free(device->broadcast_addr); 616 free(device->broadcast_data); 617 arp_protos_destroy(&device->protos); 618 free(device); 619 return rc; 620 } 621 printf("%s: Device registered (id: %d, type: 0x%x, service: %d," 622 " proto: %d)\n", NAME, device->device_id, device->hardware, 623 device->service, protocol); 624 } 625 626 fibril_mutex_unlock(&arp_globals.lock); 627 return EOK; 628 } 629 630 int il_initialize(int net_phone) 631 { 632 fibril_mutex_initialize(&arp_globals.lock); 633 634 fibril_mutex_lock(&arp_globals.lock); 635 arp_globals.net_phone = net_phone; 636 int rc = arp_cache_initialize(&arp_globals.cache); 637 fibril_mutex_unlock(&arp_globals.lock); 638 639 return rc; 640 } 641 642 static int arp_send_request(device_id_t device_id, services_t protocol, 643 measured_string_t *target, arp_device_t *device, arp_proto_t *proto) 644 { 595 retry = true; 596 goto restart; 597 } 598 if (retry) 599 return EAGAIN; 600 645 601 /* ARP packet content size = header + (address + translation) * 2 */ 646 size_tlength = 8 + 2 * (proto->addr->length + device->addr->length);602 length = 8 + 2 * (proto->addr->length + device->addr->length); 647 603 if (length > device->packet_dimension.content) 648 604 return ELIMIT; 649 650 packet _t *packet= packet_get_4_remote(arp_globals.net_phone,605 606 packet = packet_get_4_remote(arp_globals.net_phone, 651 607 device->packet_dimension.addr_len, device->packet_dimension.prefix, 652 608 length, device->packet_dimension.suffix); 653 609 if (!packet) 654 610 return ENOMEM; 655 656 arp_header_t *header = (arp_header_t *) packet_suffix(packet, length);611 612 header = (arp_header_t *) packet_suffix(packet, length); 657 613 if (!header) { 658 614 pq_release_remote(arp_globals.net_phone, packet_get_id(packet)); 659 615 return ENOMEM; 660 616 } 661 617 662 618 header->hardware = htons(device->hardware); 663 619 header->hardware_length = (uint8_t) device->addr->length; … … 665 621 header->protocol_length = (uint8_t) proto->addr->length; 666 622 header->operation = htons(ARPOP_REQUEST); 667 668 623 length = sizeof(arp_header_t); 669 670 624 memcpy(((uint8_t *) header) + length, device->addr->value, 671 625 device->addr->length); … … 677 631 length += device->addr->length; 678 632 memcpy(((uint8_t *) header) + length, target->value, target->length); 679 680 intrc = packet_set_addr(packet, (uint8_t *) device->addr->value,633 634 rc = packet_set_addr(packet, (uint8_t *) device->addr->value, 681 635 (uint8_t *) device->broadcast_addr->value, device->addr->length); 682 636 if (rc != EOK) { … … 684 638 return rc; 685 639 } 686 640 687 641 nil_send_msg(device->phone, device_id, packet, SERVICE_ARP); 688 return EOK; 689 } 690 691 /** Return the hardware address for the given protocol address. 692 * 693 * Send the ARP request packet if the hardware address is not found in the 694 * cache. 695 * 696 * @param[in] device_id Device identifier. 697 * @param[in] protocol Protocol service. 698 * @param[in] target Target protocol address. 699 * @param[out] translation Where the hardware address of the target is stored. 700 * 701 * @return EOK on success. 702 * @return EAGAIN if the caller should try again. 703 * @return Other error codes in case of error. 704 * 705 */ 706 static int arp_translate_message(device_id_t device_id, services_t protocol, 707 measured_string_t *target, measured_string_t **translation) 708 { 709 bool retry = false; 710 int rc; 711 712 assert(fibril_mutex_is_locked(&arp_globals.lock)); 713 714 restart: 715 if ((!target) || (!translation)) 716 return EBADMEM; 717 718 arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id); 719 if (!device) 720 return ENOENT; 721 722 arp_proto_t *proto = arp_protos_find(&device->protos, protocol); 723 if ((!proto) || (proto->addr->length != target->length)) 724 return ENOENT; 725 726 arp_trans_t *trans = arp_addr_find(&proto->addresses, target->value, 727 target->length); 728 if (trans) { 729 if (trans->hw_addr) { 730 /* The translation is in place. */ 731 *translation = trans->hw_addr; 732 return EOK; 733 } 734 735 if (retry) { 736 /* 737 * We may get here as a result of being signalled for 738 * some reason while waiting for the translation (e.g. 739 * translation becoming available, record being removed 740 * from the table) and then losing the race for 741 * the arp_globals.lock with someone else who modified 742 * the table. 743 * 744 * Remove the incomplete record so that it is possible 745 * to make new ARP requests. 746 */ 747 arp_clear_trans(trans); 748 arp_addr_exclude(&proto->addresses, target->value, 749 target->length); 750 return EAGAIN; 751 } 752 753 /* 754 * We are a random passer-by who merely joins an already waiting 755 * fibril in waiting for the translation. 756 */ 757 rc = fibril_condvar_wait_timeout(&trans->cv, &arp_globals.lock, 758 ARP_TRANS_WAIT); 759 if (rc == ETIMEOUT) 760 return ENOENT; 761 762 /* 763 * Need to recheck because we did not hold the lock while 764 * sleeping on the condition variable. 765 */ 766 retry = true; 767 goto restart; 768 } 769 770 if (retry) 771 return EAGAIN; 772 773 /* 774 * We are under the protection of arp_globals.lock, so we can afford to 775 * first send the ARP request and then insert an incomplete ARP record. 776 * The incomplete record is used to tell any other potential waiter 777 * that this fibril has already sent the request and that it is waiting 778 * for the answer. Lastly, any fibril which sees the incomplete request 779 * can perform a timed wait on its condition variable to wait for the 780 * ARP reply to arrive. 781 */ 782 783 rc = arp_send_request(device_id, protocol, target, device, proto); 784 if (rc != EOK) 785 return rc; 786 642 787 643 trans = (arp_trans_t *) malloc(sizeof(arp_trans_t)); 788 644 if (!trans) 789 645 return ENOMEM; 790 791 646 trans->hw_addr = NULL; 792 647 fibril_condvar_initialize(&trans->cv); 793 794 648 rc = arp_addr_add(&proto->addresses, target->value, target->length, 795 649 trans); … … 801 655 rc = fibril_condvar_wait_timeout(&trans->cv, &arp_globals.lock, 802 656 ARP_TRANS_WAIT); 803 if (rc == ETIMEOUT) { 804 /* 805 * Remove the incomplete record so that it is possible to make 806 * new ARP requests. 807 */ 808 arp_clear_trans(trans); 809 arp_addr_exclude(&proto->addresses, target->value, 810 target->length); 657 if (rc == ETIMEOUT) 811 658 return ENOENT; 812 }813 814 /*815 * We need to recheck that the translation has indeed become available,816 * because we dropped the arp_globals.lock while sleeping on the817 * condition variable and someone else might have e.g. removed the818 * translation before we managed to lock arp_globals.lock again.819 */820 821 659 retry = true; 822 660 goto restart; 823 661 } 824 662 825 /** Process the ARP message. 826 * 827 * @param[in] callid Message identifier. 828 * @param[in] call Message parameters. 829 * @param[out] answer Answer. 830 * @param[out] count Number of arguments of the answer. 831 * 832 * @return EOK on success. 833 * @return ENOTSUP if the message is not known. 663 664 /** Processes the ARP message. 665 * 666 * @param[in] callid The message identifier. 667 * @param[in] call The message parameters. 668 * @param[out] answer The message answer parameters. 669 * @param[out] answer_count The last parameter for the actual answer in the 670 * answer parameter. 671 * @return EOK on success. 672 * @return ENOTSUP if the message is not known. 834 673 * 835 674 * @see arp_interface.h 836 675 * @see IS_NET_ARP_MESSAGE() 837 * 838 */ 839 int il_module_message(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer,840 size_t *count)676 */ 677 int 678 arp_message_standalone(ipc_callid_t callid, ipc_call_t *call, 679 ipc_call_t *answer, size_t *answer_count) 841 680 { 842 681 measured_string_t *address; 843 682 measured_string_t *translation; 844 683 uint8_t *data; 684 packet_t *packet; 685 packet_t *next; 845 686 int rc; 846 687 847 * count = 0;688 *answer_count = 0; 848 689 switch (IPC_GET_IMETHOD(*call)) { 849 690 case IPC_M_PHONE_HUNGUP: … … 861 702 free(data); 862 703 } 863 864 704 return rc; 865 705 … … 874 714 free(address); 875 715 free(data); 876 877 716 if (rc != EOK) { 878 717 fibril_mutex_unlock(&arp_globals.lock); 879 718 return rc; 880 719 } 881 882 720 if (!translation) { 883 721 fibril_mutex_unlock(&arp_globals.lock); 884 722 return ENOENT; 885 723 } 886 887 724 rc = measured_strings_reply(translation, 1); 888 725 fibril_mutex_unlock(&arp_globals.lock); 889 726 return rc; 890 727 891 728 case NET_ARP_CLEAR_DEVICE: 892 729 return arp_clear_device_req(0, IPC_GET_DEVICE(*call)); 893 730 894 731 case NET_ARP_CLEAR_ADDRESS: 895 732 rc = measured_strings_receive(&address, &data, 1); … … 905 742 case NET_ARP_CLEAN_CACHE: 906 743 return arp_clean_cache_req(0); 744 745 case NET_IL_DEVICE_STATE: 746 /* Do nothing - keep the cache */ 747 return EOK; 748 749 case NET_IL_RECEIVED: 750 751 rc = packet_translate_remote(arp_globals.net_phone, &packet, 752 IPC_GET_PACKET(*call)); 753 if (rc != EOK) 754 return rc; 755 756 fibril_mutex_lock(&arp_globals.lock); 757 do { 758 next = pq_detach(packet); 759 rc = arp_receive_message(IPC_GET_DEVICE(*call), packet); 760 if (rc != 1) { 761 pq_release_remote(arp_globals.net_phone, 762 packet_get_id(packet)); 763 } 764 packet = next; 765 } while (packet); 766 fibril_mutex_unlock(&arp_globals.lock); 767 768 return EOK; 769 770 case NET_IL_MTU_CHANGED: 771 return arp_mtu_changed_message(IPC_GET_DEVICE(*call), 772 IPC_GET_MTU(*call)); 907 773 } 908 774 … … 910 776 } 911 777 778 /** Default thread for new connections. 779 * 780 * @param[in] iid The initial message identifier. 781 * @param[in] icall The initial message call structure. 782 */ 783 static void il_client_connection(ipc_callid_t iid, ipc_call_t *icall) 784 { 785 /* 786 * Accept the connection 787 * - Answer the first IPC_M_CONNECT_ME_TO call. 788 */ 789 ipc_answer_0(iid, EOK); 790 791 while (true) { 792 ipc_call_t answer; 793 size_t count; 794 795 /* Clear the answer structure */ 796 refresh_answer(&answer, &count); 797 798 /* Fetch the next message */ 799 ipc_call_t call; 800 ipc_callid_t callid = async_get_call(&call); 801 802 /* Process the message */ 803 int res = il_module_message_standalone(callid, &call, &answer, 804 &count); 805 806 /* 807 * End if told to either by the message or the processing 808 * result. 809 */ 810 if ((IPC_GET_IMETHOD(call) == IPC_M_PHONE_HUNGUP) || 811 (res == EHANGUP)) 812 return; 813 814 /* Answer the message */ 815 answer_call(callid, res, &answer, count); 816 } 817 } 818 819 /** Starts the module. 820 * 821 * @return EOK on success. 822 * @return Other error codes as defined for each specific module 823 * start function. 824 */ 912 825 int main(int argc, char *argv[]) 913 826 { 827 int rc; 828 914 829 /* Start the module */ 915 return il_module_start(SERVICE_ARP); 830 rc = il_module_start_standalone(il_client_connection); 831 return rc; 916 832 } 917 833 918 834 /** @} 919 835 */ 836 -
uspace/srv/net/il/arp/arp.h
r8426912a r6610565b 125 125 arp_cache_t cache; 126 126 127 /** 128 * The client connection processing function. 129 * The module skeleton propagates its own one. 130 */ 131 async_client_conn_t client_connection; 132 127 133 /** Networking module phone. */ 128 134 int net_phone; -
uspace/srv/net/il/ip/Makefile
r8426912a r6610565b 34 34 35 35 SOURCES = \ 36 ip.c 36 ip.c \ 37 ip_module.c 37 38 38 39 include $(USPACE_PREFIX)/Makefile.common -
uspace/srv/net/il/ip/ip.c
r8426912a r6610565b 35 35 * @see arp.h 36 36 */ 37 38 #include "ip.h" 39 #include "ip_module.h" 37 40 38 41 #include <async.h> … … 49 52 #include <sys/types.h> 50 53 #include <byteorder.h> 51 #include "ip.h"52 54 53 55 #include <adt/measured_strings.h> … … 68 70 #include <icmp_client.h> 69 71 #include <icmp_interface.h> 72 #include <il_interface.h> 70 73 #include <ip_client.h> 71 74 #include <ip_interface.h> 72 75 #include <ip_header.h> 73 76 #include <net_interface.h> 74 #include <nil_ remote.h>75 #include <tl_ remote.h>77 #include <nil_interface.h> 78 #include <tl_interface.h> 76 79 #include <packet_remote.h> 77 #include <il_remote.h> 78 #include <il_skel.h> 80 #include <il_local.h> 79 81 80 82 /** IP module name. */ … … 120 122 INT_MAP_IMPLEMENT(ip_protos, ip_proto_t); 121 123 GENERIC_FIELD_IMPLEMENT(ip_routes, ip_route_t); 122 123 static void ip_receiver(ipc_callid_t, ipc_call_t *);124 124 125 125 /** Releases the packet and returns the result. … … 244 244 } 245 245 246 int il_initialize(int net_phone) 247 { 246 /** Initializes the IP module. 247 * 248 * @param[in] client_connection The client connection processing function. The 249 * module skeleton propagates its own one. 250 * @return EOK on success. 251 * @return ENOMEM if there is not enough memory left. 252 */ 253 int ip_initialize(async_client_conn_t client_connection) 254 { 255 int rc; 256 248 257 fibril_rwlock_initialize(&ip_globals.lock); 249 258 fibril_rwlock_write_lock(&ip_globals.lock); 250 259 fibril_rwlock_initialize(&ip_globals.protos_lock); 251 260 fibril_rwlock_initialize(&ip_globals.netifs_lock); 252 253 ip_globals.net_phone = net_phone;254 261 ip_globals.packet_counter = 0; 255 262 ip_globals.gateway.address.s_addr = 0; … … 257 264 ip_globals.gateway.gateway.s_addr = 0; 258 265 ip_globals.gateway.netif = NULL; 259 260 int rc = ip_netifs_initialize(&ip_globals.netifs); 266 ip_globals.client_connection = client_connection; 267 268 rc = ip_netifs_initialize(&ip_globals.netifs); 261 269 if (rc != EOK) 262 270 goto out; … … 423 431 ip_netif->phone = nil_bind_service(ip_netif->service, 424 432 (sysarg_t) ip_netif->device_id, SERVICE_IP, 425 ip_ receiver);433 ip_globals.client_connection); 426 434 if (ip_netif->phone < 0) { 427 435 printf("Failed to contact the nil service %d\n", … … 479 487 } 480 488 481 static int ip_device_req_local(int il_phone, device_id_t device_id, 482 services_t netif) 483 { 484 ip_netif_t *ip_netif; 485 ip_route_t *route; 486 int index; 487 int rc; 488 489 ip_netif = (ip_netif_t *) malloc(sizeof(ip_netif_t)); 490 if (!ip_netif) 491 return ENOMEM; 492 493 rc = ip_routes_initialize(&ip_netif->routes); 494 if (rc != EOK) { 495 free(ip_netif); 496 return rc; 497 } 498 499 ip_netif->device_id = device_id; 500 ip_netif->service = netif; 501 ip_netif->state = NETIF_STOPPED; 489 /** Updates the device content length according to the new MTU value. 490 * 491 * @param[in] device_id The device identifier. 492 * @param[in] mtu The new mtu value. 493 * @return EOK on success. 494 * @return ENOENT if device is not found. 495 */ 496 static int ip_mtu_changed_message(device_id_t device_id, size_t mtu) 497 { 498 ip_netif_t *netif; 502 499 503 500 fibril_rwlock_write_lock(&ip_globals.netifs_lock); 504 505 rc = ip_netif_initialize(ip_netif); 506 if (rc != EOK) { 501 netif = ip_netifs_find(&ip_globals.netifs, device_id); 502 if (!netif) { 507 503 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 508 ip_routes_destroy(&ip_netif->routes); 509 free(ip_netif); 510 return rc; 511 } 512 if (ip_netif->arp) 513 ip_netif->arp->usage++; 514 515 // print the settings 516 printf("%s: Device registered (id: %d, phone: %d, ipv: %d, conf: %s)\n", 517 NAME, ip_netif->device_id, ip_netif->phone, ip_netif->ipv, 518 ip_netif->dhcp ? "dhcp" : "static"); 519 520 // TODO ipv6 addresses 521 522 char address[INET_ADDRSTRLEN]; 523 char netmask[INET_ADDRSTRLEN]; 524 char gateway[INET_ADDRSTRLEN]; 525 526 for (index = 0; index < ip_routes_count(&ip_netif->routes); index++) { 527 route = ip_routes_get_index(&ip_netif->routes, index); 528 if (route) { 529 inet_ntop(AF_INET, (uint8_t *) &route->address.s_addr, 530 address, INET_ADDRSTRLEN); 531 inet_ntop(AF_INET, (uint8_t *) &route->netmask.s_addr, 532 netmask, INET_ADDRSTRLEN); 533 inet_ntop(AF_INET, (uint8_t *) &route->gateway.s_addr, 534 gateway, INET_ADDRSTRLEN); 535 printf("%s: Route %d (address: %s, netmask: %s, " 536 "gateway: %s)\n", NAME, index, address, netmask, 537 gateway); 538 } 539 } 540 541 inet_ntop(AF_INET, (uint8_t *) &ip_netif->broadcast.s_addr, address, 542 INET_ADDRSTRLEN); 504 return ENOENT; 505 } 506 netif->packet_dimension.content = mtu; 543 507 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 544 508 545 printf("%s: Broadcast (%s)\n", NAME, address);509 printf("%s: Device %d changed MTU to %zu\n", NAME, device_id, mtu); 546 510 547 511 return EOK; 548 512 } 549 513 550 /** Searches the network interfaces if there is a suitable route. 551 * 552 * @param[in] netif The network interface to be searched for routes. May be 553 * NULL. 554 * @param[in] destination The destination address. 555 * @return The found route. 556 * @return NULL if no route was found. 557 */ 558 static ip_route_t *ip_netif_find_route(ip_netif_t *netif, 559 in_addr_t destination) 560 { 561 int index; 562 ip_route_t *route; 563 564 if (!netif) 514 /** Updates the device state. 515 * 516 * @param[in] device_id The device identifier. 517 * @param[in] state The new state value. 518 * @return EOK on success. 519 * @return ENOENT if device is not found. 520 */ 521 static int ip_device_state_message(device_id_t device_id, device_state_t state) 522 { 523 ip_netif_t *netif; 524 525 fibril_rwlock_write_lock(&ip_globals.netifs_lock); 526 // find the device 527 netif = ip_netifs_find(&ip_globals.netifs, device_id); 528 if (!netif) { 529 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 530 return ENOENT; 531 } 532 netif->state = state; 533 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 534 535 printf("%s: Device %d changed state to %d\n", NAME, device_id, state); 536 537 return EOK; 538 } 539 540 541 /** Prefixes a middle fragment header based on the last fragment header to the 542 * packet. 543 * 544 * @param[in] packet The packet to be prefixed. 545 * @param[in] last The last header to be copied. 546 * @return The prefixed middle header. 547 * @return NULL on error. 548 */ 549 static ip_header_t * 550 ip_create_middle_header(packet_t *packet, ip_header_t *last) 551 { 552 ip_header_t *middle; 553 554 middle = (ip_header_t *) packet_suffix(packet, IP_HEADER_LENGTH(last)); 555 if (!middle) 565 556 return NULL; 566 567 /* Start with the first one (the direct route) */ 568 for (index = 0; index < ip_routes_count(&netif->routes); index++) { 569 route = ip_routes_get_index(&netif->routes, index); 570 if ((route) && 571 ((route->address.s_addr & route->netmask.s_addr) == 572 (destination.s_addr & route->netmask.s_addr))) 573 return route; 574 } 575 576 return NULL; 577 } 578 579 /** Searches all network interfaces if there is a suitable route. 580 * 581 * @param[in] destination The destination address. 582 * @return The found route. 583 * @return NULL if no route was found. 584 */ 585 static ip_route_t *ip_find_route(in_addr_t destination) { 586 int index; 587 ip_route_t *route; 588 ip_netif_t *netif; 589 590 // start with the last netif - the newest one 591 index = ip_netifs_count(&ip_globals.netifs) - 1; 592 while (index >= 0) { 593 netif = ip_netifs_get_index(&ip_globals.netifs, index); 594 if (netif && (netif->state == NETIF_ACTIVE)) { 595 route = ip_netif_find_route(netif, destination); 596 if (route) 597 return route; 598 } 599 index--; 600 } 601 602 return &ip_globals.gateway; 603 } 604 605 /** Returns the network interface's IP address. 606 * 607 * @param[in] netif The network interface. 608 * @return The IP address. 609 * @return NULL if no IP address was found. 610 */ 611 static in_addr_t *ip_netif_address(ip_netif_t *netif) 612 { 613 ip_route_t *route; 614 615 route = ip_routes_get_index(&netif->routes, 0); 616 return route ? &route->address : NULL; 557 memcpy(middle, last, IP_HEADER_LENGTH(last)); 558 middle->flags |= IPFLAG_MORE_FRAGMENTS; 559 return middle; 617 560 } 618 561 … … 683 626 * function. 684 627 */ 685 static int ip_prepare_packet(in_addr_t *source, in_addr_t dest, 686 packet_t *packet, measured_string_t *destination) 628 static int 629 ip_prepare_packet(in_addr_t *source, in_addr_t dest, packet_t *packet, 630 measured_string_t *destination) 687 631 { 688 632 size_t length; … … 813 757 * function. 814 758 */ 815 static int ip_fragment_packet_data(packet_t *packet, packet_t *new_packet, 759 static int 760 ip_fragment_packet_data(packet_t *packet, packet_t *new_packet, 816 761 ip_header_t *header, ip_header_t *new_header, size_t length, 817 762 const struct sockaddr *src, const struct sockaddr *dest, socklen_t addrlen) … … 847 792 848 793 return pq_insert_after(packet, new_packet); 849 }850 851 /** Prefixes a middle fragment header based on the last fragment header to the852 * packet.853 *854 * @param[in] packet The packet to be prefixed.855 * @param[in] last The last header to be copied.856 * @return The prefixed middle header.857 * @return NULL on error.858 */859 static ip_header_t *ip_create_middle_header(packet_t *packet,860 ip_header_t *last)861 {862 ip_header_t *middle;863 864 middle = (ip_header_t *) packet_suffix(packet, IP_HEADER_LENGTH(last));865 if (!middle)866 return NULL;867 memcpy(middle, last, IP_HEADER_LENGTH(last));868 middle->flags |= IPFLAG_MORE_FRAGMENTS;869 return middle;870 794 } 871 795 … … 1072 996 * function. 1073 997 */ 1074 static int ip_send_route(packet_t *packet, ip_netif_t *netif, 1075 ip_route_t *route, in_addr_t *src, in_addr_t dest, services_t error) 998 static int 999 ip_send_route(packet_t *packet, ip_netif_t *netif, ip_route_t *route, 1000 in_addr_t *src, in_addr_t dest, services_t error) 1076 1001 { 1077 1002 measured_string_t destination; … … 1136 1061 } 1137 1062 1138 static int ip_send_msg_local(int il_phone, device_id_t device_id, 1139 packet_t *packet, services_t sender, services_t error) 1063 /** Searches the network interfaces if there is a suitable route. 1064 * 1065 * @param[in] netif The network interface to be searched for routes. May be 1066 * NULL. 1067 * @param[in] destination The destination address. 1068 * @return The found route. 1069 * @return NULL if no route was found. 1070 */ 1071 static ip_route_t * 1072 ip_netif_find_route(ip_netif_t *netif, in_addr_t destination) 1073 { 1074 int index; 1075 ip_route_t *route; 1076 1077 if (!netif) 1078 return NULL; 1079 1080 /* Start with the first one (the direct route) */ 1081 for (index = 0; index < ip_routes_count(&netif->routes); index++) { 1082 route = ip_routes_get_index(&netif->routes, index); 1083 if ((route) && 1084 ((route->address.s_addr & route->netmask.s_addr) == 1085 (destination.s_addr & route->netmask.s_addr))) 1086 return route; 1087 } 1088 1089 return NULL; 1090 } 1091 1092 /** Searches all network interfaces if there is a suitable route. 1093 * 1094 * @param[in] destination The destination address. 1095 * @return The found route. 1096 * @return NULL if no route was found. 1097 */ 1098 static ip_route_t *ip_find_route(in_addr_t destination) { 1099 int index; 1100 ip_route_t *route; 1101 ip_netif_t *netif; 1102 1103 // start with the last netif - the newest one 1104 index = ip_netifs_count(&ip_globals.netifs) - 1; 1105 while (index >= 0) { 1106 netif = ip_netifs_get_index(&ip_globals.netifs, index); 1107 if (netif && (netif->state == NETIF_ACTIVE)) { 1108 route = ip_netif_find_route(netif, destination); 1109 if (route) 1110 return route; 1111 } 1112 index--; 1113 } 1114 1115 return &ip_globals.gateway; 1116 } 1117 1118 /** Returns the network interface's IP address. 1119 * 1120 * @param[in] netif The network interface. 1121 * @return The IP address. 1122 * @return NULL if no IP address was found. 1123 */ 1124 static in_addr_t *ip_netif_address(ip_netif_t *netif) 1125 { 1126 ip_route_t *route; 1127 1128 route = ip_routes_get_index(&netif->routes, 0); 1129 return route ? &route->address : NULL; 1130 } 1131 1132 /** Registers the transport layer protocol. 1133 * 1134 * The traffic of this protocol will be supplied using either the receive 1135 * function or IPC message. 1136 * 1137 * @param[in] protocol The transport layer module protocol. 1138 * @param[in] service The transport layer module service. 1139 * @param[in] phone The transport layer module phone. 1140 * @param[in] received_msg The receiving function. 1141 * @return EOK on success. 1142 * @return EINVAL if the protocol parameter and/or the service 1143 * parameter is zero. 1144 * @return EINVAL if the phone parameter is not a positive number 1145 * and the tl_receive_msg is NULL. 1146 * @return ENOMEM if there is not enough memory left. 1147 */ 1148 static int 1149 ip_register(int protocol, services_t service, int phone, 1150 tl_received_msg_t received_msg) 1151 { 1152 ip_proto_t *proto; 1153 int index; 1154 1155 if (!protocol || !service || ((phone < 0) && !received_msg)) 1156 return EINVAL; 1157 1158 proto = (ip_proto_t *) malloc(sizeof(ip_protos_t)); 1159 if (!proto) 1160 return ENOMEM; 1161 1162 proto->protocol = protocol; 1163 proto->service = service; 1164 proto->phone = phone; 1165 proto->received_msg = received_msg; 1166 1167 fibril_rwlock_write_lock(&ip_globals.protos_lock); 1168 index = ip_protos_add(&ip_globals.protos, proto->protocol, proto); 1169 if (index < 0) { 1170 fibril_rwlock_write_unlock(&ip_globals.protos_lock); 1171 free(proto); 1172 return index; 1173 } 1174 fibril_rwlock_write_unlock(&ip_globals.protos_lock); 1175 1176 printf("%s: Protocol registered (protocol: %d, phone: %d)\n", 1177 NAME, proto->protocol, proto->phone); 1178 1179 return EOK; 1180 } 1181 1182 static int 1183 ip_device_req_local(int il_phone, device_id_t device_id, services_t netif) 1184 { 1185 ip_netif_t *ip_netif; 1186 ip_route_t *route; 1187 int index; 1188 int rc; 1189 1190 ip_netif = (ip_netif_t *) malloc(sizeof(ip_netif_t)); 1191 if (!ip_netif) 1192 return ENOMEM; 1193 1194 rc = ip_routes_initialize(&ip_netif->routes); 1195 if (rc != EOK) { 1196 free(ip_netif); 1197 return rc; 1198 } 1199 1200 ip_netif->device_id = device_id; 1201 ip_netif->service = netif; 1202 ip_netif->state = NETIF_STOPPED; 1203 1204 fibril_rwlock_write_lock(&ip_globals.netifs_lock); 1205 1206 rc = ip_netif_initialize(ip_netif); 1207 if (rc != EOK) { 1208 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 1209 ip_routes_destroy(&ip_netif->routes); 1210 free(ip_netif); 1211 return rc; 1212 } 1213 if (ip_netif->arp) 1214 ip_netif->arp->usage++; 1215 1216 // print the settings 1217 printf("%s: Device registered (id: %d, phone: %d, ipv: %d, conf: %s)\n", 1218 NAME, ip_netif->device_id, ip_netif->phone, ip_netif->ipv, 1219 ip_netif->dhcp ? "dhcp" : "static"); 1220 1221 // TODO ipv6 addresses 1222 1223 char address[INET_ADDRSTRLEN]; 1224 char netmask[INET_ADDRSTRLEN]; 1225 char gateway[INET_ADDRSTRLEN]; 1226 1227 for (index = 0; index < ip_routes_count(&ip_netif->routes); index++) { 1228 route = ip_routes_get_index(&ip_netif->routes, index); 1229 if (route) { 1230 inet_ntop(AF_INET, (uint8_t *) &route->address.s_addr, 1231 address, INET_ADDRSTRLEN); 1232 inet_ntop(AF_INET, (uint8_t *) &route->netmask.s_addr, 1233 netmask, INET_ADDRSTRLEN); 1234 inet_ntop(AF_INET, (uint8_t *) &route->gateway.s_addr, 1235 gateway, INET_ADDRSTRLEN); 1236 printf("%s: Route %d (address: %s, netmask: %s, " 1237 "gateway: %s)\n", NAME, index, address, netmask, 1238 gateway); 1239 } 1240 } 1241 1242 inet_ntop(AF_INET, (uint8_t *) &ip_netif->broadcast.s_addr, address, 1243 INET_ADDRSTRLEN); 1244 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 1245 1246 printf("%s: Broadcast (%s)\n", NAME, address); 1247 1248 return EOK; 1249 } 1250 1251 static int 1252 ip_send_msg_local(int il_phone, device_id_t device_id, packet_t *packet, 1253 services_t sender, services_t error) 1140 1254 { 1141 1255 int addrlen; … … 1241 1355 } 1242 1356 1243 /** Updates the device state. 1244 * 1357 /** Returns the device packet dimensions for sending. 1358 * 1359 * @param[in] phone The service module phone. 1360 * @param[in] message The service specific message. 1245 1361 * @param[in] device_id The device identifier. 1246 * @param[in] state The new state value. 1362 * @param[out] addr_len The minimum reserved address length. 1363 * @param[out] prefix The minimum reserved prefix size. 1364 * @param[out] content The maximum content size. 1365 * @param[out] suffix The minimum reserved suffix size. 1247 1366 * @return EOK on success. 1248 * @return ENOENT if device is not found. 1249 */ 1250 static int ip_device_state_message(device_id_t device_id, device_state_t state) 1367 */ 1368 static int 1369 ip_packet_size_message(device_id_t device_id, size_t *addr_len, size_t *prefix, 1370 size_t *content, size_t *suffix) 1251 1371 { 1252 1372 ip_netif_t *netif; 1253 1254 fibril_rwlock_write_lock(&ip_globals.netifs_lock); 1255 // find the device 1256 netif = ip_netifs_find(&ip_globals.netifs, device_id); 1257 if (!netif) { 1258 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 1259 return ENOENT; 1260 } 1261 netif->state = state; 1262 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 1263 1264 printf("%s: Device %d changed state to %d\n", NAME, device_id, state); 1373 int index; 1374 1375 if (!addr_len || !prefix || !content || !suffix) 1376 return EBADMEM; 1377 1378 *content = IP_MAX_CONTENT - IP_PREFIX; 1379 fibril_rwlock_read_lock(&ip_globals.netifs_lock); 1380 if (device_id < 0) { 1381 *addr_len = IP_ADDR; 1382 *prefix = 0; 1383 *suffix = 0; 1384 1385 for (index = ip_netifs_count(&ip_globals.netifs) - 1; 1386 index >= 0; index--) { 1387 netif = ip_netifs_get_index(&ip_globals.netifs, index); 1388 if (!netif) 1389 continue; 1390 1391 if (netif->packet_dimension.addr_len > *addr_len) 1392 *addr_len = netif->packet_dimension.addr_len; 1393 1394 if (netif->packet_dimension.prefix > *prefix) 1395 *prefix = netif->packet_dimension.prefix; 1396 1397 if (netif->packet_dimension.suffix > *suffix) 1398 *suffix = netif->packet_dimension.suffix; 1399 } 1400 1401 *prefix = *prefix + IP_PREFIX; 1402 *suffix = *suffix + IP_SUFFIX; 1403 } else { 1404 netif = ip_netifs_find(&ip_globals.netifs, device_id); 1405 if (!netif) { 1406 fibril_rwlock_read_unlock(&ip_globals.netifs_lock); 1407 return ENOENT; 1408 } 1409 1410 *addr_len = (netif->packet_dimension.addr_len > IP_ADDR) ? 1411 netif->packet_dimension.addr_len : IP_ADDR; 1412 *prefix = netif->packet_dimension.prefix + IP_PREFIX; 1413 *suffix = netif->packet_dimension.suffix + IP_SUFFIX; 1414 } 1415 fibril_rwlock_read_unlock(&ip_globals.netifs_lock); 1265 1416 1266 1417 return EOK; … … 1302 1453 * tl_received_msg() function. 1303 1454 */ 1304 static int ip_deliver_local(device_id_t device_id, packet_t *packet, 1305 ip_header_t *header, services_t error) 1455 static int 1456 ip_deliver_local(device_id_t device_id, packet_t *packet, ip_header_t *header, 1457 services_t error) 1306 1458 { 1307 1459 ip_proto_t *proto; … … 1403 1555 * is disabled. 1404 1556 */ 1405 static int ip_process_packet(device_id_t device_id, packet_t *packet) 1557 static int 1558 ip_process_packet(device_id_t device_id, packet_t *packet) 1406 1559 { 1407 1560 ip_header_t *header; … … 1493 1646 } 1494 1647 1495 /** Returns the device packet dimensions for sending.1496 *1497 * @param[in] phone The service module phone.1498 * @param[in] message The service specific message.1499 * @param[in] device_id The device identifier.1500 * @param[out] addr_len The minimum reserved address length.1501 * @param[out] prefix The minimum reserved prefix size.1502 * @param[out] content The maximum content size.1503 * @param[out] suffix The minimum reserved suffix size.1504 * @return EOK on success.1505 */1506 static int ip_packet_size_message(device_id_t device_id, size_t *addr_len,1507 size_t *prefix, size_t *content, size_t *suffix)1508 {1509 ip_netif_t *netif;1510 int index;1511 1512 if (!addr_len || !prefix || !content || !suffix)1513 return EBADMEM;1514 1515 *content = IP_MAX_CONTENT - IP_PREFIX;1516 fibril_rwlock_read_lock(&ip_globals.netifs_lock);1517 if (device_id < 0) {1518 *addr_len = IP_ADDR;1519 *prefix = 0;1520 *suffix = 0;1521 1522 for (index = ip_netifs_count(&ip_globals.netifs) - 1;1523 index >= 0; index--) {1524 netif = ip_netifs_get_index(&ip_globals.netifs, index);1525 if (!netif)1526 continue;1527 1528 if (netif->packet_dimension.addr_len > *addr_len)1529 *addr_len = netif->packet_dimension.addr_len;1530 1531 if (netif->packet_dimension.prefix > *prefix)1532 *prefix = netif->packet_dimension.prefix;1533 1534 if (netif->packet_dimension.suffix > *suffix)1535 *suffix = netif->packet_dimension.suffix;1536 }1537 1538 *prefix = *prefix + IP_PREFIX;1539 *suffix = *suffix + IP_SUFFIX;1540 } else {1541 netif = ip_netifs_find(&ip_globals.netifs, device_id);1542 if (!netif) {1543 fibril_rwlock_read_unlock(&ip_globals.netifs_lock);1544 return ENOENT;1545 }1546 1547 *addr_len = (netif->packet_dimension.addr_len > IP_ADDR) ?1548 netif->packet_dimension.addr_len : IP_ADDR;1549 *prefix = netif->packet_dimension.prefix + IP_PREFIX;1550 *suffix = netif->packet_dimension.suffix + IP_SUFFIX;1551 }1552 fibril_rwlock_read_unlock(&ip_globals.netifs_lock);1553 1554 return EOK;1555 }1556 1557 /** Updates the device content length according to the new MTU value.1558 *1559 * @param[in] device_id The device identifier.1560 * @param[in] mtu The new mtu value.1561 * @return EOK on success.1562 * @return ENOENT if device is not found.1563 */1564 static int ip_mtu_changed_message(device_id_t device_id, size_t mtu)1565 {1566 ip_netif_t *netif;1567 1568 fibril_rwlock_write_lock(&ip_globals.netifs_lock);1569 netif = ip_netifs_find(&ip_globals.netifs, device_id);1570 if (!netif) {1571 fibril_rwlock_write_unlock(&ip_globals.netifs_lock);1572 return ENOENT;1573 }1574 netif->packet_dimension.content = mtu;1575 fibril_rwlock_write_unlock(&ip_globals.netifs_lock);1576 1577 printf("%s: Device %d changed MTU to %zu\n", NAME, device_id, mtu);1578 1579 return EOK;1580 }1581 1582 /** Process IPC messages from the registered device driver modules1583 *1584 * @param[in] iid Message identifier.1585 * @param[in,out] icall Message parameters.1586 *1587 */1588 static void ip_receiver(ipc_callid_t iid, ipc_call_t *icall)1589 {1590 packet_t *packet;1591 int rc;1592 1593 while (true) {1594 switch (IPC_GET_IMETHOD(*icall)) {1595 case NET_IL_DEVICE_STATE:1596 rc = ip_device_state_message(IPC_GET_DEVICE(*icall),1597 IPC_GET_STATE(*icall));1598 ipc_answer_0(iid, (sysarg_t) rc);1599 break;1600 1601 case NET_IL_RECEIVED:1602 rc = packet_translate_remote(ip_globals.net_phone, &packet,1603 IPC_GET_PACKET(*icall));1604 if (rc == EOK) {1605 do {1606 packet_t *next = pq_detach(packet);1607 ip_process_packet(IPC_GET_DEVICE(*icall), packet);1608 packet = next;1609 } while (packet);1610 }1611 1612 ipc_answer_0(iid, (sysarg_t) rc);1613 break;1614 1615 case NET_IL_MTU_CHANGED:1616 rc = ip_mtu_changed_message(IPC_GET_DEVICE(*icall),1617 IPC_GET_MTU(*icall));1618 ipc_answer_0(iid, (sysarg_t) rc);1619 break;1620 1621 default:1622 ipc_answer_0(iid, (sysarg_t) ENOTSUP);1623 }1624 1625 iid = async_get_call(icall);1626 }1627 }1628 1629 /** Registers the transport layer protocol.1630 *1631 * The traffic of this protocol will be supplied using either the receive1632 * function or IPC message.1633 *1634 * @param[in] protocol The transport layer module protocol.1635 * @param[in] service The transport layer module service.1636 * @param[in] phone The transport layer module phone.1637 * @param[in] received_msg The receiving function.1638 * @return EOK on success.1639 * @return EINVAL if the protocol parameter and/or the service1640 * parameter is zero.1641 * @return EINVAL if the phone parameter is not a positive number1642 * and the tl_receive_msg is NULL.1643 * @return ENOMEM if there is not enough memory left.1644 */1645 static int1646 ip_register(int protocol, services_t service, int phone,1647 tl_received_msg_t received_msg)1648 {1649 ip_proto_t *proto;1650 int index;1651 1652 if (!protocol || !service || ((phone < 0) && !received_msg))1653 return EINVAL;1654 1655 proto = (ip_proto_t *) malloc(sizeof(ip_protos_t));1656 if (!proto)1657 return ENOMEM;1658 1659 proto->protocol = protocol;1660 proto->service = service;1661 proto->phone = phone;1662 proto->received_msg = received_msg;1663 1664 fibril_rwlock_write_lock(&ip_globals.protos_lock);1665 index = ip_protos_add(&ip_globals.protos, proto->protocol, proto);1666 if (index < 0) {1667 fibril_rwlock_write_unlock(&ip_globals.protos_lock);1668 free(proto);1669 return index;1670 }1671 fibril_rwlock_write_unlock(&ip_globals.protos_lock);1672 1673 printf("%s: Protocol registered (protocol: %d, phone: %d)\n",1674 NAME, proto->protocol, proto->phone);1675 1676 return EOK;1677 }1678 1679 1680 1648 static int 1681 1649 ip_add_route_req_local(int ip_phone, device_id_t device_id, in_addr_t address, … … 1877 1845 } 1878 1846 1847 /** Processes the received IP packet or the packet queue one by one. 1848 * 1849 * The packet is either passed to another module or released on error. 1850 * 1851 * @param[in] device_id The source device identifier. 1852 * @param[in,out] packet The received packet. 1853 * @return EOK on success and the packet is no longer needed. 1854 * @return EINVAL if the packet is too small to carry the IP 1855 * packet. 1856 * @return EINVAL if the received address lengths differs from the 1857 * registered values. 1858 * @return ENOENT if the device is not found in the cache. 1859 * @return ENOENT if the protocol for the device is not found in 1860 * the cache. 1861 * @return ENOMEM if there is not enough memory left. 1862 */ 1863 static int ip_receive_message(device_id_t device_id, packet_t *packet) 1864 { 1865 packet_t *next; 1866 1867 do { 1868 next = pq_detach(packet); 1869 ip_process_packet(device_id, packet); 1870 packet = next; 1871 } while (packet); 1872 1873 return EOK; 1874 } 1875 1879 1876 /** Processes the IP message. 1880 1877 * … … 1888 1885 * 1889 1886 * @see ip_interface.h 1890 * @see il_ remote.h1887 * @see il_interface.h 1891 1888 * @see IS_NET_IP_MESSAGE() 1892 1889 */ 1893 int il_module_message(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer, 1890 int 1891 ip_message_standalone(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer, 1894 1892 size_t *answer_count) 1895 1893 { 1896 1894 packet_t *packet; 1897 1895 struct sockaddr *addr; 1898 void *header;1899 size_t headerlen;1900 1896 size_t addrlen; 1901 1897 size_t prefix; 1902 1898 size_t suffix; 1903 1899 size_t content; 1900 void *header; 1901 size_t headerlen; 1904 1902 device_id_t device_id; 1905 1903 int rc; … … 1914 1912 IPC_GET_PHONE(*call), NULL); 1915 1913 1916 case NET_I P_DEVICE:1914 case NET_IL_DEVICE: 1917 1915 return ip_device_req_local(0, IPC_GET_DEVICE(*call), 1918 1916 IPC_GET_SERVICE(*call)); 1917 1918 case NET_IL_SEND: 1919 rc = packet_translate_remote(ip_globals.net_phone, &packet, 1920 IPC_GET_PACKET(*call)); 1921 if (rc != EOK) 1922 return rc; 1923 return ip_send_msg_local(0, IPC_GET_DEVICE(*call), packet, 0, 1924 IPC_GET_ERROR(*call)); 1925 1926 case NET_IL_DEVICE_STATE: 1927 return ip_device_state_message(IPC_GET_DEVICE(*call), 1928 IPC_GET_STATE(*call)); 1929 1930 case NET_IL_RECEIVED: 1931 rc = packet_translate_remote(ip_globals.net_phone, &packet, 1932 IPC_GET_PACKET(*call)); 1933 if (rc != EOK) 1934 return rc; 1935 return ip_receive_message(IPC_GET_DEVICE(*call), packet); 1919 1936 1920 1937 case NET_IP_RECEIVED_ERROR: … … 1958 1975 return rc; 1959 1976 1960 case NET_I P_PACKET_SPACE:1977 case NET_IL_PACKET_SPACE: 1961 1978 rc = ip_packet_size_message(IPC_GET_DEVICE(*call), &addrlen, 1962 1979 &prefix, &content, &suffix); … … 1971 1988 return EOK; 1972 1989 1973 case NET_IP_SEND: 1974 rc = packet_translate_remote(ip_globals.net_phone, &packet, 1975 IPC_GET_PACKET(*call)); 1976 if (rc != EOK) 1977 return rc; 1990 case NET_IL_MTU_CHANGED: 1991 return ip_mtu_changed_message(IPC_GET_DEVICE(*call), 1992 IPC_GET_MTU(*call)); 1993 } 1994 1995 return ENOTSUP; 1996 } 1997 1998 /** Default thread for new connections. 1999 * 2000 * @param[in] iid The initial message identifier. 2001 * @param[in] icall The initial message call structure. 2002 */ 2003 static void il_client_connection(ipc_callid_t iid, ipc_call_t *icall) 2004 { 2005 /* 2006 * Accept the connection 2007 * - Answer the first IPC_M_CONNECT_ME_TO call. 2008 */ 2009 ipc_answer_0(iid, EOK); 2010 2011 while (true) { 2012 ipc_call_t answer; 2013 size_t count; 1978 2014 1979 return ip_send_msg_local(0, IPC_GET_DEVICE(*call), packet, 0, 1980 IPC_GET_ERROR(*call)); 1981 } 1982 1983 return ENOTSUP; 1984 } 1985 2015 /* Clear the answer structure */ 2016 refresh_answer(&answer, &count); 2017 2018 /* Fetch the next message */ 2019 ipc_call_t call; 2020 ipc_callid_t callid = async_get_call(&call); 2021 2022 /* Process the message */ 2023 int res = il_module_message_standalone(callid, &call, &answer, 2024 &count); 2025 2026 /* 2027 * End if told to either by the message or the processing 2028 * result. 2029 */ 2030 if ((IPC_GET_IMETHOD(call) == IPC_M_PHONE_HUNGUP) || 2031 (res == EHANGUP)) { 2032 return; 2033 } 2034 2035 /* Answer the message */ 2036 answer_call(callid, res, &answer, count); 2037 } 2038 } 2039 2040 /** Starts the module. 2041 * 2042 * @return EOK on success. 2043 * @return Other error codes as defined for each specific module start function. 2044 */ 1986 2045 int main(int argc, char *argv[]) 1987 2046 { 2047 int rc; 2048 1988 2049 /* Start the module */ 1989 return il_module_start(SERVICE_IP); 2050 rc = il_module_start_standalone(il_client_connection); 2051 return rc; 1990 2052 } 1991 2053 -
uspace/srv/net/il/ip/ip.h
r8426912a r6610565b 138 138 /** IP global data. */ 139 139 struct ip_globals { 140 /** Default client connection function for support modules. */ 141 async_client_conn_t client_connection; 140 142 /** Default gateway. */ 141 143 ip_route_t gateway; -
uspace/srv/net/net/net.c
r8426912a r6610565b 45 45 #include <stdio.h> 46 46 #include <str.h> 47 #include <str_error.h>48 47 49 48 #include <ipc/ipc.h> … … 52 51 #include <ipc/net_net.h> 53 52 #include <ipc/il.h> 54 #include <ipc/nil.h>55 53 56 54 #include <net/modules.h> … … 64 62 65 63 #include <netif_remote.h> 66 #include <nil_ remote.h>64 #include <nil_interface.h> 67 65 #include <net_interface.h> 68 66 #include <ip_interface.h> … … 290 288 if (rc != EOK) 291 289 return rc; 292 rc = add_module(NULL, &net_globals.modules, (uint8_t *) NE2000_NAME,293 (uint8_t *) NE2000_FILENAME, SERVICE_NE2000, 0, connect_to_service);290 rc = add_module(NULL, &net_globals.modules, (uint8_t *) DP8390_NAME, 291 (uint8_t *) DP8390_FILENAME, SERVICE_DP8390, 0, connect_to_service); 294 292 if (rc != EOK) 295 293 return rc; … … 333 331 if (rc != EOK) 334 332 return rc; 333 335 334 336 335 rc = net_initialize(client_connection); … … 592 591 rc = start_device(netif); 593 592 if (rc != EOK) { 594 printf("%s: Error starting interface %s (%s)\n", NAME,595 netif->name, str_error(rc));596 593 measured_strings_destroy(&netif->configuration); 597 594 netifs_exclude_index(&net_globals.netifs, index); 598 599 595 return rc; 600 596 } … … 713 709 int main(int argc, char *argv[]) 714 710 { 715 return net_module_start(net_client_connection); 711 int rc; 712 713 rc = net_module_start(net_client_connection); 714 if (rc != EOK) { 715 fprintf(stderr, "%s: net_module_start error %i\n", NAME, rc); 716 return rc; 717 } 718 719 return EOK; 716 720 } 717 721 -
uspace/srv/net/net/net.h
r8426912a r6610565b 52 52 */ 53 53 54 #define NE2000_FILENAME "/srv/ne2000"55 #define NE2000_NAME "ne2000"54 #define DP8390_FILENAME "/srv/dp8390" 55 #define DP8390_NAME "dp8390" 56 56 57 57 #define ETHERNET_FILENAME "/srv/eth" -
uspace/srv/net/netif/lo/lo.c
r8426912a r6610565b 48 48 #include <packet_client.h> 49 49 #include <net/device.h> 50 #include <nil_interface.h> 50 51 #include <netif_skel.h> 51 #include <nil_remote.h> 52 53 /** Default hardware address. */ 54 #define DEFAULT_ADDR 0 52 55 53 56 /** Default address length. */ … … 57 60 #define NAME "lo" 58 61 59 static uint8_t default_addr[DEFAULT_ADDR_LEN] = 60 {0, 0, 0, 0, 0, 0};62 /** Network interface global data. */ 63 netif_globals_t netif_globals; 61 64 62 65 int netif_specific_message(ipc_callid_t callid, ipc_call_t *call, … … 71 74 return EBADMEM; 72 75 73 address->value = default_addr; 76 uint8_t *addr = (uint8_t *) malloc(DEFAULT_ADDR_LEN); 77 memset(addr, DEFAULT_ADDR, DEFAULT_ADDR_LEN); 78 79 address->value = addr; 74 80 address->length = DEFAULT_ADDR_LEN; 75 81 … … 79 85 int netif_get_device_stats(device_id_t device_id, device_stats_t *stats) 80 86 { 87 netif_device_t *device; 88 int rc; 89 81 90 if (!stats) 82 91 return EBADMEM; 83 84 netif_device_t *device; 85 int rc = find_device(device_id, &device); 92 93 rc = find_device(device_id, &device); 86 94 if (rc != EOK) 87 95 return rc; 88 96 89 97 memcpy(stats, (device_stats_t *) device->specific, 90 98 sizeof(device_stats_t)); 91 92 return EOK; 93 } 94 95 /** Change the loopback state. 96 * 97 * @param[in] device The device structure. 98 * @param[in] state The new device state. 99 * 100 * @return New state if changed. 101 * @return EOK otherwise. 102 * 103 */ 104 static void change_state_message(netif_device_t *device, device_state_t state) 99 100 return EOK; 101 } 102 103 /** Changes the loopback state. 104 * 105 * @param[in] device The device structure. 106 * @param[in] state The new device state. 107 * @return The new state if changed. 108 * @return EOK otherwise. 109 */ 110 static int change_state_message(netif_device_t *device, device_state_t state) 105 111 { 106 112 if (device->state != state) { 107 113 device->state = state; 108 114 109 const char *desc; 110 switch (state) { 111 case NETIF_ACTIVE: 112 desc = "active"; 113 break; 114 case NETIF_STOPPED: 115 desc = "stopped"; 116 break; 117 default: 118 desc = "unknown"; 119 } 115 printf("%s: State changed to %s\n", NAME, 116 (state == NETIF_ACTIVE) ? "active" : "stopped"); 120 117 121 printf("%s: State changed to %s\n", NAME, desc); 122 } 123 } 124 125 /** Create and return the loopback network interface structure. 126 * 127 * @param[in] device_id New devce identifier. 128 * @param[out] device Device structure. 129 * 130 * @return EOK on success. 131 * @return EXDEV if one loopback network interface already exists. 132 * @return ENOMEM if there is not enough memory left. 133 * 134 */ 135 static int lo_create(device_id_t device_id, netif_device_t **device) 136 { 118 return state; 119 } 120 121 return EOK; 122 } 123 124 /** Creates and returns the loopback network interface structure. 125 * 126 * @param[in] device_id The new devce identifier. 127 * @param[out] device The device structure. 128 * @return EOK on success. 129 * @return EXDEV if one loopback network interface already exists. 130 * @return ENOMEM if there is not enough memory left. 131 */ 132 static int create(device_id_t device_id, netif_device_t **device) 133 { 134 int index; 135 137 136 if (netif_device_map_count(&netif_globals.device_map) > 0) 138 137 return EXDEV; 139 138 140 139 *device = (netif_device_t *) malloc(sizeof(netif_device_t)); 141 140 if (!*device) 142 141 return ENOMEM; 143 142 144 143 (*device)->specific = (device_stats_t *) malloc(sizeof(device_stats_t)); 145 144 if (!(*device)->specific) { … … 147 146 return ENOMEM; 148 147 } 149 148 150 149 null_device_stats((device_stats_t *) (*device)->specific); 151 150 (*device)->device_id = device_id; 152 151 (*device)->nil_phone = -1; 153 152 (*device)->state = NETIF_STOPPED; 154 in t index = netif_device_map_add(&netif_globals.device_map,153 index = netif_device_map_add(&netif_globals.device_map, 155 154 (*device)->device_id, *device); 156 155 157 156 if (index < 0) { 158 157 free(*device); … … 168 167 { 169 168 sysarg_t phonehash; 169 170 170 return ipc_connect_to_me(PHONE_NS, SERVICE_LO, 0, 0, &phonehash); 171 171 } … … 173 173 int netif_probe_message(device_id_t device_id, int irq, void *io) 174 174 { 175 netif_device_t *device; 176 int rc; 177 175 178 /* Create a new device */ 176 netif_device_t *device; 177 int rc = lo_create(device_id, &device); 179 rc = create(device_id, &device); 178 180 if (rc != EOK) 179 181 return rc; 180 182 183 /* Print the settings */ 181 184 printf("%s: Device created (id: %d)\n", NAME, device->device_id); 185 182 186 return EOK; 183 187 } … … 186 190 { 187 191 netif_device_t *device; 188 int rc = find_device(device_id, &device); 192 size_t length; 193 packet_t *next; 194 int phone; 195 int rc; 196 197 rc = find_device(device_id, &device); 189 198 if (rc != EOK) 190 199 return EOK; 191 200 192 201 if (device->state != NETIF_ACTIVE) { 193 202 netif_pq_release(packet_get_id(packet)); 194 203 return EFORWARD; 195 204 } 196 197 packet_t *next = packet;205 206 next = packet; 198 207 do { 199 208 ((device_stats_t *) device->specific)->send_packets++; 200 209 ((device_stats_t *) device->specific)->receive_packets++; 201 size_tlength = packet_get_data_length(next);210 length = packet_get_data_length(next); 202 211 ((device_stats_t *) device->specific)->send_bytes += length; 203 212 ((device_stats_t *) device->specific)->receive_bytes += length; 204 213 next = pq_next(next); 205 } while 206 207 intphone = device->nil_phone;214 } while(next); 215 216 phone = device->nil_phone; 208 217 fibril_rwlock_write_unlock(&netif_globals.lock); 209 210 218 nil_received_msg(phone, device_id, packet, sender); 211 212 219 fibril_rwlock_write_lock(&netif_globals.lock); 220 213 221 return EOK; 214 222 } … … 216 224 int netif_start_message(netif_device_t *device) 217 225 { 218 change_state_message(device, NETIF_ACTIVE); 219 return device->state; 226 return change_state_message(device, NETIF_ACTIVE); 220 227 } 221 228 222 229 int netif_stop_message(netif_device_t *device) 223 230 { 224 change_state_message(device, NETIF_STOPPED); 225 return device->state; 231 return change_state_message(device, NETIF_STOPPED); 226 232 } 227 233 -
uspace/srv/net/nil/eth/Makefile
r8426912a r6610565b 42 42 43 43 SOURCES = \ 44 eth.c 44 eth.c \ 45 eth_module.c 45 46 46 47 include $(USPACE_PREFIX)/Makefile.common -
uspace/srv/net/nil/eth/eth.c
r8426912a r6610565b 45 45 46 46 #include <ipc/ipc.h> 47 #include <ipc/nil.h>48 47 #include <ipc/net.h> 49 48 #include <ipc/services.h> … … 57 56 #include <netif_remote.h> 58 57 #include <net_interface.h> 59 #include <il_remote.h> 58 #include <nil_interface.h> 59 #include <il_interface.h> 60 60 #include <adt/measured_strings.h> 61 61 #include <packet_client.h> 62 62 #include <packet_remote.h> 63 #include <nil_ skel.h>63 #include <nil_local.h> 64 64 65 65 #include "eth.h" 66 #include "eth_header.h" 66 67 67 68 /** The module name. */ … … 71 72 #define ETH_PREFIX \ 72 73 (sizeof(eth_header_t) + sizeof(eth_header_lsap_t) + \ 73 74 sizeof(eth_header_snap_t)) 74 75 75 76 /** Reserved packet suffix length. */ 76 #define ETH_SUFFIX (sizeof(eth_fcs_t)) 77 #define ETH_SUFFIX \ 78 sizeof(eth_fcs_t) 77 79 78 80 /** Maximum packet content length. */ 79 #define ETH_MAX_CONTENT 81 #define ETH_MAX_CONTENT 1500u 80 82 81 83 /** Minimum packet content length. */ 82 #define ETH_MIN_CONTENT 84 #define ETH_MIN_CONTENT 46u 83 85 84 86 /** Maximum tagged packet content length. */ 85 87 #define ETH_MAX_TAGGED_CONTENT(flags) \ 86 88 (ETH_MAX_CONTENT - \ 87 88 89 89 ((IS_8023_2_LSAP(flags) || IS_8023_2_SNAP(flags)) ? \ 90 sizeof(eth_header_lsap_t) : 0) - \ 91 (IS_8023_2_SNAP(flags) ? sizeof(eth_header_snap_t) : 0)) 90 92 91 93 /** Minimum tagged packet content length. */ 92 94 #define ETH_MIN_TAGGED_CONTENT(flags) \ 93 95 (ETH_MIN_CONTENT - \ 94 95 96 96 ((IS_8023_2_LSAP(flags) || IS_8023_2_SNAP(flags)) ? \ 97 sizeof(eth_header_lsap_t) : 0) - \ 98 (IS_8023_2_SNAP(flags) ? sizeof(eth_header_snap_t) : 0)) 97 99 98 100 /** Dummy flag shift value. */ 99 #define ETH_DUMMY_SHIFT 101 #define ETH_DUMMY_SHIFT 0 100 102 101 103 /** Mode flag shift value. */ 102 #define ETH_MODE_SHIFT 104 #define ETH_MODE_SHIFT 1 103 105 104 106 /** Dummy device flag. 105 107 * Preamble and FCS are mandatory part of the packets. 106 108 */ 107 #define ETH_DUMMY 109 #define ETH_DUMMY (1 << ETH_DUMMY_SHIFT) 108 110 109 111 /** Returns the dummy flag. 110 112 * @see ETH_DUMMY 111 113 */ 112 #define IS_DUMMY(flags) 114 #define IS_DUMMY(flags) ((flags) & ETH_DUMMY) 113 115 114 116 /** Device mode flags. … … 117 119 * @see ETH_8023_2_SNAP 118 120 */ 119 #define ETH_MODE_MASK 121 #define ETH_MODE_MASK (3 << ETH_MODE_SHIFT) 120 122 121 123 /** DIX Ethernet mode flag. */ 122 #define ETH_DIX 123 124 /** Return whether the DIX Ethernet mode flag is set.125 * 126 * @param[in] flags Ethernet flags.124 #define ETH_DIX (1 << ETH_MODE_SHIFT) 125 126 /** Returns whether the DIX Ethernet mode flag is set. 127 * 128 * @param[in] flags The ethernet flags. 127 129 * @see ETH_DIX 128 * 129 */ 130 #define IS_DIX(flags) (((flags) & ETH_MODE_MASK) == ETH_DIX) 130 */ 131 #define IS_DIX(flags) (((flags) & ETH_MODE_MASK) == ETH_DIX) 131 132 132 133 /** 802.3 + 802.2 + LSAP mode flag. */ 133 #define ETH_8023_2_LSAP 134 135 /** Return whether the 802.3 + 802.2 + LSAP mode flag is set.136 * 137 * @param[in] flags Ethernet flags.134 #define ETH_8023_2_LSAP (2 << ETH_MODE_SHIFT) 135 136 /** Returns whether the 802.3 + 802.2 + LSAP mode flag is set. 137 * 138 * @param[in] flags The ethernet flags. 138 139 * @see ETH_8023_2_LSAP 139 * 140 */ 141 #define IS_8023_2_LSAP(flags) (((flags) & ETH_MODE_MASK) == ETH_8023_2_LSAP) 140 */ 141 #define IS_8023_2_LSAP(flags) (((flags) & ETH_MODE_MASK) == ETH_8023_2_LSAP) 142 142 143 143 /** 802.3 + 802.2 + LSAP + SNAP mode flag. */ 144 #define ETH_8023_2_SNAP 145 146 /** Return whether the 802.3 + 802.2 + LSAP + SNAP mode flag is set.147 * 148 * @param[in] flags Ethernet flags.144 #define ETH_8023_2_SNAP (3 << ETH_MODE_SHIFT) 145 146 /** Returns whether the 802.3 + 802.2 + LSAP + SNAP mode flag is set. 147 * 148 * @param[in] flags The ethernet flags. 149 149 * @see ETH_8023_2_SNAP 150 * 151 */ 152 #define IS_8023_2_SNAP(flags) (((flags) & ETH_MODE_MASK) == ETH_8023_2_SNAP) 150 */ 151 #define IS_8023_2_SNAP(flags) (((flags) & ETH_MODE_MASK) == ETH_8023_2_SNAP) 153 152 154 153 /** Type definition of the ethernet address type. … … 247 246 rc = packet_translate_remote(eth_globals.net_phone, 248 247 &packet, IPC_GET_PACKET(*icall)); 249 if (rc == EOK) 248 if (rc == EOK) { 250 249 rc = nil_received_msg_local(0, 251 250 IPC_GET_DEVICE(*icall), packet, 0); 252 251 } 253 252 ipc_answer_0(iid, (sysarg_t) rc); 254 253 break; … … 837 836 } 838 837 839 int nil_m odule_message(ipc_callid_t callid, ipc_call_t *call,840 ipc_call_t * answer, size_t *answer_count)838 int nil_message_standalone(const char *name, ipc_callid_t callid, 839 ipc_call_t *call, ipc_call_t *answer, size_t *answer_count) 841 840 { 842 841 measured_string_t *address; … … 894 893 } 895 894 895 /** Default thread for new connections. 896 * 897 * @param[in] iid The initial message identifier. 898 * @param[in] icall The initial message call structure. 899 */ 900 static void nil_client_connection(ipc_callid_t iid, ipc_call_t *icall) 901 { 902 /* 903 * Accept the connection 904 * - Answer the first IPC_M_CONNECT_ME_TO call. 905 */ 906 ipc_answer_0(iid, EOK); 907 908 while (true) { 909 ipc_call_t answer; 910 size_t count; 911 912 /* Clear the answer structure */ 913 refresh_answer(&answer, &count); 914 915 /* Fetch the next message */ 916 ipc_call_t call; 917 ipc_callid_t callid = async_get_call(&call); 918 919 /* Process the message */ 920 int res = nil_module_message_standalone(NAME, callid, &call, 921 &answer, &count); 922 923 /* 924 * End if told to either by the message or the processing 925 * result. 926 */ 927 if ((IPC_GET_IMETHOD(call) == IPC_M_PHONE_HUNGUP) || 928 (res == EHANGUP)) 929 return; 930 931 /* Answer the message */ 932 answer_call(callid, res, &answer, count); 933 } 934 } 935 896 936 int main(int argc, char *argv[]) 897 937 { 938 int rc; 939 898 940 /* Start the module */ 899 return nil_module_start(SERVICE_ETHERNET); 941 rc = nil_module_start_standalone(nil_client_connection); 942 return rc; 900 943 } 901 944 -
uspace/srv/net/nil/eth/eth.h
r8426912a r6610565b 43 43 #include <net/device.h> 44 44 #include <adt/measured_strings.h> 45 46 /** Ethernet address length. */47 #define ETH_ADDR 648 49 /** Ethernet header preamble value. */50 #define ETH_PREAMBLE 0x5551 52 /** Ethernet header start of frame value. */53 #define ETH_SFD 0xD554 55 /** IEEE 802.2 unordered information control field. */56 #define IEEE_8023_2_UI 0x0357 58 /** Type definition of the Ethernet header IEEE 802.3 + 802.2 + SNAP extensions.59 * @see eth_header_snap60 */61 typedef struct eth_header_snap eth_header_snap_t;62 63 /** Type definition of the Ethernet header IEEE 802.3 + 802.2 + SNAP extensions.64 * @see eth_header_lsap65 */66 typedef struct eth_header_lsap eth_header_lsap_t;67 68 /** Type definition of the Ethernet header LSAP extension.69 * @see eth_ieee_lsap70 */71 typedef struct eth_ieee_lsap eth_ieee_lsap_t;72 73 /** Type definition of the Ethernet header SNAP extension.74 * @see eth_snap75 */76 typedef struct eth_snap eth_snap_t;77 78 /** Type definition of the Ethernet header preamble.79 * @see preamble80 */81 typedef struct eth_preamble eth_preamble_t;82 83 /** Type definition of the Ethernet header.84 * @see eth_header85 */86 typedef struct eth_header eth_header_t;87 88 /** Ethernet header Link Service Access Point extension. */89 struct eth_ieee_lsap {90 /**91 * Destination Service Access Point identifier.92 * The possible values are assigned by an IEEE committee.93 */94 uint8_t dsap;95 96 /**97 * Source Service Access Point identifier.98 * The possible values are assigned by an IEEE committee.99 */100 uint8_t ssap;101 102 /**103 * Control parameter.104 * The possible values are assigned by an IEEE committee.105 */106 uint8_t ctrl;107 } __attribute__ ((packed));108 109 /** Ethernet header SNAP extension. */110 struct eth_snap {111 /** Protocol identifier or organization code. */112 uint8_t protocol[3];113 114 /**115 * Ethernet protocol identifier in the network byte order (big endian).116 * @see ethernet_protocols.h117 */118 uint16_t ethertype;119 } __attribute__ ((packed));120 121 /** Ethernet header preamble.122 *123 * Used for dummy devices.124 */125 struct eth_preamble {126 /**127 * Controlling preamble used for the frame transmission synchronization.128 * All should be set to ETH_PREAMBLE.129 */130 uint8_t preamble[7];131 132 /**133 * Start of Frame Delimiter used for the frame transmission134 * synchronization.135 * Should be set to ETH_SFD.136 */137 uint8_t sfd;138 } __attribute__ ((packed));139 140 /** Ethernet header. */141 struct eth_header {142 /** Destination host Ethernet address (MAC address). */143 uint8_t destination_address[ETH_ADDR];144 /** Source host Ethernet address (MAC address). */145 uint8_t source_address[ETH_ADDR];146 147 /**148 * Ethernet protocol identifier in the network byte order (big endian).149 * @see ethernet_protocols.h150 */151 uint16_t ethertype;152 } __attribute__ ((packed));153 154 /** Ethernet header IEEE 802.3 + 802.2 extension. */155 struct eth_header_lsap {156 /** Ethernet header. */157 eth_header_t header;158 159 /**160 * LSAP extension.161 * If DSAP and SSAP are set to ETH_LSAP_SNAP the SNAP extension is being162 * used.163 * If DSAP and SSAP fields are equal to ETH_RAW the raw Ethernet packet164 * without any extensions is being used and the frame content starts165 * rigth after the two fields.166 */167 eth_ieee_lsap_t lsap;168 } __attribute__ ((packed));169 170 /** Ethernet header IEEE 802.3 + 802.2 + SNAP extensions. */171 struct eth_header_snap {172 /** Ethernet header. */173 eth_header_t header;174 175 /**176 * LSAP extension.177 * If DSAP and SSAP are set to ETH_LSAP_SNAP the SNAP extension is being178 * used.179 * If DSAP and SSAP fields are equal to ETH_RAW the raw Ethernet packet180 * without any extensions is being used and the frame content starts181 * rigth after the two fields.182 */183 eth_ieee_lsap_t lsap;184 185 /** SNAP extension. */186 eth_snap_t snap;187 } __attribute__ ((packed));188 189 /** Ethernet Frame Check Sequence. */190 typedef uint32_t eth_fcs_t;191 45 192 46 /** Type definition of the Ethernet global data. -
uspace/srv/net/nil/nildummy/Makefile
r8426912a r6610565b 42 42 43 43 SOURCES = \ 44 nildummy.c 44 nildummy.c \ 45 nildummy_module.c 45 46 46 47 include $(USPACE_PREFIX)/Makefile.common -
uspace/srv/net/nil/nildummy/nildummy.c
r8426912a r6610565b 42 42 #include <str.h> 43 43 #include <ipc/ipc.h> 44 #include <ipc/nil.h>45 44 #include <ipc/net.h> 46 45 #include <ipc/services.h> … … 48 47 #include <net/modules.h> 49 48 #include <net/device.h> 50 #include <il_remote.h> 49 #include <nil_interface.h> 50 #include <il_interface.h> 51 51 #include <adt/measured_strings.h> 52 52 #include <net/packet.h> 53 53 #include <packet_remote.h> 54 54 #include <netif_remote.h> 55 #include <nil_ skel.h>55 #include <nil_local.h> 56 56 57 57 #include "nildummy.h" … … 81 81 int nil_initialize(int net_phone) 82 82 { 83 int rc; 84 83 85 fibril_rwlock_initialize(&nildummy_globals.devices_lock); 84 86 fibril_rwlock_initialize(&nildummy_globals.protos_lock); … … 88 90 nildummy_globals.net_phone = net_phone; 89 91 nildummy_globals.proto.phone = 0; 90 intrc = nildummy_devices_initialize(&nildummy_globals.devices);92 rc = nildummy_devices_initialize(&nildummy_globals.devices); 91 93 92 94 fibril_rwlock_write_unlock(&nildummy_globals.protos_lock); … … 96 98 } 97 99 98 /** Process IPC messages from the registered device driver modules 99 * 100 * @param[in] iid Message identifier.101 * @param[in ,out] icall Message parameters.102 * 100 /** Process IPC messages from the registered device driver modules in an 101 * infinite loop. 102 * 103 * @param[in] iid The message identifier. 104 * @param[in,out] icall The message parameters. 103 105 */ 104 106 static void nildummy_receiver(ipc_callid_t iid, ipc_call_t *icall) … … 106 108 packet_t *packet; 107 109 int rc; 108 110 109 111 while (true) { 110 112 switch (IPC_GET_IMETHOD(*icall)) { … … 118 120 rc = packet_translate_remote(nildummy_globals.net_phone, 119 121 &packet, IPC_GET_PACKET(*icall)); 120 if (rc == EOK) 122 if (rc == EOK) { 121 123 rc = nil_received_msg_local(0, 122 124 IPC_GET_DEVICE(*icall), packet, 0); 123 125 } 124 126 ipc_answer_0(iid, (sysarg_t) rc); 125 127 break; … … 137 139 * Determine the device local hardware address. 138 140 * 139 * @param[in] device_id New device identifier. 140 * @param[in] service Device driver service. 141 * @param[in] mtu Device maximum transmission unit. 142 * 143 * @return EOK on success. 144 * @return EEXIST if the device with the different service exists. 145 * @return ENOMEM if there is not enough memory left. 146 * @return Other error codes as defined for the 147 * netif_bind_service() function. 148 * @return Other error codes as defined for the 149 * netif_get_addr_req() function. 150 * 141 * @param[in] device_id The new device identifier. 142 * @param[in] service The device driver service. 143 * @param[in] mtu The device maximum transmission unit. 144 * @return EOK on success. 145 * @return EEXIST if the device with the different service exists. 146 * @return ENOMEM if there is not enough memory left. 147 * @return Other error codes as defined for the 148 * netif_bind_service() function. 149 * @return Other error codes as defined for the 150 * netif_get_addr_req() function. 151 151 */ 152 152 static int nildummy_device_message(device_id_t device_id, services_t service, 153 153 size_t mtu) 154 154 { 155 nildummy_device_t *device; 156 int index; 157 int rc; 158 155 159 fibril_rwlock_write_lock(&nildummy_globals.devices_lock); 156 160 157 161 /* An existing device? */ 158 nildummy_device_t *device = 159 nildummy_devices_find(&nildummy_globals.devices, device_id); 162 device = nildummy_devices_find(&nildummy_globals.devices, device_id); 160 163 if (device) { 161 164 if (device->service != service) { … … 210 213 211 214 /* Get hardware address */ 212 int rc = netif_get_addr_req(device->phone, device->device_id,213 &device->addr , &device->addr_data);215 rc = netif_get_addr_req(device->phone, device->device_id, &device->addr, 216 &device->addr_data); 214 217 if (rc != EOK) { 215 218 fibril_rwlock_write_unlock(&nildummy_globals.devices_lock); … … 219 222 220 223 /* Add to the cache */ 221 in t index = nildummy_devices_add(&nildummy_globals.devices,224 index = nildummy_devices_add(&nildummy_globals.devices, 222 225 device->device_id, device); 223 226 if (index < 0) { … … 237 240 /** Return the device hardware address. 238 241 * 239 * @param[in] device_id Device identifier. 240 * @param[out] address Device hardware address. 241 * 242 * @return EOK on success. 243 * @return EBADMEM if the address parameter is NULL. 244 * @return ENOENT if there no such device. 242 * @param[in] device_id The device identifier. 243 * @param[out] address The device hardware address. 244 * @return EOK on success. 245 * @return EBADMEM if the address parameter is NULL. 246 * @return ENOENT if there no such device. 245 247 * 246 248 */ … … 248 250 measured_string_t **address) 249 251 { 252 nildummy_device_t *device; 253 250 254 if (!address) 251 255 return EBADMEM; 252 256 253 257 fibril_rwlock_read_lock(&nildummy_globals.devices_lock); 254 255 nildummy_device_t *device = 256 nildummy_devices_find(&nildummy_globals.devices, device_id); 258 device = nildummy_devices_find(&nildummy_globals.devices, device_id); 257 259 if (!device) { 258 260 fibril_rwlock_read_unlock(&nildummy_globals.devices_lock); 259 261 return ENOENT; 260 262 } 261 262 263 *address = device->addr; 263 264 264 fibril_rwlock_read_unlock(&nildummy_globals.devices_lock); 265 265 … … 269 269 /** Return the device packet dimensions for sending. 270 270 * 271 * @param[in] device_id Device identifier. 272 * @param[out] addr_len Minimum reserved address length. 273 * @param[out] prefix Minimum reserved prefix size. 274 * @param[out] content Maximum content size. 275 * @param[out] suffix Minimum reserved suffix size. 276 * 277 * @return EOK on success. 278 * @return EBADMEM if either one of the parameters is NULL. 279 * @return ENOENT if there is no such device. 271 * @param[in] device_id The device identifier. 272 * @param[out] addr_len The minimum reserved address length. 273 * @param[out] prefix The minimum reserved prefix size. 274 * @param[out] content The maximum content size. 275 * @param[out] suffix The minimum reserved suffix size. 276 * @return EOK on success. 277 * @return EBADMEM if either one of the parameters is NULL. 278 * @return ENOENT if there is no such device. 280 279 * 281 280 */ … … 283 282 size_t *prefix, size_t *content, size_t *suffix) 284 283 { 285 if ((!addr_len) || (!prefix) || (!content) || (!suffix)) 284 nildummy_device_t *device; 285 286 if (!addr_len || !prefix || !content || !suffix) 286 287 return EBADMEM; 287 288 288 289 fibril_rwlock_read_lock(&nildummy_globals.devices_lock); 289 290 nildummy_device_t *device = 291 nildummy_devices_find(&nildummy_globals.devices, device_id); 290 device = nildummy_devices_find(&nildummy_globals.devices, device_id); 292 291 if (!device) { 293 292 fibril_rwlock_read_unlock(&nildummy_globals.devices_lock); 294 293 return ENOENT; 295 294 } 296 295 297 296 *content = device->mtu; 298 299 297 fibril_rwlock_read_unlock(&nildummy_globals.devices_lock); 300 298 … … 308 306 packet_t *packet, services_t target) 309 307 { 308 packet_t *next; 309 310 310 fibril_rwlock_read_lock(&nildummy_globals.protos_lock); 311 312 311 if (nildummy_globals.proto.phone) { 313 312 do { 314 packet_t *next = pq_detach(packet);313 next = pq_detach(packet); 315 314 il_received_msg(nildummy_globals.proto.phone, device_id, 316 315 packet, nildummy_globals.proto.service); 317 316 packet = next; 318 } while (packet); 319 } 320 317 } while(packet); 318 } 321 319 fibril_rwlock_read_unlock(&nildummy_globals.protos_lock); 322 320 … … 328 326 * Pass received packets for this service. 329 327 * 330 * @param[in] service Module service. 331 * @param[in] phone Service phone. 332 * 333 * @return EOK on success. 334 * @return ENOENT if the service is not known. 335 * @return ENOMEM if there is not enough memory left. 336 * 328 * @param[in] service The module service. 329 * @param[in] phone The service phone. 330 * @return EOK on success. 331 * @return ENOENT if the service is not known. 332 * @return ENOMEM if there is not enough memory left. 337 333 */ 338 334 static int nildummy_register_message(services_t service, int phone) … … 351 347 /** Send the packet queue. 352 348 * 353 * @param[in] device_id Device identifier. 354 * @param[in] packet Packet queue. 355 * @param[in] sender Sending module service. 356 * 357 * @return EOK on success. 358 * @return ENOENT if there no such device. 359 * @return EINVAL if the service parameter is not known. 360 * 349 * @param[in] device_id The device identifier. 350 * @param[in] packet The packet queue. 351 * @param[in] sender The sending module service. 352 * @return EOK on success. 353 * @return ENOENT if there no such device. 354 * @return EINVAL if the service parameter is not known. 361 355 */ 362 356 static int nildummy_send_message(device_id_t device_id, packet_t *packet, 363 357 services_t sender) 364 358 { 359 nildummy_device_t *device; 360 365 361 fibril_rwlock_read_lock(&nildummy_globals.devices_lock); 366 367 nildummy_device_t *device = 368 nildummy_devices_find(&nildummy_globals.devices, device_id); 362 device = nildummy_devices_find(&nildummy_globals.devices, device_id); 369 363 if (!device) { 370 364 fibril_rwlock_read_unlock(&nildummy_globals.devices_lock); 371 365 return ENOENT; 372 366 } 373 367 374 368 /* Send packet queue */ 375 369 if (packet) 376 370 netif_send_msg(device->phone, device_id, packet, 377 371 SERVICE_NILDUMMY); 378 379 372 fibril_rwlock_read_unlock(&nildummy_globals.devices_lock); 380 381 return EOK; 382 } 383 384 int nil_module_message(ipc_callid_t callid, ipc_call_t *call, 385 ipc_call_t *answer, size_t *answer_count) 373 return EOK; 374 } 375 376 int nil_message_standalone(const char *name, ipc_callid_t callid, 377 ipc_call_t *call, ipc_call_t *answer, size_t *answer_count) 386 378 { 387 379 measured_string_t *address; … … 442 434 } 443 435 436 /** Default thread for new connections. 437 * 438 * @param[in] iid The initial message identifier. 439 * @param[in] icall The initial message call structure. 440 */ 441 static void nil_client_connection(ipc_callid_t iid, ipc_call_t *icall) 442 { 443 /* 444 * Accept the connection 445 * - Answer the first IPC_M_CONNECT_ME_TO call. 446 */ 447 ipc_answer_0(iid, EOK); 448 449 while (true) { 450 ipc_call_t answer; 451 size_t count; 452 453 /* Clear the answer structure */ 454 refresh_answer(&answer, &count); 455 456 /* Fetch the next message */ 457 ipc_call_t call; 458 ipc_callid_t callid = async_get_call(&call); 459 460 /* Process the message */ 461 int res = nil_module_message_standalone(NAME, callid, &call, 462 &answer, &count); 463 464 /* 465 * End if told to either by the message or the processing 466 * result. 467 */ 468 if ((IPC_GET_IMETHOD(call) == IPC_M_PHONE_HUNGUP) || 469 (res == EHANGUP)) 470 return; 471 472 /* Answer the message */ 473 answer_call(callid, res, &answer, count); 474 } 475 } 476 444 477 int main(int argc, char *argv[]) 445 478 { 479 int rc; 480 446 481 /* Start the module */ 447 return nil_module_start(SERVICE_NILDUMMY); 482 rc = nil_module_start_standalone(nil_client_connection); 483 return rc; 448 484 } 449 485 -
uspace/srv/net/nil/nildummy/nildummy.h
r8426912a r6610565b 45 45 46 46 /** Type definition of the dummy nil global data. 47 *48 47 * @see nildummy_globals 49 *50 48 */ 51 49 typedef struct nildummy_globals nildummy_globals_t; 52 50 53 51 /** Type definition of the dummy nil device specific data. 54 *55 52 * @see nildummy_device 56 *57 53 */ 58 54 typedef struct nildummy_device nildummy_device_t; 59 55 60 56 /** Type definition of the dummy nil protocol specific data. 61 *62 57 * @see nildummy_proto 63 *64 58 */ 65 59 typedef struct nildummy_proto nildummy_proto_t; 66 60 67 61 /** Dummy nil device map. 68 * 69 * Map devices to the dummy nil device specific data. 62 * Maps devices to the dummy nil device specific data. 70 63 * @see device.h 71 *72 64 */ 73 65 DEVICE_MAP_DECLARE(nildummy_devices, nildummy_device_t); … … 77 69 /** Device identifier. */ 78 70 device_id_t device_id; 79 80 71 /** Device driver service. */ 81 72 services_t service; 82 83 73 /** Driver phone. */ 84 74 int phone; 85 86 75 /** Maximal transmission unit. */ 87 76 size_t mtu; 88 89 77 /** Actual device hardware address. */ 90 78 measured_string_t *addr; 91 92 79 /** Actual device hardware address data. */ 93 80 uint8_t *addr_data; … … 98 85 /** Protocol service. */ 99 86 services_t service; 100 101 87 /** Protocol module phone. */ 102 88 int phone; … … 107 93 /** Networking module phone. */ 108 94 int net_phone; 109 110 /** Lock for devices. */ 95 /** Safety lock for devices. */ 111 96 fibril_rwlock_t devices_lock; 112 113 97 /** All known Ethernet devices. */ 114 98 nildummy_devices_t devices; 115 116 99 /** Safety lock for protocols. */ 117 100 fibril_rwlock_t protos_lock; 118 119 101 /** Default protocol. */ 120 102 nildummy_proto_t proto; -
uspace/srv/net/tl/icmp/Makefile
r8426912a r6610565b 34 34 35 35 SOURCES = \ 36 icmp.c 36 icmp.c \ 37 icmp_module.c 37 38 38 39 include $(USPACE_PREFIX)/Makefile.common -
uspace/srv/net/tl/icmp/icmp.c
r8426912a r6610565b 35 35 * @see icmp.h 36 36 */ 37 38 #include "icmp.h" 39 #include "icmp_module.h" 37 40 38 41 #include <async.h> … … 65 68 #include <icmp_client.h> 66 69 #include <icmp_interface.h> 67 #include <il_ remote.h>70 #include <il_interface.h> 68 71 #include <ip_client.h> 69 72 #include <ip_interface.h> 70 73 #include <net_interface.h> 71 #include <tl_ remote.h>72 #include <tl_ skel.h>74 #include <tl_interface.h> 75 #include <tl_local.h> 73 76 #include <icmp_header.h> 74 77 75 #include "icmp.h"76 77 78 /** ICMP module name. */ 78 #define NAME "icmp"79 #define NAME "ICMP protocol" 79 80 80 81 /** Default ICMP error reporting. */ … … 391 392 return icmp_send_packet(ICMP_PARAMETERPROB, code, packet, header, 392 393 SERVICE_ICMP, 0, 0, 0); 394 } 395 396 /** Initializes the ICMP module. 397 * 398 * @param[in] client_connection The client connection processing function. The 399 * module skeleton propagates its own one. 400 * @return EOK on success. 401 * @return ENOMEM if there is not enough memory left. 402 */ 403 int icmp_initialize(async_client_conn_t client_connection) 404 { 405 measured_string_t names[] = { 406 { 407 (uint8_t *) "ICMP_ERROR_REPORTING", 408 20 409 }, 410 { 411 (uint8_t *) "ICMP_ECHO_REPLYING", 412 18 413 } 414 }; 415 measured_string_t *configuration; 416 size_t count = sizeof(names) / sizeof(measured_string_t); 417 uint8_t *data; 418 int rc; 419 420 fibril_rwlock_initialize(&icmp_globals.lock); 421 fibril_rwlock_write_lock(&icmp_globals.lock); 422 icmp_replies_initialize(&icmp_globals.replies); 423 icmp_echo_data_initialize(&icmp_globals.echo_data); 424 425 icmp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_ICMP, 426 SERVICE_ICMP, client_connection); 427 if (icmp_globals.ip_phone < 0) { 428 fibril_rwlock_write_unlock(&icmp_globals.lock); 429 return icmp_globals.ip_phone; 430 } 431 432 rc = ip_packet_size_req(icmp_globals.ip_phone, -1, 433 &icmp_globals.packet_dimension); 434 if (rc != EOK) { 435 fibril_rwlock_write_unlock(&icmp_globals.lock); 436 return rc; 437 } 438 439 icmp_globals.packet_dimension.prefix += ICMP_HEADER_SIZE; 440 icmp_globals.packet_dimension.content -= ICMP_HEADER_SIZE; 441 442 icmp_globals.error_reporting = NET_DEFAULT_ICMP_ERROR_REPORTING; 443 icmp_globals.echo_replying = NET_DEFAULT_ICMP_ECHO_REPLYING; 444 445 /* Get configuration */ 446 configuration = &names[0]; 447 rc = net_get_conf_req(icmp_globals.net_phone, &configuration, count, 448 &data); 449 if (rc != EOK) { 450 fibril_rwlock_write_unlock(&icmp_globals.lock); 451 return rc; 452 } 453 454 if (configuration) { 455 if (configuration[0].value) { 456 icmp_globals.error_reporting = 457 (configuration[0].value[0] == 'y'); 458 } 459 if (configuration[1].value) { 460 icmp_globals.echo_replying = 461 (configuration[1].value[0] == 'y'); 462 } 463 net_free_settings(configuration, data); 464 } 465 466 fibril_rwlock_write_unlock(&icmp_globals.lock); 467 return EOK; 393 468 } 394 469 … … 592 667 return icmp_release_and_return(packet, rc); 593 668 594 return EOK;595 }596 597 /** Process IPC messages from the IP module598 *599 * @param[in] iid Message identifier.600 * @param[in,out] icall Message parameters.601 *602 */603 static void icmp_receiver(ipc_callid_t iid, ipc_call_t *icall)604 {605 packet_t *packet;606 int rc;607 608 while (true) {609 switch (IPC_GET_IMETHOD(*icall)) {610 case NET_TL_RECEIVED:611 rc = packet_translate_remote(icmp_globals.net_phone, &packet,612 IPC_GET_PACKET(*icall));613 if (rc == EOK)614 rc = icmp_received_msg_local(IPC_GET_DEVICE(*icall), packet,615 SERVICE_ICMP, IPC_GET_ERROR(*icall));616 617 ipc_answer_0(iid, (sysarg_t) rc);618 break;619 default:620 ipc_answer_0(iid, (sysarg_t) ENOTSUP);621 }622 623 iid = async_get_call(icall);624 }625 }626 627 /** Initialize the ICMP module.628 *629 * @param[in] net_phone Network module phone.630 *631 * @return EOK on success.632 * @return ENOMEM if there is not enough memory left.633 *634 */635 int tl_initialize(int net_phone)636 {637 measured_string_t names[] = {638 {639 (uint8_t *) "ICMP_ERROR_REPORTING",640 20641 },642 {643 (uint8_t *) "ICMP_ECHO_REPLYING",644 18645 }646 };647 measured_string_t *configuration;648 size_t count = sizeof(names) / sizeof(measured_string_t);649 uint8_t *data;650 651 fibril_rwlock_initialize(&icmp_globals.lock);652 fibril_rwlock_write_lock(&icmp_globals.lock);653 icmp_replies_initialize(&icmp_globals.replies);654 icmp_echo_data_initialize(&icmp_globals.echo_data);655 656 icmp_globals.net_phone = net_phone;657 658 icmp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_ICMP,659 SERVICE_ICMP, icmp_receiver);660 if (icmp_globals.ip_phone < 0) {661 fibril_rwlock_write_unlock(&icmp_globals.lock);662 return icmp_globals.ip_phone;663 }664 665 int rc = ip_packet_size_req(icmp_globals.ip_phone, -1,666 &icmp_globals.packet_dimension);667 if (rc != EOK) {668 fibril_rwlock_write_unlock(&icmp_globals.lock);669 return rc;670 }671 672 icmp_globals.packet_dimension.prefix += ICMP_HEADER_SIZE;673 icmp_globals.packet_dimension.content -= ICMP_HEADER_SIZE;674 675 icmp_globals.error_reporting = NET_DEFAULT_ICMP_ERROR_REPORTING;676 icmp_globals.echo_replying = NET_DEFAULT_ICMP_ECHO_REPLYING;677 678 /* Get configuration */679 configuration = &names[0];680 rc = net_get_conf_req(icmp_globals.net_phone, &configuration, count,681 &data);682 if (rc != EOK) {683 fibril_rwlock_write_unlock(&icmp_globals.lock);684 return rc;685 }686 687 if (configuration) {688 if (configuration[0].value) {689 icmp_globals.error_reporting =690 (configuration[0].value[0] == 'y');691 }692 if (configuration[1].value) {693 icmp_globals.echo_replying =694 (configuration[1].value[0] == 'y');695 }696 net_free_settings(configuration, data);697 }698 699 fibril_rwlock_write_unlock(&icmp_globals.lock);700 669 return EOK; 701 670 } … … 924 893 * @see IS_NET_ICMP_MESSAGE() 925 894 */ 926 int tl_module_message(ipc_callid_t callid, ipc_call_t *call,895 int icmp_message_standalone(ipc_callid_t callid, ipc_call_t *call, 927 896 ipc_call_t *answer, size_t *answer_count) 928 897 { 898 packet_t *packet; 899 int rc; 900 929 901 *answer_count = 0; 930 902 switch (IPC_GET_IMETHOD(*call)) { 903 case NET_TL_RECEIVED: 904 rc = packet_translate_remote(icmp_globals.net_phone, &packet, 905 IPC_GET_PACKET(*call)); 906 if (rc != EOK) 907 return rc; 908 return icmp_received_msg_local(IPC_GET_DEVICE(*call), packet, 909 SERVICE_ICMP, IPC_GET_ERROR(*call)); 910 931 911 case NET_ICMP_INIT: 932 912 return icmp_process_client_messages(callid, *call); 913 933 914 default: 934 915 return icmp_process_message(call); 935 916 } 917 918 return ENOTSUP; 919 } 920 921 922 /** Default thread for new connections. 923 * 924 * @param[in] iid The initial message identifier. 925 * @param[in] icall The initial message call structure. 926 * 927 */ 928 static void tl_client_connection(ipc_callid_t iid, ipc_call_t *icall) 929 { 930 /* 931 * Accept the connection 932 * - Answer the first IPC_M_CONNECT_ME_TO call. 933 */ 934 ipc_answer_0(iid, EOK); 936 935 937 return ENOTSUP; 938 } 939 936 while (true) { 937 ipc_call_t answer; 938 size_t answer_count; 939 940 /* Clear the answer structure */ 941 refresh_answer(&answer, &answer_count); 942 943 /* Fetch the next message */ 944 ipc_call_t call; 945 ipc_callid_t callid = async_get_call(&call); 946 947 /* Process the message */ 948 int res = tl_module_message_standalone(callid, &call, &answer, 949 &answer_count); 950 951 /* 952 * End if told to either by the message or the processing 953 * result. 954 */ 955 if ((IPC_GET_IMETHOD(call) == IPC_M_PHONE_HUNGUP) || 956 (res == EHANGUP)) 957 return; 958 959 /* Answer the message */ 960 answer_call(callid, res, &answer, answer_count); 961 } 962 } 963 964 /** Starts the module. 965 * 966 * @return EOK on success. 967 * @return Other error codes as defined for each specific module 968 * start function. 969 */ 940 970 int main(int argc, char *argv[]) 941 971 { 972 int rc; 973 942 974 /* Start the module */ 943 return tl_module_start(SERVICE_ICMP); 975 rc = tl_module_start_standalone(tl_client_connection); 976 return rc; 944 977 } 945 978 946 979 /** @} 947 980 */ 981 -
uspace/srv/net/tl/tcp/Makefile
r8426912a r6610565b 34 34 35 35 SOURCES = \ 36 tcp.c 36 tcp.c \ 37 tcp_module.c 37 38 38 39 include $(USPACE_PREFIX)/Makefile.common -
uspace/srv/net/tl/tcp/tcp.c
r8426912a r6610565b 36 36 */ 37 37 38 #include "tcp.h" 39 #include "tcp_header.h" 40 #include "tcp_module.h" 41 38 42 #include <assert.h> 39 43 #include <async.h> … … 68 72 #include <socket_core.h> 69 73 #include <tl_common.h> 70 #include <tl_remote.h> 71 #include <tl_skel.h> 72 73 #include "tcp.h" 74 #include "tcp_header.h" 74 #include <tl_local.h> 75 #include <tl_interface.h> 75 76 76 77 /** TCP module name. */ 77 #define NAME "tcp"78 #define NAME "TCP protocol" 78 79 79 80 /** The TCP window default value. */ … … 219 220 /** TCP global data. */ 220 221 tcp_globals_t tcp_globals; 222 223 /** Initializes the TCP module. 224 * 225 * @param[in] client_connection The client connection processing function. The 226 * module skeleton propagates its own one. 227 * @return EOK on success. 228 * @return ENOMEM if there is not enough memory left. 229 */ 230 int tcp_initialize(async_client_conn_t client_connection) 231 { 232 int rc; 233 234 assert(client_connection); 235 236 fibril_rwlock_initialize(&tcp_globals.lock); 237 fibril_rwlock_write_lock(&tcp_globals.lock); 238 239 tcp_globals.icmp_phone = icmp_connect_module(SERVICE_ICMP, 240 ICMP_CONNECT_TIMEOUT); 241 tcp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_TCP, 242 SERVICE_TCP, client_connection); 243 if (tcp_globals.ip_phone < 0) { 244 fibril_rwlock_write_unlock(&tcp_globals.lock); 245 return tcp_globals.ip_phone; 246 } 247 248 rc = socket_ports_initialize(&tcp_globals.sockets); 249 if (rc != EOK) 250 goto out; 251 252 rc = packet_dimensions_initialize(&tcp_globals.dimensions); 253 if (rc != EOK) { 254 socket_ports_destroy(&tcp_globals.sockets); 255 goto out; 256 } 257 258 tcp_globals.last_used_port = TCP_FREE_PORTS_START - 1; 259 260 out: 261 fibril_rwlock_write_unlock(&tcp_globals.lock); 262 return rc; 263 } 221 264 222 265 int tcp_received_msg(device_id_t device_id, packet_t *packet, … … 1217 1260 * @see IS_NET_TCP_MESSAGE() 1218 1261 */ 1219 int tl_module_message(ipc_callid_t callid, ipc_call_t *call, 1262 int 1263 tcp_message_standalone(ipc_callid_t callid, ipc_call_t *call, 1220 1264 ipc_call_t *answer, size_t *answer_count) 1221 1265 { 1266 packet_t *packet; 1267 int rc; 1268 1222 1269 assert(call); 1223 1270 assert(answer); … … 1226 1273 *answer_count = 0; 1227 1274 switch (IPC_GET_IMETHOD(*call)) { 1275 case NET_TL_RECEIVED: 1276 // fibril_rwlock_read_lock(&tcp_globals.lock); 1277 rc = packet_translate_remote(tcp_globals.net_phone, &packet, 1278 IPC_GET_PACKET(*call)); 1279 if (rc != EOK) { 1280 // fibril_rwlock_read_unlock(&tcp_globals.lock); 1281 return rc; 1282 } 1283 rc = tcp_received_msg(IPC_GET_DEVICE(*call), packet, SERVICE_TCP, 1284 IPC_GET_ERROR(*call)); 1285 // fibril_rwlock_read_unlock(&tcp_globals.lock); 1286 return rc; 1228 1287 case IPC_M_CONNECT_TO_ME: 1229 1288 return tcp_process_client_messages(callid, *call); … … 2427 2486 } 2428 2487 2429 /** Process IPC messages from the IP module2488 /** Default thread for new connections. 2430 2489 * 2431 * @param[in] iid Message identifier.2432 * @param[in ,out] icall Message parameters.2490 * @param[in] iid The initial message identifier. 2491 * @param[in] icall The initial message call structure. 2433 2492 * 2434 2493 */ 2435 static void tcp_receiver(ipc_callid_t iid, ipc_call_t *icall) 2436 { 2437 packet_t *packet; 2494 static void tl_client_connection(ipc_callid_t iid, ipc_call_t * icall) 2495 { 2496 /* 2497 * Accept the connection 2498 * - Answer the first IPC_M_CONNECT_ME_TO call. 2499 */ 2500 ipc_answer_0(iid, EOK); 2501 2502 while (true) { 2503 ipc_call_t answer; 2504 size_t answer_count; 2505 2506 /* Clear the answer structure */ 2507 refresh_answer(&answer, &answer_count); 2508 2509 /* Fetch the next message */ 2510 ipc_call_t call; 2511 ipc_callid_t callid = async_get_call(&call); 2512 2513 /* Process the message */ 2514 int res = tl_module_message_standalone(callid, &call, &answer, 2515 &answer_count); 2516 2517 /* 2518 * End if told to either by the message or the processing 2519 * result. 2520 */ 2521 if ((IPC_GET_IMETHOD(call) == IPC_M_PHONE_HUNGUP) || 2522 (res == EHANGUP)) 2523 return; 2524 2525 /* 2526 * Answer the message 2527 */ 2528 answer_call(callid, res, &answer, answer_count); 2529 } 2530 } 2531 2532 /** Starts the module. 2533 * 2534 * @return EOK on success. 2535 * @return Other error codes as defined for each specific module 2536 * start function. 2537 */ 2538 int 2539 main(int argc, char *argv[]) 2540 { 2438 2541 int rc; 2439 2440 while (true) { 2441 switch (IPC_GET_IMETHOD(*icall)) { 2442 case NET_TL_RECEIVED: 2443 rc = packet_translate_remote(tcp_globals.net_phone, &packet, 2444 IPC_GET_PACKET(*icall)); 2445 if (rc == EOK) 2446 rc = tcp_received_msg(IPC_GET_DEVICE(*icall), packet, 2447 SERVICE_TCP, IPC_GET_ERROR(*icall)); 2448 2449 ipc_answer_0(iid, (sysarg_t) rc); 2450 break; 2451 default: 2452 ipc_answer_0(iid, (sysarg_t) ENOTSUP); 2453 } 2454 2455 iid = async_get_call(icall); 2456 } 2457 } 2458 2459 /** Initialize the TCP module. 2460 * 2461 * @param[in] net_phone Network module phone. 2462 * 2463 * @return EOK on success. 2464 * @return ENOMEM if there is not enough memory left. 2465 * 2466 */ 2467 int tl_initialize(int net_phone) 2468 { 2469 fibril_rwlock_initialize(&tcp_globals.lock); 2470 fibril_rwlock_write_lock(&tcp_globals.lock); 2471 2472 tcp_globals.net_phone = net_phone; 2473 2474 tcp_globals.icmp_phone = icmp_connect_module(SERVICE_ICMP, 2475 ICMP_CONNECT_TIMEOUT); 2476 tcp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_TCP, 2477 SERVICE_TCP, tcp_receiver); 2478 if (tcp_globals.ip_phone < 0) { 2479 fibril_rwlock_write_unlock(&tcp_globals.lock); 2480 return tcp_globals.ip_phone; 2481 } 2482 2483 int rc = socket_ports_initialize(&tcp_globals.sockets); 2484 if (rc != EOK) 2485 goto out; 2486 2487 rc = packet_dimensions_initialize(&tcp_globals.dimensions); 2488 if (rc != EOK) { 2489 socket_ports_destroy(&tcp_globals.sockets); 2490 goto out; 2491 } 2492 2493 tcp_globals.last_used_port = TCP_FREE_PORTS_START - 1; 2494 2495 out: 2496 fibril_rwlock_write_unlock(&tcp_globals.lock); 2542 2543 rc = tl_module_start_standalone(tl_client_connection); 2497 2544 return rc; 2498 }2499 2500 int main(int argc, char *argv[])2501 {2502 return tl_module_start(SERVICE_TCP);2503 2545 } 2504 2546 -
uspace/srv/net/tl/udp/Makefile
r8426912a r6610565b 34 34 35 35 SOURCES = \ 36 udp.c 36 udp.c \ 37 udp_module.c 37 38 38 39 include $(USPACE_PREFIX)/Makefile.common -
uspace/srv/net/tl/udp/udp.c
r8426912a r6610565b 35 35 * @see udp.h 36 36 */ 37 38 #include "udp.h" 39 #include "udp_header.h" 40 #include "udp_module.h" 37 41 38 42 #include <async.h> … … 65 69 #include <socket_core.h> 66 70 #include <tl_common.h> 67 #include <tl_remote.h> 68 #include <tl_skel.h> 69 70 #include "udp.h" 71 #include "udp_header.h" 71 #include <tl_local.h> 72 #include <tl_interface.h> 72 73 73 74 /** UDP module name. */ 74 #define NAME "udp"75 #define NAME "UDP protocol" 75 76 76 77 /** Default UDP checksum computing. */ … … 91 92 /** UDP global data. */ 92 93 udp_globals_t udp_globals; 94 95 /** Initializes the UDP module. 96 * 97 * @param[in] client_connection The client connection processing function. The 98 * module skeleton propagates its own one. 99 * @return EOK on success. 100 * @return ENOMEM if there is not enough memory left. 101 */ 102 int udp_initialize(async_client_conn_t client_connection) 103 { 104 measured_string_t names[] = { 105 { 106 (uint8_t *) "UDP_CHECKSUM_COMPUTING", 107 22 108 }, 109 { 110 (uint8_t *) "UDP_AUTOBINDING", 111 15 112 } 113 }; 114 measured_string_t *configuration; 115 size_t count = sizeof(names) / sizeof(measured_string_t); 116 uint8_t *data; 117 int rc; 118 119 fibril_rwlock_initialize(&udp_globals.lock); 120 fibril_rwlock_write_lock(&udp_globals.lock); 121 122 udp_globals.icmp_phone = icmp_connect_module(SERVICE_ICMP, 123 ICMP_CONNECT_TIMEOUT); 124 125 udp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_UDP, 126 SERVICE_UDP, client_connection); 127 if (udp_globals.ip_phone < 0) { 128 fibril_rwlock_write_unlock(&udp_globals.lock); 129 return udp_globals.ip_phone; 130 } 131 132 /* Read default packet dimensions */ 133 rc = ip_packet_size_req(udp_globals.ip_phone, -1, 134 &udp_globals.packet_dimension); 135 if (rc != EOK) { 136 fibril_rwlock_write_unlock(&udp_globals.lock); 137 return rc; 138 } 139 140 rc = socket_ports_initialize(&udp_globals.sockets); 141 if (rc != EOK) { 142 fibril_rwlock_write_unlock(&udp_globals.lock); 143 return rc; 144 } 145 146 rc = packet_dimensions_initialize(&udp_globals.dimensions); 147 if (rc != EOK) { 148 socket_ports_destroy(&udp_globals.sockets); 149 fibril_rwlock_write_unlock(&udp_globals.lock); 150 return rc; 151 } 152 153 udp_globals.packet_dimension.prefix += sizeof(udp_header_t); 154 udp_globals.packet_dimension.content -= sizeof(udp_header_t); 155 udp_globals.last_used_port = UDP_FREE_PORTS_START - 1; 156 157 udp_globals.checksum_computing = NET_DEFAULT_UDP_CHECKSUM_COMPUTING; 158 udp_globals.autobinding = NET_DEFAULT_UDP_AUTOBINDING; 159 160 /* Get configuration */ 161 configuration = &names[0]; 162 rc = net_get_conf_req(udp_globals.net_phone, &configuration, count, 163 &data); 164 if (rc != EOK) { 165 socket_ports_destroy(&udp_globals.sockets); 166 fibril_rwlock_write_unlock(&udp_globals.lock); 167 return rc; 168 } 169 170 if (configuration) { 171 if (configuration[0].value) 172 udp_globals.checksum_computing = 173 (configuration[0].value[0] == 'y'); 174 175 if (configuration[1].value) 176 udp_globals.autobinding = 177 (configuration[1].value[0] == 'y'); 178 179 net_free_settings(configuration, data); 180 } 181 182 fibril_rwlock_write_unlock(&udp_globals.lock); 183 return EOK; 184 } 93 185 94 186 /** Releases the packet and returns the result. … … 334 426 } 335 427 336 /** Process IPC messages from the IP module337 *338 * @param[in] iid Message identifier.339 * @param[in,out] icall Message parameters.340 *341 */342 static void udp_receiver(ipc_callid_t iid, ipc_call_t *icall)343 {344 packet_t *packet;345 int rc;346 347 while (true) {348 switch (IPC_GET_IMETHOD(*icall)) {349 case NET_TL_RECEIVED:350 rc = packet_translate_remote(udp_globals.net_phone, &packet,351 IPC_GET_PACKET(*icall));352 if (rc == EOK)353 rc = udp_received_msg(IPC_GET_DEVICE(*icall), packet,354 SERVICE_UDP, IPC_GET_ERROR(*icall));355 356 ipc_answer_0(iid, (sysarg_t) rc);357 break;358 default:359 ipc_answer_0(iid, (sysarg_t) ENOTSUP);360 }361 362 iid = async_get_call(icall);363 }364 }365 366 /** Initialize the UDP module.367 *368 * @param[in] net_phone Network module phone.369 *370 * @return EOK on success.371 * @return ENOMEM if there is not enough memory left.372 *373 */374 int tl_initialize(int net_phone)375 {376 measured_string_t names[] = {377 {378 (uint8_t *) "UDP_CHECKSUM_COMPUTING",379 22380 },381 {382 (uint8_t *) "UDP_AUTOBINDING",383 15384 }385 };386 measured_string_t *configuration;387 size_t count = sizeof(names) / sizeof(measured_string_t);388 uint8_t *data;389 390 fibril_rwlock_initialize(&udp_globals.lock);391 fibril_rwlock_write_lock(&udp_globals.lock);392 393 udp_globals.net_phone = net_phone;394 395 udp_globals.icmp_phone = icmp_connect_module(SERVICE_ICMP,396 ICMP_CONNECT_TIMEOUT);397 398 udp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_UDP,399 SERVICE_UDP, udp_receiver);400 if (udp_globals.ip_phone < 0) {401 fibril_rwlock_write_unlock(&udp_globals.lock);402 return udp_globals.ip_phone;403 }404 405 /* Read default packet dimensions */406 int rc = ip_packet_size_req(udp_globals.ip_phone, -1,407 &udp_globals.packet_dimension);408 if (rc != EOK) {409 fibril_rwlock_write_unlock(&udp_globals.lock);410 return rc;411 }412 413 rc = socket_ports_initialize(&udp_globals.sockets);414 if (rc != EOK) {415 fibril_rwlock_write_unlock(&udp_globals.lock);416 return rc;417 }418 419 rc = packet_dimensions_initialize(&udp_globals.dimensions);420 if (rc != EOK) {421 socket_ports_destroy(&udp_globals.sockets);422 fibril_rwlock_write_unlock(&udp_globals.lock);423 return rc;424 }425 426 udp_globals.packet_dimension.prefix += sizeof(udp_header_t);427 udp_globals.packet_dimension.content -= sizeof(udp_header_t);428 udp_globals.last_used_port = UDP_FREE_PORTS_START - 1;429 430 udp_globals.checksum_computing = NET_DEFAULT_UDP_CHECKSUM_COMPUTING;431 udp_globals.autobinding = NET_DEFAULT_UDP_AUTOBINDING;432 433 /* Get configuration */434 configuration = &names[0];435 rc = net_get_conf_req(udp_globals.net_phone, &configuration, count,436 &data);437 if (rc != EOK) {438 socket_ports_destroy(&udp_globals.sockets);439 fibril_rwlock_write_unlock(&udp_globals.lock);440 return rc;441 }442 443 if (configuration) {444 if (configuration[0].value)445 udp_globals.checksum_computing =446 (configuration[0].value[0] == 'y');447 448 if (configuration[1].value)449 udp_globals.autobinding =450 (configuration[1].value[0] == 'y');451 452 net_free_settings(configuration, data);453 }454 455 fibril_rwlock_write_unlock(&udp_globals.lock);456 return EOK;457 }458 459 428 /** Sends data from the socket to the remote address. 460 429 * … … 891 860 * @see IS_NET_UDP_MESSAGE() 892 861 */ 893 int tl_module_message(ipc_callid_t callid, ipc_call_t *call,862 int udp_message_standalone(ipc_callid_t callid, ipc_call_t *call, 894 863 ipc_call_t *answer, size_t *answer_count) 895 864 { 865 packet_t *packet; 866 int rc; 867 896 868 *answer_count = 0; 897 869 898 870 switch (IPC_GET_IMETHOD(*call)) { 871 case NET_TL_RECEIVED: 872 rc = packet_translate_remote(udp_globals.net_phone, &packet, 873 IPC_GET_PACKET(*call)); 874 if (rc != EOK) 875 return rc; 876 return udp_received_msg(IPC_GET_DEVICE(*call), packet, 877 SERVICE_UDP, IPC_GET_ERROR(*call)); 899 878 case IPC_M_CONNECT_TO_ME: 900 879 return udp_process_client_messages(callid, *call); … … 904 883 } 905 884 885 /** Default thread for new connections. 886 * 887 * @param[in] iid The initial message identifier. 888 * @param[in] icall The initial message call structure. 889 */ 890 static void tl_client_connection(ipc_callid_t iid, ipc_call_t * icall) 891 { 892 /* 893 * Accept the connection 894 * - Answer the first IPC_M_CONNECT_ME_TO call. 895 */ 896 ipc_answer_0(iid, EOK); 897 898 while (true) { 899 ipc_call_t answer; 900 size_t answer_count; 901 902 /* Clear the answer structure */ 903 refresh_answer(&answer, &answer_count); 904 905 /* Fetch the next message */ 906 ipc_call_t call; 907 ipc_callid_t callid = async_get_call(&call); 908 909 /* Process the message */ 910 int res = tl_module_message_standalone(callid, &call, &answer, 911 &answer_count); 912 913 /* 914 * End if told to either by the message or the processing 915 * result. 916 */ 917 if ((IPC_GET_IMETHOD(call) == IPC_M_PHONE_HUNGUP) || 918 (res == EHANGUP)) 919 return; 920 921 /* Answer the message */ 922 answer_call(callid, res, &answer, answer_count); 923 } 924 } 925 926 /** Starts the module. 927 * 928 * @return EOK on success. 929 * @return Other error codes as defined for each specific module 930 * start function. 931 */ 906 932 int main(int argc, char *argv[]) 907 933 { 934 int rc; 935 908 936 /* Start the module */ 909 return tl_module_start(SERVICE_UDP); 937 rc = tl_module_start_standalone(tl_client_connection); 938 return rc; 910 939 } 911 940
Note:
See TracChangeset
for help on using the changeset viewer.