Changes in / [6610565b:8426912a] in mainline
- Files:
-
- 14 added
- 27 deleted
- 51 edited
Legend:
- Unmodified
- Added
- Removed
-
boot/Makefile.common
r6610565b r8426912a 98 98 $(USPACE_PATH)/srv/fs/fat/fat \ 99 99 $(USPACE_PATH)/srv/taskmon/taskmon \ 100 $(USPACE_PATH)/srv/hw/netif/dp8390/dp8390 \ 101 $(USPACE_PATH)/srv/hw/bus/usb/hcd/virtual/vhcd \ 100 $(USPACE_PATH)/srv/hw/netif/ne2000/ne2000 \ 102 101 $(USPACE_PATH)/srv/net/netif/lo/lo \ 103 102 $(USPACE_PATH)/srv/net/nil/eth/eth \ … … 133 132 $(USPACE_PATH)/app/taskdump/taskdump \ 134 133 $(USPACE_PATH)/app/tester/tester \ 135 $(USPACE_PATH)/app/test_serial/test_serial \136 134 $(USPACE_PATH)/app/tetris/tetris \ 137 135 $(USPACE_PATH)/app/trace/trace \ 138 $(USPACE_PATH)/app/netstart/netstart \139 136 $(USPACE_PATH)/app/nettest1/nettest1 \ 140 137 $(USPACE_PATH)/app/nettest2/nettest2 \ -
kernel/arch/amd64/include/interrupt.h
r6610565b r8426912a 55 55 #define IRQ_PIC_SPUR 7 56 56 #define IRQ_MOUSE 12 57 #define IRQ_ DP8390 957 #define IRQ_NE2000 9 58 58 59 59 /* This one must have four least significant bits set to ones */ -
kernel/arch/amd64/src/amd64.c
r6610565b r8426912a 238 238 sysinfo_set_item_val(irqs_info, NULL, true); 239 239 240 sysinfo_set_item_val("netif. dp8390.inr", NULL, IRQ_DP8390);240 sysinfo_set_item_val("netif.ne2000.inr", NULL, IRQ_NE2000); 241 241 } 242 242 -
kernel/arch/ia32/include/interrupt.h
r6610565b r8426912a 55 55 #define IRQ_PIC_SPUR 7 56 56 #define IRQ_MOUSE 12 57 #define IRQ_ DP8390 557 #define IRQ_NE2000 5 58 58 59 59 /* This one must have four least significant bits set to ones */ -
kernel/arch/ia32/src/ia32.c
r6610565b r8426912a 196 196 sysinfo_set_item_val(irqs_info, NULL, true); 197 197 198 sysinfo_set_item_val("netif. dp8390.inr", NULL, IRQ_DP8390);198 sysinfo_set_item_val("netif.ne2000.inr", NULL, IRQ_NE2000); 199 199 } 200 200 -
kernel/arch/ia64/include/interrupt.h
r6610565b r8426912a 61 61 #define IRQ_KBD (0x01 + LEGACY_INTERRUPT_BASE) 62 62 #define IRQ_MOUSE (0x0c + LEGACY_INTERRUPT_BASE) 63 #define IRQ_ DP8390 (0x09 + LEGACY_INTERRUPT_BASE)63 #define IRQ_NE2000 (0x09 + LEGACY_INTERRUPT_BASE) 64 64 65 65 /** General Exception codes. */ -
kernel/arch/ia64/src/ia64.c
r6610565b r8426912a 222 222 #endif 223 223 224 sysinfo_set_item_val("netif. dp8390.inr", NULL, IRQ_DP8390);224 sysinfo_set_item_val("netif.ne2000.inr", NULL, IRQ_NE2000); 225 225 226 226 sysinfo_set_item_val("ia64_iospace", NULL, true); -
kernel/generic/include/ddi/ddi.h
r6610565b r8426912a 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);57 56 58 57 /* -
kernel/generic/include/syscall/syscall.h
r6610565b r8426912a 82 82 SYS_PHYSMEM_MAP, 83 83 SYS_IOSPACE_ENABLE, 84 SYS_INTERRUPT_ENABLE,85 84 86 85 SYS_SYSINFO_GET_TAG, -
kernel/generic/src/ddi/ddi.c
r6610565b r8426912a 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 0271 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 #endif287 return 0;288 }289 290 260 /** @} 291 261 */ -
kernel/generic/src/mm/slab.c
r6610565b r8426912a 806 806 } 807 807 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 */ 808 /** Go through all caches and reclaim what is possible */ 814 809 size_t slab_reclaim(unsigned int flags) 815 810 { 816 irq_spinlock_lock(&slab_cache_lock, false);811 irq_spinlock_lock(&slab_cache_lock, true); 817 812 818 813 size_t frames = 0; … … 824 819 } 825 820 826 irq_spinlock_unlock(&slab_cache_lock, false);821 irq_spinlock_unlock(&slab_cache_lock, true); 827 822 828 823 return frames; -
kernel/generic/src/syscall/syscall.c
r6610565b r8426912a 171 171 (syshandler_t) sys_physmem_map, 172 172 (syshandler_t) sys_iospace_enable, 173 (syshandler_t) sys_interrupt_enable,174 173 175 174 /* Sysinfo syscalls */ -
uspace/Makefile
r6610565b r8426912a 82 82 srv/hw/char/i8042 \ 83 83 srv/hw/char/s3c24xx_uart \ 84 srv/hw/netif/ dp8390 \84 srv/hw/netif/ne2000 \ 85 85 srv/net/netif/lo \ 86 86 srv/net/il/arp \ -
uspace/app/trace/syscalls.c
r6610565b r8426912a 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 },76 75 77 76 [SYS_SYSINFO_GET_TAG] = { "sysinfo_get_tag", 2, V_INTEGER }, -
uspace/doc/doxygroups.h
r6610565b r8426912a 43 43 44 44 /** 45 * @defgroup dp8390 Generic DP8390 network interface familyservice45 * @defgroup ne2000 NE2000 network interface service 46 46 * @ingroup netif 47 47 */ 48 49 /**50 * @defgroup ne2k NE2000 network interface family51 * @ingroup dp839052 */53 48 54 49 /** -
uspace/drv/ns8250/ns8250.c
r6610565b r8426912a 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;439 433 440 434 /* Enable interrupt on the serial port. */ -
uspace/lib/c/generic/ddi.c
r6610565b r8426912a 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 120 98 /** Enable PIO for specified I/O range. 121 99 * -
uspace/lib/c/generic/devman.c
r6610565b r8426912a 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 else84 } else { 85 85 devman_phone_client = async_connect_me_to(PHONE_NS, 86 86 SERVICE_DEVMAN, DEVMAN_CLIENT, 0); 87 } 87 88 88 89 fibril_mutex_unlock(&devman_phone_mutex); -
uspace/lib/c/include/ddi.h
r6610565b r8426912a 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);46 44 47 45 #endif -
uspace/lib/c/include/ipc/il.h
r6610565b r8426912a 33 33 /** @file 34 34 * Internetwork layer modules messages. 35 * @see il_ interface.h35 * @see il_remote.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,51 47 /** Device state changed message. 52 48 * @see il_device_state_msg() 53 49 */ 54 NET_IL_DEVICE_STATE, 50 NET_IL_DEVICE_STATE = NET_IL_FIRST, 51 55 52 /** Device MTU changed message. 56 53 * @see il_mtu_changed_msg() 57 54 */ 58 55 NET_IL_MTU_CHANGED, 59 /** Packet size message. 60 * @see il_packet_size_req() 61 */ 62 NET_IL_PACKET_SPACE, 56 63 57 /** Packet received message. 64 58 * @see il_received_msg() 65 59 */ 66 NET_IL_RECEIVED, 67 /** Packet send message. 68 * @see il_send_msg() 69 */ 70 NET_IL_SEND 60 NET_IL_RECEIVED 71 61 } il_messages; 72 62 -
uspace/lib/c/include/ipc/ip.h
r6610565b r8426912a 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 49 54 /** Adds the routing entry. 50 55 * @see ip_add_route() 51 56 */ 52 NET_IP_ADD_ROUTE = NET_IP_FIRST,57 NET_IP_ADD_ROUTE, 53 58 54 59 /** Gets the actual route information. … … 65 70 * @see ip_set_default_gateway() 66 71 */ 67 NET_IP_SET_GATEWAY 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 68 83 } ip_messages; 69 84 -
uspace/lib/c/include/ipc/services.h
r6610565b r8426912a 54 54 SERVICE_NETWORKING, 55 55 SERVICE_LO, 56 SERVICE_ DP8390,56 SERVICE_NE2000, 57 57 SERVICE_ETHERNET, 58 58 SERVICE_NILDUMMY, -
uspace/lib/net/Makefile
r6610565b r8426912a 43 43 netif/netif_skel.c \ 44 44 nil/nil_remote.c \ 45 il/il_interface.c \ 45 nil/nil_skel.c \ 46 il/il_remote.c \ 47 il/il_skel.c \ 46 48 il/ip_remote.c \ 47 49 il/ip_client.c \ … … 50 52 tl/icmp_client.c \ 51 53 tl/socket_core.c \ 52 tl/tl_interface.c \ 53 tl/tl_common.c 54 tl/tl_common.c \ 55 tl/tl_remote.c \ 56 tl/tl_skel.c 54 57 55 58 include $(USPACE_PREFIX)/Makefile.common -
uspace/lib/net/generic/protocol_map.c
r6610565b r8426912a 50 50 switch (nil) { 51 51 case SERVICE_ETHERNET: 52 case SERVICE_ DP8390:52 case SERVICE_NE2000: 53 53 switch (il) { 54 54 case SERVICE_IP: … … 76 76 switch (nil) { 77 77 case SERVICE_ETHERNET: 78 case SERVICE_ DP8390:78 case SERVICE_NE2000: 79 79 switch (protocol) { 80 80 case ETH_P_IP: … … 139 139 switch (nil) { 140 140 case SERVICE_ETHERNET: 141 case SERVICE_ DP8390:141 case SERVICE_NE2000: 142 142 return HW_ETHER; 143 143 default: -
uspace/lib/net/il/ip_remote.c
r6610565b r8426912a 36 36 * 37 37 * @see ip_interface.h 38 * @see il_ interface.h38 * @see il_remote.h 39 39 * 40 40 */ … … 121 121 services_t service) 122 122 { 123 return generic_device_req_remote(ip_phone, NET_I L_DEVICE, device_id, 0,123 return generic_device_req_remote(ip_phone, NET_IP_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 L_PACKET_SPACE,190 return generic_packet_size_req_remote(ip_phone, NET_IP_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 L_SEND, device_id,230 return generic_send_msg_remote(ip_phone, NET_IP_SEND, device_id, 231 231 packet_get_id(packet), sender, error); 232 232 } -
uspace/lib/net/include/nil_remote.h
r6610565b r8426912a 37 37 #include <net/device.h> 38 38 #include <net/packet.h> 39 #include <generic.h> 39 40 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); 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); 42 65 43 66 #endif -
uspace/lib/net/netif/netif_skel.c
r6610565b r8426912a 33 33 /** @file 34 34 * Network interface module skeleton implementation. 35 * @see netif .h35 * @see netif_skel.h 36 36 */ 37 37 … … 52 52 #include <adt/measured_strings.h> 53 53 #include <net/device.h> 54 #include <nil_interface.h>55 54 #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 nil_device_state_msg(phone, device_id, result); 132 133 fibril_rwlock_write_unlock(&netif_globals.lock); 133 nil_device_state_msg(phone, device_id, result);134 134 return EOK; 135 135 } … … 166 166 if (result > NETIF_NULL) { 167 167 int phone = device->nil_phone; 168 nil_device_state_msg(phone, device_id, result); 168 169 fibril_rwlock_write_unlock(&netif_globals.lock); 169 nil_device_state_msg(phone, device_id, result);170 170 return EOK; 171 171 } -
uspace/lib/net/nil/nil_remote.c
r6610565b r8426912a 33 33 /** @file 34 34 * Network interface layer interface implementation for remote modules. 35 * @see nil_ interface.h35 * @see nil_remote.h 36 36 */ 37 37 38 38 #include <nil_remote.h> 39 #include <nil_interface.h>40 39 #include <generic.h> 41 40 #include <net/device.h> 42 41 #include <net/packet.h> 43 42 #include <packet_client.h> 44 45 43 #include <ipc/nil.h> 46 44 47 45 /** Notify the network interface layer about the device state change. 48 46 * 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. 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 * 55 55 */ 56 int nil_device_state_msg _remote(int nil_phone, device_id_t device_id, int state)56 int nil_device_state_msg(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 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. 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 * 74 76 */ 75 int nil_received_msg _remote(int nil_phone, device_id_t device_id,77 int nil_received_msg(int nil_phone, device_id_t device_id, 76 78 packet_t *packet, services_t target) 77 79 { -
uspace/lib/net/tl/tl_common.c
r6610565b r8426912a 42 42 #include <ip_remote.h> 43 43 #include <ip_interface.h> 44 #include <tl_ interface.h>44 #include <tl_remote.h> 45 45 46 46 #include <net/socket_codes.h> -
uspace/srv/net/cfg/ne2k
r6610565b r8426912a 3 3 NAME=ne2k 4 4 5 NETIF= dp83905 NETIF=ne2000 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. 24019 IP_NETMASK=255.255.255.0 20 20 IP_BROADCAST=10.0.2.255 21 21 IP_GATEWAY=10.0.2.2 -
uspace/srv/net/il/arp/Makefile
r6610565b r8426912a 34 34 35 35 SOURCES = \ 36 arp.c \ 37 arp_module.c 36 arp.c 38 37 39 38 include $(USPACE_PREFIX)/Makefile.common -
uspace/srv/net/il/arp/arp.c
r6610565b r8426912a 36 36 */ 37 37 38 #include "arp.h"39 #include "arp_header.h"40 #include "arp_oc.h"41 #include "arp_module.h"42 43 38 #include <async.h> 44 39 #include <malloc.h> 45 40 #include <mem.h> 46 41 #include <fibril_synch.h> 42 #include <assert.h> 47 43 #include <stdio.h> 48 44 #include <str.h> … … 54 50 #include <ipc/arp.h> 55 51 #include <ipc/il.h> 52 #include <ipc/nil.h> 56 53 #include <byteorder.h> 57 54 #include <errno.h> 58 59 55 #include <net/modules.h> 60 56 #include <net/device.h> 61 57 #include <net/packet.h> 62 63 #include <nil_interface.h> 58 #include <nil_remote.h> 64 59 #include <protocol_map.h> 65 60 #include <packet_client.h> 66 61 #include <packet_remote.h> 67 #include <il_ interface.h>68 #include <il_ local.h>69 62 #include <il_remote.h> 63 #include <il_skel.h> 64 #include "arp.h" 70 65 71 66 /** ARP module name. */ … … 73 68 74 69 /** Number of microseconds to wait for an ARP reply. */ 75 #define ARP_TRANS_WAIT 1000000 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)); 76 109 77 110 /** ARP global data. */ … … 88 121 trans->hw_addr = NULL; 89 122 } 123 90 124 fibril_condvar_broadcast(&trans->cv); 91 125 } … … 94 128 { 95 129 int count; 96 arp_trans_t *trans; 97 130 98 131 for (count = arp_addr_count(addresses) - 1; count >= 0; count--) { 99 trans = arp_addr_items_get_index(&addresses->values, count); 132 arp_trans_t *trans = arp_addr_items_get_index(&addresses->values, 133 count); 100 134 if (trans) 101 135 arp_clear_trans(trans); … … 103 137 } 104 138 105 106 /** Clears the device specific data. 107 * 108 * @param[in] device The device specific data. 139 /** Clear the device specific data. 140 * 141 * @param[in] device Device specific data. 109 142 */ 110 143 static void arp_clear_device(arp_device_t *device) 111 144 { 112 145 int count; 113 arp_proto_t *proto; 114 146 115 147 for (count = arp_protos_count(&device->protos) - 1; count >= 0; 116 148 count--) { 117 proto = arp_protos_get_index(&device->protos, count); 149 arp_proto_t *proto = arp_protos_get_index(&device->protos, 150 count); 151 118 152 if (proto) { 119 153 if (proto->addr) 120 154 free(proto->addr); 155 121 156 if (proto->addr_data) 122 157 free(proto->addr_data); 158 123 159 arp_clear_addr(&proto->addresses); 124 160 arp_addr_destroy(&proto->addresses); 125 161 } 126 162 } 163 127 164 arp_protos_clear(&device->protos); 128 165 } … … 131 168 { 132 169 int count; 133 arp_device_t *device; 134 170 135 171 fibril_mutex_lock(&arp_globals.lock); 136 172 for (count = arp_cache_count(&arp_globals.cache) - 1; count >= 0; 137 173 count--) { 138 device = arp_cache_get_index(&arp_globals.cache, count); 174 arp_device_t *device = arp_cache_get_index(&arp_globals.cache, 175 count); 176 139 177 if (device) { 140 178 arp_clear_device(device); 141 179 if (device->addr_data) 142 180 free(device->addr_data); 181 143 182 if (device->broadcast_data) 144 183 free(device->broadcast_data); 145 184 } 146 185 } 186 147 187 arp_cache_clear(&arp_globals.cache); 148 188 fibril_mutex_unlock(&arp_globals.lock); 149 printf("Cache cleaned\n");189 150 190 return EOK; 151 191 } … … 154 194 services_t protocol, measured_string_t *address) 155 195 { 156 arp_device_t *device;157 arp_proto_t *proto;158 arp_trans_t *trans;159 160 196 fibril_mutex_lock(&arp_globals.lock); 161 device = arp_cache_find(&arp_globals.cache, device_id); 197 198 arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id); 162 199 if (!device) { 163 200 fibril_mutex_unlock(&arp_globals.lock); 164 201 return ENOENT; 165 202 } 166 proto = arp_protos_find(&device->protos, protocol); 203 204 arp_proto_t *proto = arp_protos_find(&device->protos, protocol); 167 205 if (!proto) { 168 206 fibril_mutex_unlock(&arp_globals.lock); 169 207 return ENOENT; 170 208 } 171 trans = arp_addr_find(&proto->addresses, address->value, address->length); 209 210 arp_trans_t *trans = arp_addr_find(&proto->addresses, address->value, 211 address->length); 172 212 if (trans) 173 213 arp_clear_trans(trans); 214 174 215 arp_addr_exclude(&proto->addresses, address->value, address->length); 216 175 217 fibril_mutex_unlock(&arp_globals.lock); 176 218 return EOK; 177 219 } 178 220 179 180 221 static int arp_clear_device_req(int arp_phone, device_id_t device_id) 181 222 { 182 arp_device_t *device;183 184 223 fibril_mutex_lock(&arp_globals.lock); 185 device = arp_cache_find(&arp_globals.cache, device_id); 224 225 arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id); 186 226 if (!device) { 187 227 fibril_mutex_unlock(&arp_globals.lock); 188 228 return ENOENT; 189 229 } 230 190 231 arp_clear_device(device); 191 printf("Device %d cleared\n", device_id);232 192 233 fibril_mutex_unlock(&arp_globals.lock); 193 234 return EOK; 194 235 } 195 236 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. 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 * 205 248 */ 206 249 static int arp_proto_create(arp_proto_t **proto, services_t service, 207 250 measured_string_t *address) 208 251 { 209 int rc;210 211 252 *proto = (arp_proto_t *) malloc(sizeof(arp_proto_t)); 212 253 if (!*proto) … … 217 258 (*proto)->addr_data = address->value; 218 259 219 rc = arp_addr_initialize(&(*proto)->addresses);260 int rc = arp_addr_initialize(&(*proto)->addresses); 220 261 if (rc != EOK) { 221 262 free(*proto); … … 226 267 } 227 268 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; 269 /** Process the received ARP packet. 270 * 271 * Update the source hardware address if the source entry exists or the packet 272 * is targeted to my protocol address. 273 * 274 * Respond to the ARP request if the packet is the ARP request and is 275 * targeted to my address. 276 * 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 * 291 */ 292 static int arp_receive_message(device_id_t device_id, packet_t *packet) 293 { 251 294 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 430 * is targeted to my protocol address. 431 * Responses to the ARP request if the packet is the ARP request and is 432 * targeted to my address. 433 * 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. 446 */ 447 static int arp_receive_message(device_id_t device_id, packet_t *packet) 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; 458 int rc; 459 460 length = packet_get_data_length(packet); 295 296 size_t length = packet_get_data_length(packet); 461 297 if (length <= sizeof(arp_header_t)) 462 298 return EINVAL; 463 464 device = arp_cache_find(&arp_globals.cache, device_id);299 300 arp_device_t *device = arp_cache_find(&arp_globals.cache, device_id); 465 301 if (!device) 466 302 return ENOENT; 467 468 header = (arp_header_t *) packet_get_data(packet);303 304 arp_header_t *header = (arp_header_t *) packet_get_data(packet); 469 305 if ((ntohs(header->hardware) != device->hardware) || 470 306 (length < sizeof(arp_header_t) + header->hardware_length * 2U + … … 472 308 return EINVAL; 473 309 } 474 475 proto = arp_protos_find(&device->protos,310 311 arp_proto_t *proto = arp_protos_find(&device->protos, 476 312 protocol_unmap(device->service, ntohs(header->protocol))); 477 313 if (!proto) 478 314 return ENOENT; 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, 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, 485 322 header->protocol_length); 486 /* Exists? */ 487 if (trans && trans->hw_addr) { 323 324 if ((trans) && (trans->hw_addr)) { 325 /* Translation exists */ 488 326 if (trans->hw_addr->length != header->hardware_length) 489 327 return EINVAL; 328 490 329 memcpy(trans->hw_addr->value, src_hw, trans->hw_addr->length); 491 330 } 331 492 332 /* Is my protocol address? */ 493 333 if (proto->addr->length != header->protocol_length) … … 495 335 496 336 if (!bcmp(proto->addr->value, des_proto, proto->addr->length)) { 497 /* Not already updated? */498 337 if (!trans) { 338 /* Update the translation */ 499 339 trans = (arp_trans_t *) malloc(sizeof(arp_trans_t)); 500 340 if (!trans) 501 341 return ENOMEM; 342 502 343 trans->hw_addr = NULL; 503 344 fibril_condvar_initialize(&trans->cv); … … 509 350 } 510 351 } 352 511 353 if (!trans->hw_addr) { 512 354 trans->hw_addr = measured_string_create_bulk(src_hw, … … 518 360 fibril_condvar_broadcast(&trans->cv); 519 361 } 362 520 363 if (ntohs(header->operation) == ARPOP_REQUEST) { 521 364 header->operation = htons(ARPOP_REPLY); … … 538 381 } 539 382 } 540 383 541 384 return EOK; 542 385 } 543 386 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; 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); 403 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 { 566 423 packet_t *packet; 567 arp_header_t *header;568 bool retry = false;569 424 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) 577 return ENOENT; 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) 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) 594 530 return ENOENT; 595 retry = true; 596 goto restart; 597 } 598 if (retry) 599 return EAGAIN; 600 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 { 601 645 /* ARP packet content size = header + (address + translation) * 2 */ 602 length = 8 + 2 * (proto->addr->length + device->addr->length);646 size_t length = 8 + 2 * (proto->addr->length + device->addr->length); 603 647 if (length > device->packet_dimension.content) 604 648 return ELIMIT; 605 606 packet = packet_get_4_remote(arp_globals.net_phone,649 650 packet_t *packet = packet_get_4_remote(arp_globals.net_phone, 607 651 device->packet_dimension.addr_len, device->packet_dimension.prefix, 608 652 length, device->packet_dimension.suffix); 609 653 if (!packet) 610 654 return ENOMEM; 611 612 header = (arp_header_t *) packet_suffix(packet, length);655 656 arp_header_t *header = (arp_header_t *) packet_suffix(packet, length); 613 657 if (!header) { 614 658 pq_release_remote(arp_globals.net_phone, packet_get_id(packet)); 615 659 return ENOMEM; 616 660 } 617 661 618 662 header->hardware = htons(device->hardware); 619 663 header->hardware_length = (uint8_t) device->addr->length; … … 621 665 header->protocol_length = (uint8_t) proto->addr->length; 622 666 header->operation = htons(ARPOP_REQUEST); 667 623 668 length = sizeof(arp_header_t); 669 624 670 memcpy(((uint8_t *) header) + length, device->addr->value, 625 671 device->addr->length); … … 631 677 length += device->addr->length; 632 678 memcpy(((uint8_t *) header) + length, target->value, target->length); 633 634 rc = packet_set_addr(packet, (uint8_t *) device->addr->value,679 680 int rc = packet_set_addr(packet, (uint8_t *) device->addr->value, 635 681 (uint8_t *) device->broadcast_addr->value, device->addr->length); 636 682 if (rc != EOK) { … … 638 684 return rc; 639 685 } 640 686 641 687 nil_send_msg(device->phone, device_id, packet, SERVICE_ARP); 642 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 643 787 trans = (arp_trans_t *) malloc(sizeof(arp_trans_t)); 644 788 if (!trans) 645 789 return ENOMEM; 790 646 791 trans->hw_addr = NULL; 647 792 fibril_condvar_initialize(&trans->cv); 793 648 794 rc = arp_addr_add(&proto->addresses, target->value, target->length, 649 795 trans); … … 655 801 rc = fibril_condvar_wait_timeout(&trans->cv, &arp_globals.lock, 656 802 ARP_TRANS_WAIT); 657 if (rc == ETIMEOUT) 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); 658 811 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 the 817 * condition variable and someone else might have e.g. removed the 818 * translation before we managed to lock arp_globals.lock again. 819 */ 820 659 821 retry = true; 660 822 goto restart; 661 823 } 662 824 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. 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. 673 834 * 674 835 * @see arp_interface.h 675 836 * @see IS_NET_ARP_MESSAGE() 676 * /677 int 678 arp_message_standalone(ipc_callid_t callid, ipc_call_t *call,679 ipc_call_t *answer, size_t *answer_count)837 * 838 */ 839 int il_module_message(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer, 840 size_t *count) 680 841 { 681 842 measured_string_t *address; 682 843 measured_string_t *translation; 683 844 uint8_t *data; 684 packet_t *packet;685 packet_t *next;686 845 int rc; 687 846 688 * answer_count = 0;847 *count = 0; 689 848 switch (IPC_GET_IMETHOD(*call)) { 690 849 case IPC_M_PHONE_HUNGUP: … … 702 861 free(data); 703 862 } 863 704 864 return rc; 705 865 … … 714 874 free(address); 715 875 free(data); 876 716 877 if (rc != EOK) { 717 878 fibril_mutex_unlock(&arp_globals.lock); 718 879 return rc; 719 880 } 881 720 882 if (!translation) { 721 883 fibril_mutex_unlock(&arp_globals.lock); 722 884 return ENOENT; 723 885 } 886 724 887 rc = measured_strings_reply(translation, 1); 725 888 fibril_mutex_unlock(&arp_globals.lock); 726 889 return rc; 727 890 728 891 case NET_ARP_CLEAR_DEVICE: 729 892 return arp_clear_device_req(0, IPC_GET_DEVICE(*call)); 730 893 731 894 case NET_ARP_CLEAR_ADDRESS: 732 895 rc = measured_strings_receive(&address, &data, 1); … … 742 905 case NET_ARP_CLEAN_CACHE: 743 906 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));773 907 } 774 908 … … 776 910 } 777 911 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 connection787 * - 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 processing808 * 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 module823 * start function.824 */825 912 int main(int argc, char *argv[]) 826 913 { 827 int rc;828 829 914 /* Start the module */ 830 rc = il_module_start_standalone(il_client_connection); 831 return rc; 915 return il_module_start(SERVICE_ARP); 832 916 } 833 917 834 918 /** @} 835 919 */ 836 -
uspace/srv/net/il/arp/arp.h
r6610565b r8426912a 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 133 127 /** Networking module phone. */ 134 128 int net_phone; -
uspace/srv/net/il/ip/Makefile
r6610565b r8426912a 34 34 35 35 SOURCES = \ 36 ip.c \ 37 ip_module.c 36 ip.c 38 37 39 38 include $(USPACE_PREFIX)/Makefile.common -
uspace/srv/net/il/ip/ip.c
r6610565b r8426912a 35 35 * @see arp.h 36 36 */ 37 38 #include "ip.h"39 #include "ip_module.h"40 37 41 38 #include <async.h> … … 52 49 #include <sys/types.h> 53 50 #include <byteorder.h> 51 #include "ip.h" 54 52 55 53 #include <adt/measured_strings.h> … … 70 68 #include <icmp_client.h> 71 69 #include <icmp_interface.h> 72 #include <il_interface.h>73 70 #include <ip_client.h> 74 71 #include <ip_interface.h> 75 72 #include <ip_header.h> 76 73 #include <net_interface.h> 77 #include <nil_ interface.h>78 #include <tl_ interface.h>74 #include <nil_remote.h> 75 #include <tl_remote.h> 79 76 #include <packet_remote.h> 80 #include <il_local.h> 77 #include <il_remote.h> 78 #include <il_skel.h> 81 79 82 80 /** IP module name. */ … … 122 120 INT_MAP_IMPLEMENT(ip_protos, ip_proto_t); 123 121 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 /** 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 246 int il_initialize(int net_phone) 247 { 257 248 fibril_rwlock_initialize(&ip_globals.lock); 258 249 fibril_rwlock_write_lock(&ip_globals.lock); 259 250 fibril_rwlock_initialize(&ip_globals.protos_lock); 260 251 fibril_rwlock_initialize(&ip_globals.netifs_lock); 252 253 ip_globals.net_phone = net_phone; 261 254 ip_globals.packet_counter = 0; 262 255 ip_globals.gateway.address.s_addr = 0; … … 264 257 ip_globals.gateway.gateway.s_addr = 0; 265 258 ip_globals.gateway.netif = NULL; 266 ip_globals.client_connection = client_connection; 267 268 rc = ip_netifs_initialize(&ip_globals.netifs); 259 260 int rc = ip_netifs_initialize(&ip_globals.netifs); 269 261 if (rc != EOK) 270 262 goto out; … … 431 423 ip_netif->phone = nil_bind_service(ip_netif->service, 432 424 (sysarg_t) ip_netif->device_id, SERVICE_IP, 433 ip_ globals.client_connection);425 ip_receiver); 434 426 if (ip_netif->phone < 0) { 435 427 printf("Failed to contact the nil service %d\n", … … 487 479 } 488 480 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 { 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; 502 503 fibril_rwlock_write_lock(&ip_globals.netifs_lock); 504 505 rc = ip_netif_initialize(ip_netif); 506 if (rc != EOK) { 507 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); 543 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 544 545 printf("%s: Broadcast (%s)\n", NAME, address); 546 547 return EOK; 548 } 549 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) 565 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; 498 588 ip_netif_t *netif; 499 589 500 fibril_rwlock_write_lock(&ip_globals.netifs_lock); 501 netif = ip_netifs_find(&ip_globals.netifs, device_id); 502 if (!netif) { 503 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 504 return ENOENT; 505 } 506 netif->packet_dimension.content = mtu; 507 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 508 509 printf("%s: Device %d changed MTU to %zu\n", NAME, device_id, mtu); 510 511 return EOK; 512 } 513 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) 556 return NULL; 557 memcpy(middle, last, IP_HEADER_LENGTH(last)); 558 middle->flags |= IPFLAG_MORE_FRAGMENTS; 559 return middle; 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; 560 617 } 561 618 … … 626 683 * function. 627 684 */ 628 static int 629 ip_prepare_packet(in_addr_t *source, in_addr_t dest, packet_t *packet, 630 measured_string_t *destination) 685 static int ip_prepare_packet(in_addr_t *source, in_addr_t dest, 686 packet_t *packet, measured_string_t *destination) 631 687 { 632 688 size_t length; … … 757 813 * function. 758 814 */ 759 static int 760 ip_fragment_packet_data(packet_t *packet, packet_t *new_packet, 815 static int ip_fragment_packet_data(packet_t *packet, packet_t *new_packet, 761 816 ip_header_t *header, ip_header_t *new_header, size_t length, 762 817 const struct sockaddr *src, const struct sockaddr *dest, socklen_t addrlen) … … 792 847 793 848 return pq_insert_after(packet, new_packet); 849 } 850 851 /** Prefixes a middle fragment header based on the last fragment header to the 852 * 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; 794 870 } 795 871 … … 996 1072 * function. 997 1073 */ 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) 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) 1001 1076 { 1002 1077 measured_string_t destination; … … 1061 1136 } 1062 1137 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) 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) 1254 1140 { 1255 1141 int addrlen; … … 1355 1241 } 1356 1242 1243 /** Updates the device state. 1244 * 1245 * @param[in] device_id The device identifier. 1246 * @param[in] state The new state value. 1247 * @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) 1251 { 1252 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); 1265 1266 return EOK; 1267 } 1268 1269 /** Returns the packet destination address from the IP header. 1270 * 1271 * @param[in] header The packet IP header to be read. 1272 * @return The packet destination address. 1273 */ 1274 static in_addr_t ip_get_destination(ip_header_t *header) 1275 { 1276 in_addr_t destination; 1277 1278 // TODO search set ipopt route? 1279 destination.s_addr = header->destination_address; 1280 return destination; 1281 } 1282 1283 /** Delivers the packet to the local host. 1284 * 1285 * The packet is either passed to another module or released on error. 1286 * The ICMP_PROT_UNREACH error notification may be sent if the protocol is not 1287 * found. 1288 * 1289 * @param[in] device_id The source device identifier. 1290 * @param[in] packet The packet to be delivered. 1291 * @param[in] header The first packet IP header. May be NULL. 1292 * @param[in] error The packet error service. 1293 * @return EOK on success. 1294 * @return ENOTSUP if the packet is a fragment. 1295 * @return EAFNOSUPPORT if the address family is not supported. 1296 * @return ENOENT if the target protocol is not found. 1297 * @return Other error codes as defined for the packet_set_addr() 1298 * function. 1299 * @return Other error codes as defined for the packet_trim() 1300 * function. 1301 * @return Other error codes as defined for the protocol specific 1302 * tl_received_msg() function. 1303 */ 1304 static int ip_deliver_local(device_id_t device_id, packet_t *packet, 1305 ip_header_t *header, services_t error) 1306 { 1307 ip_proto_t *proto; 1308 int phone; 1309 services_t service; 1310 tl_received_msg_t received_msg; 1311 struct sockaddr *src; 1312 struct sockaddr *dest; 1313 struct sockaddr_in src_in; 1314 struct sockaddr_in dest_in; 1315 socklen_t addrlen; 1316 int rc; 1317 1318 if ((header->flags & IPFLAG_MORE_FRAGMENTS) || 1319 IP_FRAGMENT_OFFSET(header)) { 1320 // TODO fragmented 1321 return ENOTSUP; 1322 } 1323 1324 switch (header->version) { 1325 case IPVERSION: 1326 addrlen = sizeof(src_in); 1327 bzero(&src_in, addrlen); 1328 src_in.sin_family = AF_INET; 1329 memcpy(&dest_in, &src_in, addrlen); 1330 memcpy(&src_in.sin_addr.s_addr, &header->source_address, 1331 sizeof(header->source_address)); 1332 memcpy(&dest_in.sin_addr.s_addr, &header->destination_address, 1333 sizeof(header->destination_address)); 1334 src = (struct sockaddr *) &src_in; 1335 dest = (struct sockaddr *) &dest_in; 1336 break; 1337 1338 default: 1339 return ip_release_and_return(packet, EAFNOSUPPORT); 1340 } 1341 1342 rc = packet_set_addr(packet, (uint8_t *) src, (uint8_t *) dest, 1343 addrlen); 1344 if (rc != EOK) 1345 return ip_release_and_return(packet, rc); 1346 1347 // trim padding if present 1348 if (!error && 1349 (IP_TOTAL_LENGTH(header) < packet_get_data_length(packet))) { 1350 rc = packet_trim(packet, 0, 1351 packet_get_data_length(packet) - IP_TOTAL_LENGTH(header)); 1352 if (rc != EOK) 1353 return ip_release_and_return(packet, rc); 1354 } 1355 1356 fibril_rwlock_read_lock(&ip_globals.protos_lock); 1357 1358 proto = ip_protos_find(&ip_globals.protos, header->protocol); 1359 if (!proto) { 1360 fibril_rwlock_read_unlock(&ip_globals.protos_lock); 1361 phone = ip_prepare_icmp_and_get_phone(error, packet, header); 1362 if (phone >= 0) { 1363 // unreachable ICMP 1364 icmp_destination_unreachable_msg(phone, 1365 ICMP_PROT_UNREACH, 0, packet); 1366 } 1367 return ENOENT; 1368 } 1369 1370 if (proto->received_msg) { 1371 service = proto->service; 1372 received_msg = proto->received_msg; 1373 fibril_rwlock_read_unlock(&ip_globals.protos_lock); 1374 rc = received_msg(device_id, packet, service, error); 1375 } else { 1376 rc = tl_received_msg(proto->phone, device_id, packet, 1377 proto->service, error); 1378 fibril_rwlock_read_unlock(&ip_globals.protos_lock); 1379 } 1380 1381 return rc; 1382 } 1383 1384 /** Processes the received packet. 1385 * 1386 * The packet is either passed to another module or released on error. 1387 * 1388 * The ICMP_PARAM_POINTER error notification may be sent if the checksum is 1389 * invalid. 1390 * The ICMP_EXC_TTL error notification may be sent if the TTL is less than two. 1391 * The ICMP_HOST_UNREACH error notification may be sent if no route was found. 1392 * The ICMP_HOST_UNREACH error notification may be sent if the packet is for 1393 * another host and the routing is disabled. 1394 * 1395 * @param[in] device_id The source device identifier. 1396 * @param[in] packet The received packet to be processed. 1397 * @return EOK on success. 1398 * @return EINVAL if the TTL is less than two. 1399 * @return EINVAL if the checksum is invalid. 1400 * @return EAFNOSUPPORT if the address family is not supported. 1401 * @return ENOENT if no route was found. 1402 * @return ENOENT if the packet is for another host and the routing 1403 * is disabled. 1404 */ 1405 static int ip_process_packet(device_id_t device_id, packet_t *packet) 1406 { 1407 ip_header_t *header; 1408 in_addr_t dest; 1409 ip_route_t *route; 1410 int phone; 1411 struct sockaddr *addr; 1412 struct sockaddr_in addr_in; 1413 socklen_t addrlen; 1414 int rc; 1415 1416 header = (ip_header_t *) packet_get_data(packet); 1417 if (!header) 1418 return ip_release_and_return(packet, ENOMEM); 1419 1420 // checksum 1421 if ((header->header_checksum) && 1422 (IP_HEADER_CHECKSUM(header) != IP_CHECKSUM_ZERO)) { 1423 phone = ip_prepare_icmp_and_get_phone(0, packet, header); 1424 if (phone >= 0) { 1425 // checksum error ICMP 1426 icmp_parameter_problem_msg(phone, ICMP_PARAM_POINTER, 1427 ((size_t) ((void *) &header->header_checksum)) - 1428 ((size_t) ((void *) header)), packet); 1429 } 1430 return EINVAL; 1431 } 1432 1433 if (header->ttl <= 1) { 1434 phone = ip_prepare_icmp_and_get_phone(0, packet, header); 1435 if (phone >= 0) { 1436 // ttl exceeded ICMP 1437 icmp_time_exceeded_msg(phone, ICMP_EXC_TTL, packet); 1438 } 1439 return EINVAL; 1440 } 1441 1442 // process ipopt and get destination 1443 dest = ip_get_destination(header); 1444 1445 // set the addrination address 1446 switch (header->version) { 1447 case IPVERSION: 1448 addrlen = sizeof(addr_in); 1449 bzero(&addr_in, addrlen); 1450 addr_in.sin_family = AF_INET; 1451 memcpy(&addr_in.sin_addr.s_addr, &dest, sizeof(dest)); 1452 addr = (struct sockaddr *) &addr_in; 1453 break; 1454 1455 default: 1456 return ip_release_and_return(packet, EAFNOSUPPORT); 1457 } 1458 1459 rc = packet_set_addr(packet, NULL, (uint8_t *) &addr, addrlen); 1460 if (rc != EOK) 1461 return rc; 1462 1463 route = ip_find_route(dest); 1464 if (!route) { 1465 phone = ip_prepare_icmp_and_get_phone(0, packet, header); 1466 if (phone >= 0) { 1467 // unreachable ICMP 1468 icmp_destination_unreachable_msg(phone, 1469 ICMP_HOST_UNREACH, 0, packet); 1470 } 1471 return ENOENT; 1472 } 1473 1474 if (route->address.s_addr == dest.s_addr) { 1475 // local delivery 1476 return ip_deliver_local(device_id, packet, header, 0); 1477 } 1478 1479 if (route->netif->routing) { 1480 header->ttl--; 1481 return ip_send_route(packet, route->netif, route, NULL, dest, 1482 0); 1483 } 1484 1485 phone = ip_prepare_icmp_and_get_phone(0, packet, header); 1486 if (phone >= 0) { 1487 // unreachable ICMP if no routing 1488 icmp_destination_unreachable_msg(phone, ICMP_HOST_UNREACH, 0, 1489 packet); 1490 } 1491 1492 return ENOENT; 1493 } 1494 1357 1495 /** Returns the device packet dimensions for sending. 1358 1496 * … … 1366 1504 * @return EOK on success. 1367 1505 */ 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) 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) 1371 1508 { 1372 1509 ip_netif_t *netif; … … 1418 1555 } 1419 1556 1420 /** Returns the packet destination address from the IP header. 1421 * 1422 * @param[in] header The packet IP header to be read. 1423 * @return The packet destination address. 1424 */ 1425 static in_addr_t ip_get_destination(ip_header_t *header) 1426 { 1427 in_addr_t destination; 1428 1429 // TODO search set ipopt route? 1430 destination.s_addr = header->destination_address; 1431 return destination; 1432 } 1433 1434 /** Delivers the packet to the local host. 1435 * 1436 * The packet is either passed to another module or released on error. 1437 * The ICMP_PROT_UNREACH error notification may be sent if the protocol is not 1438 * found. 1439 * 1440 * @param[in] device_id The source device identifier. 1441 * @param[in] packet The packet to be delivered. 1442 * @param[in] header The first packet IP header. May be NULL. 1443 * @param[in] error The packet error service. 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. 1444 1561 * @return EOK on success. 1445 * @return ENOTSUP if the packet is a fragment. 1446 * @return EAFNOSUPPORT if the address family is not supported. 1447 * @return ENOENT if the target protocol is not found. 1448 * @return Other error codes as defined for the packet_set_addr() 1449 * function. 1450 * @return Other error codes as defined for the packet_trim() 1451 * function. 1452 * @return Other error codes as defined for the protocol specific 1453 * tl_received_msg() function. 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 modules 1583 * 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 receive 1632 * 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 service 1640 * parameter is zero. 1641 * @return EINVAL if the phone parameter is not a positive number 1642 * and the tl_receive_msg is NULL. 1643 * @return ENOMEM if there is not enough memory left. 1454 1644 */ 1455 1645 static int 1456 ip_ deliver_local(device_id_t device_id, packet_t *packet, ip_header_t *header,1457 services_t error)1646 ip_register(int protocol, services_t service, int phone, 1647 tl_received_msg_t received_msg) 1458 1648 { 1459 1649 ip_proto_t *proto; 1460 int phone; 1461 services_t service; 1462 tl_received_msg_t received_msg; 1463 struct sockaddr *src; 1464 struct sockaddr *dest; 1465 struct sockaddr_in src_in; 1466 struct sockaddr_in dest_in; 1467 socklen_t addrlen; 1468 int rc; 1469 1470 if ((header->flags & IPFLAG_MORE_FRAGMENTS) || 1471 IP_FRAGMENT_OFFSET(header)) { 1472 // TODO fragmented 1473 return ENOTSUP; 1474 } 1475 1476 switch (header->version) { 1477 case IPVERSION: 1478 addrlen = sizeof(src_in); 1479 bzero(&src_in, addrlen); 1480 src_in.sin_family = AF_INET; 1481 memcpy(&dest_in, &src_in, addrlen); 1482 memcpy(&src_in.sin_addr.s_addr, &header->source_address, 1483 sizeof(header->source_address)); 1484 memcpy(&dest_in.sin_addr.s_addr, &header->destination_address, 1485 sizeof(header->destination_address)); 1486 src = (struct sockaddr *) &src_in; 1487 dest = (struct sockaddr *) &dest_in; 1488 break; 1489 1490 default: 1491 return ip_release_and_return(packet, EAFNOSUPPORT); 1492 } 1493 1494 rc = packet_set_addr(packet, (uint8_t *) src, (uint8_t *) dest, 1495 addrlen); 1496 if (rc != EOK) 1497 return ip_release_and_return(packet, rc); 1498 1499 // trim padding if present 1500 if (!error && 1501 (IP_TOTAL_LENGTH(header) < packet_get_data_length(packet))) { 1502 rc = packet_trim(packet, 0, 1503 packet_get_data_length(packet) - IP_TOTAL_LENGTH(header)); 1504 if (rc != EOK) 1505 return ip_release_and_return(packet, rc); 1506 } 1507 1508 fibril_rwlock_read_lock(&ip_globals.protos_lock); 1509 1510 proto = ip_protos_find(&ip_globals.protos, header->protocol); 1511 if (!proto) { 1512 fibril_rwlock_read_unlock(&ip_globals.protos_lock); 1513 phone = ip_prepare_icmp_and_get_phone(error, packet, header); 1514 if (phone >= 0) { 1515 // unreachable ICMP 1516 icmp_destination_unreachable_msg(phone, 1517 ICMP_PROT_UNREACH, 0, packet); 1518 } 1519 return ENOENT; 1520 } 1521 1522 if (proto->received_msg) { 1523 service = proto->service; 1524 received_msg = proto->received_msg; 1525 fibril_rwlock_read_unlock(&ip_globals.protos_lock); 1526 rc = received_msg(device_id, packet, service, error); 1527 } else { 1528 rc = tl_received_msg(proto->phone, device_id, packet, 1529 proto->service, error); 1530 fibril_rwlock_read_unlock(&ip_globals.protos_lock); 1531 } 1532 1533 return rc; 1534 } 1535 1536 /** Processes the received packet. 1537 * 1538 * The packet is either passed to another module or released on error. 1539 * 1540 * The ICMP_PARAM_POINTER error notification may be sent if the checksum is 1541 * invalid. 1542 * The ICMP_EXC_TTL error notification may be sent if the TTL is less than two. 1543 * The ICMP_HOST_UNREACH error notification may be sent if no route was found. 1544 * The ICMP_HOST_UNREACH error notification may be sent if the packet is for 1545 * another host and the routing is disabled. 1546 * 1547 * @param[in] device_id The source device identifier. 1548 * @param[in] packet The received packet to be processed. 1549 * @return EOK on success. 1550 * @return EINVAL if the TTL is less than two. 1551 * @return EINVAL if the checksum is invalid. 1552 * @return EAFNOSUPPORT if the address family is not supported. 1553 * @return ENOENT if no route was found. 1554 * @return ENOENT if the packet is for another host and the routing 1555 * is disabled. 1556 */ 1557 static int 1558 ip_process_packet(device_id_t device_id, packet_t *packet) 1559 { 1560 ip_header_t *header; 1561 in_addr_t dest; 1562 ip_route_t *route; 1563 int phone; 1564 struct sockaddr *addr; 1565 struct sockaddr_in addr_in; 1566 socklen_t addrlen; 1567 int rc; 1568 1569 header = (ip_header_t *) packet_get_data(packet); 1570 if (!header) 1571 return ip_release_and_return(packet, ENOMEM); 1572 1573 // checksum 1574 if ((header->header_checksum) && 1575 (IP_HEADER_CHECKSUM(header) != IP_CHECKSUM_ZERO)) { 1576 phone = ip_prepare_icmp_and_get_phone(0, packet, header); 1577 if (phone >= 0) { 1578 // checksum error ICMP 1579 icmp_parameter_problem_msg(phone, ICMP_PARAM_POINTER, 1580 ((size_t) ((void *) &header->header_checksum)) - 1581 ((size_t) ((void *) header)), packet); 1582 } 1650 int index; 1651 1652 if (!protocol || !service || ((phone < 0) && !received_msg)) 1583 1653 return EINVAL; 1584 } 1585 1586 if (header->ttl <= 1) { 1587 phone = ip_prepare_icmp_and_get_phone(0, packet, header); 1588 if (phone >= 0) { 1589 // ttl exceeded ICMP 1590 icmp_time_exceeded_msg(phone, ICMP_EXC_TTL, packet); 1591 } 1592 return EINVAL; 1593 } 1594 1595 // process ipopt and get destination 1596 dest = ip_get_destination(header); 1597 1598 // set the addrination address 1599 switch (header->version) { 1600 case IPVERSION: 1601 addrlen = sizeof(addr_in); 1602 bzero(&addr_in, addrlen); 1603 addr_in.sin_family = AF_INET; 1604 memcpy(&addr_in.sin_addr.s_addr, &dest, sizeof(dest)); 1605 addr = (struct sockaddr *) &addr_in; 1606 break; 1607 1608 default: 1609 return ip_release_and_return(packet, EAFNOSUPPORT); 1610 } 1611 1612 rc = packet_set_addr(packet, NULL, (uint8_t *) &addr, addrlen); 1613 if (rc != EOK) 1614 return rc; 1615 1616 route = ip_find_route(dest); 1617 if (!route) { 1618 phone = ip_prepare_icmp_and_get_phone(0, packet, header); 1619 if (phone >= 0) { 1620 // unreachable ICMP 1621 icmp_destination_unreachable_msg(phone, 1622 ICMP_HOST_UNREACH, 0, packet); 1623 } 1624 return ENOENT; 1625 } 1626 1627 if (route->address.s_addr == dest.s_addr) { 1628 // local delivery 1629 return ip_deliver_local(device_id, packet, header, 0); 1630 } 1631 1632 if (route->netif->routing) { 1633 header->ttl--; 1634 return ip_send_route(packet, route->netif, route, NULL, dest, 1635 0); 1636 } 1637 1638 phone = ip_prepare_icmp_and_get_phone(0, packet, header); 1639 if (phone >= 0) { 1640 // unreachable ICMP if no routing 1641 icmp_destination_unreachable_msg(phone, ICMP_HOST_UNREACH, 0, 1642 packet); 1643 } 1644 1645 return ENOENT; 1646 } 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 1647 1679 1648 1680 static int … … 1845 1877 } 1846 1878 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 IP1855 * packet.1856 * @return EINVAL if the received address lengths differs from the1857 * 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 in1860 * 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 1876 1879 /** Processes the IP message. 1877 1880 * … … 1885 1888 * 1886 1889 * @see ip_interface.h 1887 * @see il_ interface.h1890 * @see il_remote.h 1888 1891 * @see IS_NET_IP_MESSAGE() 1889 1892 */ 1890 int 1891 ip_message_standalone(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer, 1893 int il_module_message(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer, 1892 1894 size_t *answer_count) 1893 1895 { 1894 1896 packet_t *packet; 1895 1897 struct sockaddr *addr; 1898 void *header; 1899 size_t headerlen; 1896 1900 size_t addrlen; 1897 1901 size_t prefix; 1898 1902 size_t suffix; 1899 1903 size_t content; 1900 void *header;1901 size_t headerlen;1902 1904 device_id_t device_id; 1903 1905 int rc; … … 1912 1914 IPC_GET_PHONE(*call), NULL); 1913 1915 1914 case NET_I L_DEVICE:1916 case NET_IP_DEVICE: 1915 1917 return ip_device_req_local(0, IPC_GET_DEVICE(*call), 1916 1918 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);1936 1919 1937 1920 case NET_IP_RECEIVED_ERROR: … … 1975 1958 return rc; 1976 1959 1977 case NET_I L_PACKET_SPACE:1960 case NET_IP_PACKET_SPACE: 1978 1961 rc = ip_packet_size_message(IPC_GET_DEVICE(*call), &addrlen, 1979 1962 &prefix, &content, &suffix); … … 1988 1971 return EOK; 1989 1972 1990 case NET_IL_MTU_CHANGED: 1991 return ip_mtu_changed_message(IPC_GET_DEVICE(*call), 1992 IPC_GET_MTU(*call)); 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; 1978 1979 return ip_send_msg_local(0, IPC_GET_DEVICE(*call), packet, 0, 1980 IPC_GET_ERROR(*call)); 1993 1981 } 1994 1982 … … 1996 1984 } 1997 1985 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 connection2007 * - 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;2014 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 processing2028 * 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 */2045 1986 int main(int argc, char *argv[]) 2046 1987 { 2047 int rc;2048 2049 1988 /* Start the module */ 2050 rc = il_module_start_standalone(il_client_connection); 2051 return rc; 1989 return il_module_start(SERVICE_IP); 2052 1990 } 2053 1991 -
uspace/srv/net/il/ip/ip.h
r6610565b r8426912a 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;142 140 /** Default gateway. */ 143 141 ip_route_t gateway; -
uspace/srv/net/net/net.c
r6610565b r8426912a 45 45 #include <stdio.h> 46 46 #include <str.h> 47 #include <str_error.h> 47 48 48 49 #include <ipc/ipc.h> … … 51 52 #include <ipc/net_net.h> 52 53 #include <ipc/il.h> 54 #include <ipc/nil.h> 53 55 54 56 #include <net/modules.h> … … 62 64 63 65 #include <netif_remote.h> 64 #include <nil_ interface.h>66 #include <nil_remote.h> 65 67 #include <net_interface.h> 66 68 #include <ip_interface.h> … … 288 290 if (rc != EOK) 289 291 return rc; 290 rc = add_module(NULL, &net_globals.modules, (uint8_t *) DP8390_NAME,291 (uint8_t *) DP8390_FILENAME, SERVICE_DP8390, 0, connect_to_service);292 rc = add_module(NULL, &net_globals.modules, (uint8_t *) NE2000_NAME, 293 (uint8_t *) NE2000_FILENAME, SERVICE_NE2000, 0, connect_to_service); 292 294 if (rc != EOK) 293 295 return rc; … … 331 333 if (rc != EOK) 332 334 return rc; 333 334 335 335 336 rc = net_initialize(client_connection); … … 591 592 rc = start_device(netif); 592 593 if (rc != EOK) { 594 printf("%s: Error starting interface %s (%s)\n", NAME, 595 netif->name, str_error(rc)); 593 596 measured_strings_destroy(&netif->configuration); 594 597 netifs_exclude_index(&net_globals.netifs, index); 598 595 599 return rc; 596 600 } … … 709 713 int main(int argc, char *argv[]) 710 714 { 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; 715 return net_module_start(net_client_connection); 720 716 } 721 717 -
uspace/srv/net/net/net.h
r6610565b r8426912a 52 52 */ 53 53 54 #define DP8390_FILENAME "/srv/dp8390"55 #define DP8390_NAME "dp8390"54 #define NE2000_FILENAME "/srv/ne2000" 55 #define NE2000_NAME "ne2000" 56 56 57 57 #define ETHERNET_FILENAME "/srv/eth" -
uspace/srv/net/netif/lo/lo.c
r6610565b r8426912a 48 48 #include <packet_client.h> 49 49 #include <net/device.h> 50 #include <nil_interface.h>51 50 #include <netif_skel.h> 52 53 /** Default hardware address. */ 54 #define DEFAULT_ADDR 0 51 #include <nil_remote.h> 55 52 56 53 /** Default address length. */ … … 60 57 #define NAME "lo" 61 58 62 /** Network interface global data. */ 63 netif_globals_t netif_globals;59 static uint8_t default_addr[DEFAULT_ADDR_LEN] = 60 {0, 0, 0, 0, 0, 0}; 64 61 65 62 int netif_specific_message(ipc_callid_t callid, ipc_call_t *call, … … 74 71 return EBADMEM; 75 72 76 uint8_t *addr = (uint8_t *) malloc(DEFAULT_ADDR_LEN); 77 memset(addr, DEFAULT_ADDR, DEFAULT_ADDR_LEN); 78 79 address->value = addr; 73 address->value = default_addr; 80 74 address->length = DEFAULT_ADDR_LEN; 81 75 … … 85 79 int netif_get_device_stats(device_id_t device_id, device_stats_t *stats) 86 80 { 87 netif_device_t *device;88 int rc;89 90 81 if (!stats) 91 82 return EBADMEM; 92 93 rc = find_device(device_id, &device); 83 84 netif_device_t *device; 85 int rc = find_device(device_id, &device); 94 86 if (rc != EOK) 95 87 return rc; 96 88 97 89 memcpy(stats, (device_stats_t *) device->specific, 98 90 sizeof(device_stats_t)); 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) 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) 111 105 { 112 106 if (device->state != state) { 113 107 device->state = state; 114 108 115 printf("%s: State changed to %s\n", NAME, 116 (state == NETIF_ACTIVE) ? "active" : "stopped"); 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 } 117 120 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 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 { 136 137 if (netif_device_map_count(&netif_globals.device_map) > 0) 137 138 return EXDEV; 138 139 139 140 *device = (netif_device_t *) malloc(sizeof(netif_device_t)); 140 141 if (!*device) 141 142 return ENOMEM; 142 143 143 144 (*device)->specific = (device_stats_t *) malloc(sizeof(device_stats_t)); 144 145 if (!(*device)->specific) { … … 146 147 return ENOMEM; 147 148 } 148 149 149 150 null_device_stats((device_stats_t *) (*device)->specific); 150 151 (*device)->device_id = device_id; 151 152 (*device)->nil_phone = -1; 152 153 (*device)->state = NETIF_STOPPED; 153 in dex = netif_device_map_add(&netif_globals.device_map,154 int index = netif_device_map_add(&netif_globals.device_map, 154 155 (*device)->device_id, *device); 155 156 156 157 if (index < 0) { 157 158 free(*device); … … 167 168 { 168 169 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 /* Create a new device */ 175 176 netif_device_t *device; 176 int rc; 177 178 /* Create a new device */ 179 rc = create(device_id, &device); 177 int rc = lo_create(device_id, &device); 180 178 if (rc != EOK) 181 179 return rc; 182 183 /* Print the settings */ 180 184 181 printf("%s: Device created (id: %d)\n", NAME, device->device_id); 185 186 182 return EOK; 187 183 } … … 190 186 { 191 187 netif_device_t *device; 192 size_t length; 193 packet_t *next; 194 int phone; 195 int rc; 196 197 rc = find_device(device_id, &device); 188 int rc = find_device(device_id, &device); 198 189 if (rc != EOK) 199 190 return EOK; 200 191 201 192 if (device->state != NETIF_ACTIVE) { 202 193 netif_pq_release(packet_get_id(packet)); 203 194 return EFORWARD; 204 195 } 205 206 next = packet;196 197 packet_t *next = packet; 207 198 do { 208 199 ((device_stats_t *) device->specific)->send_packets++; 209 200 ((device_stats_t *) device->specific)->receive_packets++; 210 length = packet_get_data_length(next);201 size_t length = packet_get_data_length(next); 211 202 ((device_stats_t *) device->specific)->send_bytes += length; 212 203 ((device_stats_t *) device->specific)->receive_bytes += length; 213 204 next = pq_next(next); 214 } while (next);215 216 phone = device->nil_phone;205 } while (next); 206 207 int phone = device->nil_phone; 217 208 fibril_rwlock_write_unlock(&netif_globals.lock); 209 218 210 nil_received_msg(phone, device_id, packet, sender); 211 219 212 fibril_rwlock_write_lock(&netif_globals.lock); 220 221 213 return EOK; 222 214 } … … 224 216 int netif_start_message(netif_device_t *device) 225 217 { 226 return change_state_message(device, NETIF_ACTIVE); 218 change_state_message(device, NETIF_ACTIVE); 219 return device->state; 227 220 } 228 221 229 222 int netif_stop_message(netif_device_t *device) 230 223 { 231 return change_state_message(device, NETIF_STOPPED); 224 change_state_message(device, NETIF_STOPPED); 225 return device->state; 232 226 } 233 227 -
uspace/srv/net/nil/eth/Makefile
r6610565b r8426912a 42 42 43 43 SOURCES = \ 44 eth.c \ 45 eth_module.c 44 eth.c 46 45 47 46 include $(USPACE_PREFIX)/Makefile.common -
uspace/srv/net/nil/eth/eth.c
r6610565b r8426912a 45 45 46 46 #include <ipc/ipc.h> 47 #include <ipc/nil.h> 47 48 #include <ipc/net.h> 48 49 #include <ipc/services.h> … … 56 57 #include <netif_remote.h> 57 58 #include <net_interface.h> 58 #include <nil_interface.h> 59 #include <il_interface.h> 59 #include <il_remote.h> 60 60 #include <adt/measured_strings.h> 61 61 #include <packet_client.h> 62 62 #include <packet_remote.h> 63 #include <nil_ local.h>63 #include <nil_skel.h> 64 64 65 65 #include "eth.h" 66 #include "eth_header.h"67 66 68 67 /** The module name. */ … … 72 71 #define ETH_PREFIX \ 73 72 (sizeof(eth_header_t) + sizeof(eth_header_lsap_t) + \ 74 sizeof(eth_header_snap_t))73 sizeof(eth_header_snap_t)) 75 74 76 75 /** Reserved packet suffix length. */ 77 #define ETH_SUFFIX \ 78 sizeof(eth_fcs_t) 76 #define ETH_SUFFIX (sizeof(eth_fcs_t)) 79 77 80 78 /** Maximum packet content length. */ 81 #define ETH_MAX_CONTENT 1500u79 #define ETH_MAX_CONTENT 1500u 82 80 83 81 /** Minimum packet content length. */ 84 #define ETH_MIN_CONTENT 46u82 #define ETH_MIN_CONTENT 46u 85 83 86 84 /** Maximum tagged packet content length. */ 87 85 #define ETH_MAX_TAGGED_CONTENT(flags) \ 88 86 (ETH_MAX_CONTENT - \ 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))87 ((IS_8023_2_LSAP(flags) || IS_8023_2_SNAP(flags)) ? \ 88 sizeof(eth_header_lsap_t) : 0) - \ 89 (IS_8023_2_SNAP(flags) ? sizeof(eth_header_snap_t) : 0)) 92 90 93 91 /** Minimum tagged packet content length. */ 94 92 #define ETH_MIN_TAGGED_CONTENT(flags) \ 95 93 (ETH_MIN_CONTENT - \ 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))94 ((IS_8023_2_LSAP(flags) || IS_8023_2_SNAP(flags)) ? \ 95 sizeof(eth_header_lsap_t) : 0) - \ 96 (IS_8023_2_SNAP(flags) ? sizeof(eth_header_snap_t) : 0)) 99 97 100 98 /** Dummy flag shift value. */ 101 #define ETH_DUMMY_SHIFT 99 #define ETH_DUMMY_SHIFT 0 102 100 103 101 /** Mode flag shift value. */ 104 #define ETH_MODE_SHIFT 102 #define ETH_MODE_SHIFT 1 105 103 106 104 /** Dummy device flag. 107 105 * Preamble and FCS are mandatory part of the packets. 108 106 */ 109 #define ETH_DUMMY 107 #define ETH_DUMMY (1 << ETH_DUMMY_SHIFT) 110 108 111 109 /** Returns the dummy flag. 112 110 * @see ETH_DUMMY 113 111 */ 114 #define IS_DUMMY(flags) 112 #define IS_DUMMY(flags) ((flags) & ETH_DUMMY) 115 113 116 114 /** Device mode flags. … … 119 117 * @see ETH_8023_2_SNAP 120 118 */ 121 #define ETH_MODE_MASK 119 #define ETH_MODE_MASK (3 << ETH_MODE_SHIFT) 122 120 123 121 /** DIX Ethernet mode flag. */ 124 #define ETH_DIX 125 126 /** Return swhether the DIX Ethernet mode flag is set.127 * 128 * @param[in] flags The ethernet flags.122 #define ETH_DIX (1 << ETH_MODE_SHIFT) 123 124 /** Return whether the DIX Ethernet mode flag is set. 125 * 126 * @param[in] flags Ethernet flags. 129 127 * @see ETH_DIX 130 */ 131 #define IS_DIX(flags) (((flags) & ETH_MODE_MASK) == ETH_DIX) 128 * 129 */ 130 #define IS_DIX(flags) (((flags) & ETH_MODE_MASK) == ETH_DIX) 132 131 133 132 /** 802.3 + 802.2 + LSAP mode flag. */ 134 #define ETH_8023_2_LSAP 135 136 /** Return swhether the 802.3 + 802.2 + LSAP mode flag is set.137 * 138 * @param[in] flags The ethernet flags.133 #define ETH_8023_2_LSAP (2 << ETH_MODE_SHIFT) 134 135 /** Return whether the 802.3 + 802.2 + LSAP mode flag is set. 136 * 137 * @param[in] flags Ethernet flags. 139 138 * @see ETH_8023_2_LSAP 140 */ 141 #define IS_8023_2_LSAP(flags) (((flags) & ETH_MODE_MASK) == ETH_8023_2_LSAP) 139 * 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 swhether the 802.3 + 802.2 + LSAP + SNAP mode flag is set.147 * 148 * @param[in] flags The ethernet flags.144 #define ETH_8023_2_SNAP (3 << ETH_MODE_SHIFT) 145 146 /** Return whether the 802.3 + 802.2 + LSAP + SNAP mode flag is set. 147 * 148 * @param[in] flags Ethernet flags. 149 149 * @see ETH_8023_2_SNAP 150 */ 151 #define IS_8023_2_SNAP(flags) (((flags) & ETH_MODE_MASK) == ETH_8023_2_SNAP) 150 * 151 */ 152 #define IS_8023_2_SNAP(flags) (((flags) & ETH_MODE_MASK) == ETH_8023_2_SNAP) 152 153 153 154 /** Type definition of the ethernet address type. … … 246 247 rc = packet_translate_remote(eth_globals.net_phone, 247 248 &packet, IPC_GET_PACKET(*icall)); 248 if (rc == EOK) {249 if (rc == EOK) 249 250 rc = nil_received_msg_local(0, 250 251 IPC_GET_DEVICE(*icall), packet, 0); 251 }252 252 253 ipc_answer_0(iid, (sysarg_t) rc); 253 254 break; … … 836 837 } 837 838 838 int nil_m essage_standalone(const char *name, ipc_callid_t callid,839 ipc_call_t * call, ipc_call_t *answer, size_t *answer_count)839 int nil_module_message(ipc_callid_t callid, ipc_call_t *call, 840 ipc_call_t *answer, size_t *answer_count) 840 841 { 841 842 measured_string_t *address; … … 893 894 } 894 895 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 connection904 * - 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 processing925 * 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 936 896 int main(int argc, char *argv[]) 937 897 { 938 int rc;939 940 898 /* Start the module */ 941 rc = nil_module_start_standalone(nil_client_connection); 942 return rc; 899 return nil_module_start(SERVICE_ETHERNET); 943 900 } 944 901 -
uspace/srv/net/nil/eth/eth.h
r6610565b r8426912a 44 44 #include <adt/measured_strings.h> 45 45 46 /** Ethernet address length. */ 47 #define ETH_ADDR 6 48 49 /** Ethernet header preamble value. */ 50 #define ETH_PREAMBLE 0x55 51 52 /** Ethernet header start of frame value. */ 53 #define ETH_SFD 0xD5 54 55 /** IEEE 802.2 unordered information control field. */ 56 #define IEEE_8023_2_UI 0x03 57 58 /** Type definition of the Ethernet header IEEE 802.3 + 802.2 + SNAP extensions. 59 * @see eth_header_snap 60 */ 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_lsap 65 */ 66 typedef struct eth_header_lsap eth_header_lsap_t; 67 68 /** Type definition of the Ethernet header LSAP extension. 69 * @see eth_ieee_lsap 70 */ 71 typedef struct eth_ieee_lsap eth_ieee_lsap_t; 72 73 /** Type definition of the Ethernet header SNAP extension. 74 * @see eth_snap 75 */ 76 typedef struct eth_snap eth_snap_t; 77 78 /** Type definition of the Ethernet header preamble. 79 * @see preamble 80 */ 81 typedef struct eth_preamble eth_preamble_t; 82 83 /** Type definition of the Ethernet header. 84 * @see eth_header 85 */ 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.h 117 */ 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 transmission 134 * 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.h 150 */ 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 being 162 * used. 163 * If DSAP and SSAP fields are equal to ETH_RAW the raw Ethernet packet 164 * without any extensions is being used and the frame content starts 165 * 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 being 178 * used. 179 * If DSAP and SSAP fields are equal to ETH_RAW the raw Ethernet packet 180 * without any extensions is being used and the frame content starts 181 * 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 46 192 /** Type definition of the Ethernet global data. 47 193 * @see eth_globals -
uspace/srv/net/nil/nildummy/Makefile
r6610565b r8426912a 42 42 43 43 SOURCES = \ 44 nildummy.c \ 45 nildummy_module.c 44 nildummy.c 46 45 47 46 include $(USPACE_PREFIX)/Makefile.common -
uspace/srv/net/nil/nildummy/nildummy.c
r6610565b r8426912a 42 42 #include <str.h> 43 43 #include <ipc/ipc.h> 44 #include <ipc/nil.h> 44 45 #include <ipc/net.h> 45 46 #include <ipc/services.h> … … 47 48 #include <net/modules.h> 48 49 #include <net/device.h> 49 #include <nil_interface.h> 50 #include <il_interface.h> 50 #include <il_remote.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_ local.h>55 #include <nil_skel.h> 56 56 57 57 #include "nildummy.h" … … 81 81 int nil_initialize(int net_phone) 82 82 { 83 int rc;84 85 83 fibril_rwlock_initialize(&nildummy_globals.devices_lock); 86 84 fibril_rwlock_initialize(&nildummy_globals.protos_lock); … … 90 88 nildummy_globals.net_phone = net_phone; 91 89 nildummy_globals.proto.phone = 0; 92 rc = nildummy_devices_initialize(&nildummy_globals.devices);90 int rc = nildummy_devices_initialize(&nildummy_globals.devices); 93 91 94 92 fibril_rwlock_write_unlock(&nildummy_globals.protos_lock); … … 98 96 } 99 97 100 /** Process IPC messages from the registered device driver modules in an101 * infinite loop.102 * 103 * @param[in ] iid The message identifier.104 * @param[in,out] icall The message parameters.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 * 105 103 */ 106 104 static void nildummy_receiver(ipc_callid_t iid, ipc_call_t *icall) … … 108 106 packet_t *packet; 109 107 int rc; 110 108 111 109 while (true) { 112 110 switch (IPC_GET_IMETHOD(*icall)) { … … 120 118 rc = packet_translate_remote(nildummy_globals.net_phone, 121 119 &packet, IPC_GET_PACKET(*icall)); 122 if (rc == EOK) {120 if (rc == EOK) 123 121 rc = nil_received_msg_local(0, 124 122 IPC_GET_DEVICE(*icall), packet, 0); 125 }123 126 124 ipc_answer_0(iid, (sysarg_t) rc); 127 125 break; … … 139 137 * Determine the device local hardware address. 140 138 * 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. 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 * 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 159 155 fibril_rwlock_write_lock(&nildummy_globals.devices_lock); 160 156 161 157 /* An existing device? */ 162 device = nildummy_devices_find(&nildummy_globals.devices, device_id); 158 nildummy_device_t *device = 159 nildummy_devices_find(&nildummy_globals.devices, device_id); 163 160 if (device) { 164 161 if (device->service != service) { … … 213 210 214 211 /* Get hardware address */ 215 rc = netif_get_addr_req(device->phone, device->device_id, &device->addr,216 &device->addr _data);212 int rc = netif_get_addr_req(device->phone, device->device_id, 213 &device->addr, &device->addr_data); 217 214 if (rc != EOK) { 218 215 fibril_rwlock_write_unlock(&nildummy_globals.devices_lock); … … 222 219 223 220 /* Add to the cache */ 224 in dex = nildummy_devices_add(&nildummy_globals.devices,221 int index = nildummy_devices_add(&nildummy_globals.devices, 225 222 device->device_id, device); 226 223 if (index < 0) { … … 240 237 /** Return the device hardware address. 241 238 * 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. 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. 247 245 * 248 246 */ … … 250 248 measured_string_t **address) 251 249 { 252 nildummy_device_t *device;253 254 250 if (!address) 255 251 return EBADMEM; 256 252 257 253 fibril_rwlock_read_lock(&nildummy_globals.devices_lock); 258 device = nildummy_devices_find(&nildummy_globals.devices, device_id); 254 255 nildummy_device_t *device = 256 nildummy_devices_find(&nildummy_globals.devices, device_id); 259 257 if (!device) { 260 258 fibril_rwlock_read_unlock(&nildummy_globals.devices_lock); 261 259 return ENOENT; 262 260 } 261 263 262 *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 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. 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. 279 280 * 280 281 */ … … 282 283 size_t *prefix, size_t *content, size_t *suffix) 283 284 { 284 nildummy_device_t *device; 285 286 if (!addr_len || !prefix || !content || !suffix) 285 if ((!addr_len) || (!prefix) || (!content) || (!suffix)) 287 286 return EBADMEM; 288 287 289 288 fibril_rwlock_read_lock(&nildummy_globals.devices_lock); 290 device = nildummy_devices_find(&nildummy_globals.devices, device_id); 289 290 nildummy_device_t *device = 291 nildummy_devices_find(&nildummy_globals.devices, device_id); 291 292 if (!device) { 292 293 fibril_rwlock_read_unlock(&nildummy_globals.devices_lock); 293 294 return ENOENT; 294 295 } 295 296 296 297 *content = device->mtu; 298 297 299 fibril_rwlock_read_unlock(&nildummy_globals.devices_lock); 298 300 … … 306 308 packet_t *packet, services_t target) 307 309 { 308 packet_t *next;309 310 310 fibril_rwlock_read_lock(&nildummy_globals.protos_lock); 311 311 312 if (nildummy_globals.proto.phone) { 312 313 do { 313 next = pq_detach(packet);314 packet_t *next = pq_detach(packet); 314 315 il_received_msg(nildummy_globals.proto.phone, device_id, 315 316 packet, nildummy_globals.proto.service); 316 317 packet = next; 317 } while(packet); 318 } 318 } while (packet); 319 } 320 319 321 fibril_rwlock_read_unlock(&nildummy_globals.protos_lock); 320 322 … … 326 328 * Pass received packets for this service. 327 329 * 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. 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 * 333 337 */ 334 338 static int nildummy_register_message(services_t service, int phone) … … 347 351 /** Send the packet queue. 348 352 * 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. 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 * 355 361 */ 356 362 static int nildummy_send_message(device_id_t device_id, packet_t *packet, 357 363 services_t sender) 358 364 { 359 nildummy_device_t *device;360 361 365 fibril_rwlock_read_lock(&nildummy_globals.devices_lock); 362 device = nildummy_devices_find(&nildummy_globals.devices, device_id); 366 367 nildummy_device_t *device = 368 nildummy_devices_find(&nildummy_globals.devices, device_id); 363 369 if (!device) { 364 370 fibril_rwlock_read_unlock(&nildummy_globals.devices_lock); 365 371 return ENOENT; 366 372 } 367 373 368 374 /* Send packet queue */ 369 375 if (packet) 370 376 netif_send_msg(device->phone, device_id, packet, 371 377 SERVICE_NILDUMMY); 378 372 379 fibril_rwlock_read_unlock(&nildummy_globals.devices_lock); 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) 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) 378 386 { 379 387 measured_string_t *address; … … 434 442 } 435 443 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 connection445 * - 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 processing466 * 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 477 444 int main(int argc, char *argv[]) 478 445 { 479 int rc;480 481 446 /* Start the module */ 482 rc = nil_module_start_standalone(nil_client_connection); 483 return rc; 447 return nil_module_start(SERVICE_NILDUMMY); 484 448 } 485 449 -
uspace/srv/net/nil/nildummy/nildummy.h
r6610565b r8426912a 45 45 46 46 /** Type definition of the dummy nil global data. 47 * 47 48 * @see nildummy_globals 49 * 48 50 */ 49 51 typedef struct nildummy_globals nildummy_globals_t; 50 52 51 53 /** Type definition of the dummy nil device specific data. 54 * 52 55 * @see nildummy_device 56 * 53 57 */ 54 58 typedef struct nildummy_device nildummy_device_t; 55 59 56 60 /** Type definition of the dummy nil protocol specific data. 61 * 57 62 * @see nildummy_proto 63 * 58 64 */ 59 65 typedef struct nildummy_proto nildummy_proto_t; 60 66 61 67 /** Dummy nil device map. 62 * Maps devices to the dummy nil device specific data. 68 * 69 * Map devices to the dummy nil device specific data. 63 70 * @see device.h 71 * 64 72 */ 65 73 DEVICE_MAP_DECLARE(nildummy_devices, nildummy_device_t); … … 69 77 /** Device identifier. */ 70 78 device_id_t device_id; 79 71 80 /** Device driver service. */ 72 81 services_t service; 82 73 83 /** Driver phone. */ 74 84 int phone; 85 75 86 /** Maximal transmission unit. */ 76 87 size_t mtu; 88 77 89 /** Actual device hardware address. */ 78 90 measured_string_t *addr; 91 79 92 /** Actual device hardware address data. */ 80 93 uint8_t *addr_data; … … 85 98 /** Protocol service. */ 86 99 services_t service; 100 87 101 /** Protocol module phone. */ 88 102 int phone; … … 93 107 /** Networking module phone. */ 94 108 int net_phone; 95 /** Safety lock for devices. */ 109 110 /** Lock for devices. */ 96 111 fibril_rwlock_t devices_lock; 112 97 113 /** All known Ethernet devices. */ 98 114 nildummy_devices_t devices; 115 99 116 /** Safety lock for protocols. */ 100 117 fibril_rwlock_t protos_lock; 118 101 119 /** Default protocol. */ 102 120 nildummy_proto_t proto; -
uspace/srv/net/tl/icmp/Makefile
r6610565b r8426912a 34 34 35 35 SOURCES = \ 36 icmp.c \ 37 icmp_module.c 36 icmp.c 38 37 39 38 include $(USPACE_PREFIX)/Makefile.common -
uspace/srv/net/tl/icmp/icmp.c
r6610565b r8426912a 35 35 * @see icmp.h 36 36 */ 37 38 #include "icmp.h"39 #include "icmp_module.h"40 37 41 38 #include <async.h> … … 68 65 #include <icmp_client.h> 69 66 #include <icmp_interface.h> 70 #include <il_ interface.h>67 #include <il_remote.h> 71 68 #include <ip_client.h> 72 69 #include <ip_interface.h> 73 70 #include <net_interface.h> 74 #include <tl_ interface.h>75 #include <tl_ local.h>71 #include <tl_remote.h> 72 #include <tl_skel.h> 76 73 #include <icmp_header.h> 77 74 75 #include "icmp.h" 76 78 77 /** ICMP module name. */ 79 #define NAME "ICMP protocol"78 #define NAME "icmp" 80 79 81 80 /** Default ICMP error reporting. */ … … 394 393 } 395 394 396 /** Initializes the ICMP module.397 *398 * @param[in] client_connection The client connection processing function. The399 * 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 20409 },410 {411 (uint8_t *) "ICMP_ECHO_REPLYING",412 18413 }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;468 }469 470 395 /** Tries to set the pending reply result as the received message type. 471 396 * … … 667 592 return icmp_release_and_return(packet, rc); 668 593 594 return EOK; 595 } 596 597 /** Process IPC messages from the IP module 598 * 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 20 641 }, 642 { 643 (uint8_t *) "ICMP_ECHO_REPLYING", 644 18 645 } 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); 669 700 return EOK; 670 701 } … … 893 924 * @see IS_NET_ICMP_MESSAGE() 894 925 */ 895 int icmp_message_standalone(ipc_callid_t callid, ipc_call_t *call,926 int tl_module_message (ipc_callid_t callid, ipc_call_t *call, 896 927 ipc_call_t *answer, size_t *answer_count) 897 928 { 898 packet_t *packet;899 int rc;900 901 929 *answer_count = 0; 902 930 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 911 931 case NET_ICMP_INIT: 912 932 return icmp_process_client_messages(callid, *call); 913 914 933 default: 915 934 return icmp_process_message(call); 916 935 } 917 936 918 937 return ENOTSUP; 919 938 } 920 939 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 connection932 * - Answer the first IPC_M_CONNECT_ME_TO call.933 */934 ipc_answer_0(iid, EOK);935 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 processing953 * 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 module968 * start function.969 */970 940 int main(int argc, char *argv[]) 971 941 { 972 int rc;973 974 942 /* Start the module */ 975 rc = tl_module_start_standalone(tl_client_connection); 976 return rc; 943 return tl_module_start(SERVICE_ICMP); 977 944 } 978 945 979 946 /** @} 980 947 */ 981 -
uspace/srv/net/tl/tcp/Makefile
r6610565b r8426912a 34 34 35 35 SOURCES = \ 36 tcp.c \ 37 tcp_module.c 36 tcp.c 38 37 39 38 include $(USPACE_PREFIX)/Makefile.common -
uspace/srv/net/tl/tcp/tcp.c
r6610565b r8426912a 36 36 */ 37 37 38 #include "tcp.h"39 #include "tcp_header.h"40 #include "tcp_module.h"41 42 38 #include <assert.h> 43 39 #include <async.h> … … 72 68 #include <socket_core.h> 73 69 #include <tl_common.h> 74 #include <tl_local.h> 75 #include <tl_interface.h> 70 #include <tl_remote.h> 71 #include <tl_skel.h> 72 73 #include "tcp.h" 74 #include "tcp_header.h" 76 75 77 76 /** TCP module name. */ 78 #define NAME "TCP protocol"77 #define NAME "tcp" 79 78 80 79 /** The TCP window default value. */ … … 220 219 /** TCP global data. */ 221 220 tcp_globals_t tcp_globals; 222 223 /** Initializes the TCP module.224 *225 * @param[in] client_connection The client connection processing function. The226 * 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 }264 221 265 222 int tcp_received_msg(device_id_t device_id, packet_t *packet, … … 1260 1217 * @see IS_NET_TCP_MESSAGE() 1261 1218 */ 1262 int 1263 tcp_message_standalone(ipc_callid_t callid, ipc_call_t *call, 1219 int tl_module_message(ipc_callid_t callid, ipc_call_t *call, 1264 1220 ipc_call_t *answer, size_t *answer_count) 1265 1221 { 1266 packet_t *packet;1267 int rc;1268 1269 1222 assert(call); 1270 1223 assert(answer); … … 1273 1226 *answer_count = 0; 1274 1227 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;1287 1228 case IPC_M_CONNECT_TO_ME: 1288 1229 return tcp_process_client_messages(callid, *call); … … 2486 2427 } 2487 2428 2488 /** Default thread for new connections.2429 /** Process IPC messages from the IP module 2489 2430 * 2490 * @param[in] iid The initial message identifier.2491 * @param[in ] icall The initial message call structure.2431 * @param[in] iid Message identifier. 2432 * @param[in,out] icall Message parameters. 2492 2433 * 2493 2434 */ 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 2435 static void tcp_receiver(ipc_callid_t iid, ipc_call_t *icall) 2436 { 2437 packet_t *packet; 2438 int rc; 2439 2502 2440 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. 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. 2533 2460 * 2534 * @return EOK on success. 2535 * @return Other error codes as defined for each specific module 2536 * start function. 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 * 2537 2466 */ 2538 int 2539 main(int argc, char *argv[]) 2540 { 2541 int rc; 2542 2543 rc = tl_module_start_standalone(tl_client_connection); 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); 2544 2497 return rc; 2498 } 2499 2500 int main(int argc, char *argv[]) 2501 { 2502 return tl_module_start(SERVICE_TCP); 2545 2503 } 2546 2504 -
uspace/srv/net/tl/udp/Makefile
r6610565b r8426912a 34 34 35 35 SOURCES = \ 36 udp.c \ 37 udp_module.c 36 udp.c 38 37 39 38 include $(USPACE_PREFIX)/Makefile.common -
uspace/srv/net/tl/udp/udp.c
r6610565b r8426912a 35 35 * @see udp.h 36 36 */ 37 38 #include "udp.h"39 #include "udp_header.h"40 #include "udp_module.h"41 37 42 38 #include <async.h> … … 69 65 #include <socket_core.h> 70 66 #include <tl_common.h> 71 #include <tl_local.h> 72 #include <tl_interface.h> 67 #include <tl_remote.h> 68 #include <tl_skel.h> 69 70 #include "udp.h" 71 #include "udp_header.h" 73 72 74 73 /** UDP module name. */ 75 #define NAME "UDP protocol"74 #define NAME "udp" 76 75 77 76 /** Default UDP checksum computing. */ … … 92 91 /** UDP global data. */ 93 92 udp_globals_t udp_globals; 94 95 /** Initializes the UDP module.96 *97 * @param[in] client_connection The client connection processing function. The98 * 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 22108 },109 {110 (uint8_t *) "UDP_AUTOBINDING",111 15112 }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 }185 93 186 94 /** Releases the packet and returns the result. … … 426 334 } 427 335 336 /** Process IPC messages from the IP module 337 * 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 22 380 }, 381 { 382 (uint8_t *) "UDP_AUTOBINDING", 383 15 384 } 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 428 459 /** Sends data from the socket to the remote address. 429 460 * … … 860 891 * @see IS_NET_UDP_MESSAGE() 861 892 */ 862 int udp_message_standalone(ipc_callid_t callid, ipc_call_t *call,893 int tl_module_message(ipc_callid_t callid, ipc_call_t *call, 863 894 ipc_call_t *answer, size_t *answer_count) 864 895 { 865 packet_t *packet;866 int rc;867 868 896 *answer_count = 0; 869 897 870 898 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));878 899 case IPC_M_CONNECT_TO_ME: 879 900 return udp_process_client_messages(callid, *call); … … 883 904 } 884 905 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 connection894 * - 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 processing915 * 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 module930 * start function.931 */932 906 int main(int argc, char *argv[]) 933 907 { 934 int rc;935 936 908 /* Start the module */ 937 rc = tl_module_start_standalone(tl_client_connection); 938 return rc; 909 return tl_module_start(SERVICE_UDP); 939 910 } 940 911
Note:
See TracChangeset
for help on using the changeset viewer.