static ni_netdev_t * __ni_objectmodel_dummy_newlink(ni_netdev_t *cfg_ifp, const char *ifname, DBusError *error) { ni_netconfig_t *nc = ni_global_state_handle(0); ni_netdev_t *dev_ifp = NULL; int rv; if (ni_string_empty(ifname)) { if (ni_string_empty(cfg_ifp->name) && (ifname = ni_netdev_make_name(nc, "dummy", 0))) { ni_string_dup(&cfg_ifp->name, ifname); } else { dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "Unable to create dummy interface: " "name argument missed"); goto out; } ifname = NULL; } else if(!ni_string_eq(cfg_ifp->name, ifname)) { ni_string_dup(&cfg_ifp->name, ifname); } if (cfg_ifp->link.hwaddr.len) { if (cfg_ifp->link.hwaddr.type == ARPHRD_VOID) cfg_ifp->link.hwaddr.type = ARPHRD_ETHER; if (cfg_ifp->link.hwaddr.type != ARPHRD_ETHER || cfg_ifp->link.hwaddr.len != ni_link_address_length(ARPHRD_ETHER)) { dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "Cannot create dummy interface: " "invalid ethernet address '%s'", ni_link_address_print(&cfg_ifp->link.hwaddr)); return NULL; } } if ((rv = ni_system_dummy_create(nc, cfg_ifp, &dev_ifp)) < 0) { if (rv != -NI_ERROR_DEVICE_EXISTS || dev_ifp == NULL || (ifname && dev_ifp && !ni_string_eq(dev_ifp->name, ifname))) { dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create dummy interface: %s", ni_strerror(rv)); dev_ifp = NULL; goto out; } ni_debug_dbus("dummy interface exists (and name matches)"); } if (dev_ifp->link.type != NI_IFTYPE_DUMMY) { dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create dummy interface: " "new interface is of type %s", ni_linktype_type_to_name(dev_ifp->link.type)); dev_ifp = NULL; } out: if (cfg_ifp) ni_netdev_put(cfg_ifp); return dev_ifp; }
/* * get/set ethtool.wake-on-lan */ static dbus_bool_t ni_objectmodel_ethtool_get_wake_on_lan(const ni_dbus_object_t *object, const ni_dbus_property_t *property, ni_dbus_variant_t *result, DBusError *error) { const ni_ethtool_wake_on_lan_t *wol; const ni_ethtool_t *ethtool; if (!(ethtool = ni_objectmodel_ethtool_read_handle(object, error))) return FALSE; if (!(wol = ethtool->wake_on_lan)) return FALSE; if (wol->support == NI_ETHTOOL_WOL_DEFAULT || wol->support == NI_ETHTOOL_WOL_DISABLE) return FALSE; ni_dbus_variant_init_dict(result); ni_dbus_dict_add_uint32(result, "support", wol->support); if (wol->options != NI_ETHTOOL_WOL_DEFAULT) ni_dbus_dict_add_uint32(result, "options", wol->options); /* from config it is VOID, hide sopass from kernel with type ETHER */ if (wol->sopass.len && wol->sopass.type == ARPHRD_VOID && wol->sopass.len == ni_link_address_length(ARPHRD_ETHER)) __ni_objectmodel_dict_add_hwaddr(result, "sopass", &wol->sopass); return TRUE; }
static ni_netdev_t * __ni_objectmodel_team_newlink(ni_netdev_t *cfg_ifp, const char *ifname, DBusError *error) { ni_netconfig_t *nc = ni_global_state_handle(0); ni_netdev_t *new_ifp = NULL; int rv; ni_netdev_get_team(cfg_ifp); if (ifname == NULL && !(ifname = ni_netdev_make_name(nc, "team", 0))) { dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create team interface - too many interfaces"); goto out; } ni_string_dup(&cfg_ifp->name, ifname); if (cfg_ifp->link.hwaddr.len) { if (cfg_ifp->link.hwaddr.type == ARPHRD_VOID) cfg_ifp->link.hwaddr.type = ARPHRD_ETHER; if (cfg_ifp->link.hwaddr.type != ARPHRD_ETHER || cfg_ifp->link.hwaddr.len != ni_link_address_length(ARPHRD_ETHER)) { dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "Cannot create team interface: invalid ethernet address '%s'", ni_link_address_print(&cfg_ifp->link.hwaddr)); goto out; } } if ((rv = ni_system_team_create(nc, cfg_ifp, &new_ifp)) < 0) { dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create team interface '%s'", cfg_ifp->name); new_ifp = NULL; goto out; #if 0 if (rv != -NI_ERROR_DEVICE_EXISTS && (ifname != NULL && strcmp(ifname, new_ifp->name))) { dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create team interface: %s", ni_strerror(rv)); goto out; } ni_debug_dbus("Bonding interface exists (and name matches)"); #endif } if (new_ifp->link.type != NI_IFTYPE_TEAM) { dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create team interface: new interface is of type %s", ni_linktype_type_to_name(new_ifp->link.type)); new_ifp = NULL; } out: if (cfg_ifp) ni_netdev_put(cfg_ifp); return new_ifp; }
int ni_arp_send(ni_arp_socket_t *arph, const ni_arp_packet_t *packet) { unsigned int hwlen, pktlen; struct arphdr *arp; ni_buffer_t buf; int rv; hwlen = ni_link_address_length(arph->dev_info.hwaddr.type); pktlen = sizeof(*arp) + 2 * hwlen + 2 * 4; arp = calloc(1, pktlen); ni_buffer_init(&buf, arp, pktlen); arp = ni_buffer_push_tail(&buf, sizeof(*arp)); arp->ar_hrd = htons(arph->dev_info.hwaddr.type); arp->ar_pro = htons(ETHERTYPE_IP); arp->ar_hln = hwlen; arp->ar_pln = 4; arp->ar_op = htons(packet->op); if (packet->sha.len == hwlen) { ni_buffer_put(&buf, packet->sha.data, packet->sha.len); } else { ni_buffer_put(&buf, NULL, hwlen); } ni_buffer_put(&buf, &packet->sip, 4); if (packet->tha.len == hwlen) { ni_buffer_put(&buf, packet->tha.data, packet->tha.len); } else { ni_buffer_put(&buf, NULL, hwlen); } ni_buffer_put(&buf, &packet->tip, 4); rv = ni_capture_send(arph->capture, &buf, NULL); free(buf.base); return rv; }
int ni_arp_parse(ni_arp_socket_t *arph, ni_buffer_t *bp, ni_arp_packet_t *p) { struct arphdr *arp; if (!(arp = ni_buffer_pull_head(bp, sizeof(*arp)))) return -1; if (arp->ar_pro != htons(ETHERTYPE_IP) || arp->ar_pln != 4) return -1; p->op = ntohs(arp->ar_op); p->sha.type = arph->dev_info.hwaddr.type; p->sha.len = ni_link_address_length(arph->dev_info.hwaddr.type); p->tha = p->sha; if (ni_buffer_get(bp, p->sha.data, p->sha.len) < 0 || ni_buffer_get(bp, &p->sip, 4) < 0 || ni_buffer_get(bp, p->tha.data, p->tha.len) < 0 || ni_buffer_get(bp, &p->tip, 4) < 0) return -1; return 0; }
static ni_netdev_t * __ni_objectmodel_macvlan_newlink(ni_netdev_t *cfg_ifp, const char *ifname, DBusError *error) { ni_netconfig_t *nc = ni_global_state_handle(0); ni_netdev_t *dev_ifp = NULL; const ni_macvlan_t *macvlan; const char *err; const char *cfg_ifp_iftype = NULL; int rv; cfg_ifp_iftype = ni_linktype_type_to_name(cfg_ifp->link.type); if (ni_string_empty(cfg_ifp->link.lowerdev.name)) { dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "Incomplete arguments: need a lower device name"); return NULL; } else if (!ni_netdev_ref_bind_ifindex(&cfg_ifp->link.lowerdev, nc)) { dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "Unable to find %s lower device %s by name", cfg_ifp_iftype, cfg_ifp->link.lowerdev.name); return NULL; } macvlan = ni_netdev_get_macvlan(cfg_ifp); if ((err = ni_macvlan_validate(macvlan))) { dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "%s", err); goto out; } if (ni_string_empty(ifname)) { if (ni_string_empty(cfg_ifp->name) && (ifname = ni_netdev_make_name( nc, cfg_ifp_iftype, 0))) { ni_string_dup(&cfg_ifp->name, ifname); } else { dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "Unable to create %s interface: " "name argument missed", cfg_ifp_iftype); goto out; } ifname = NULL; } else if(!ni_string_eq(cfg_ifp->name, ifname)) { ni_string_dup(&cfg_ifp->name, ifname); } if (ni_string_eq(cfg_ifp->name, cfg_ifp->link.lowerdev.name)) { dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "Cannot create %s interface: " "macvlan name %s equal with lower device name", cfg_ifp_iftype, cfg_ifp->name); return NULL; } if (cfg_ifp->link.hwaddr.len) { if (cfg_ifp->link.hwaddr.type == ARPHRD_VOID) cfg_ifp->link.hwaddr.type = ARPHRD_ETHER; if (cfg_ifp->link.hwaddr.type != ARPHRD_ETHER || cfg_ifp->link.hwaddr.len != ni_link_address_length(ARPHRD_ETHER)) { dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "Cannot create %s interface: " "invalid ethernet address '%s'", cfg_ifp_iftype, ni_link_address_print(&cfg_ifp->link.hwaddr)); return NULL; } } if ((rv = ni_system_macvlan_create(nc, cfg_ifp, &dev_ifp)) < 0) { if (rv != -NI_ERROR_DEVICE_EXISTS || dev_ifp == NULL || (ifname && dev_ifp && !ni_string_eq(dev_ifp->name, ifname))) { dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create %s interface: %s", cfg_ifp_iftype, ni_strerror(rv)); dev_ifp = NULL; goto out; } ni_debug_dbus("%s interface exists (and name matches)", cfg_ifp_iftype); } if (dev_ifp->link.type != cfg_ifp->link.type) { dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create %s interface: " "new interface is of type %s", cfg_ifp_iftype, ni_linktype_type_to_name(dev_ifp->link.type)); dev_ifp = NULL; } out: if (cfg_ifp) ni_netdev_put(cfg_ifp); return dev_ifp; }
static ni_netdev_t * __ni_objectmodel_gre_create(ni_netdev_t *cfg_ifp, const char *ifname, DBusError *error) { ni_netconfig_t *nc = ni_global_state_handle(0); ni_gre_t *gre = NULL; ni_netdev_t *dev = NULL; const char *err = NULL; int rv; gre = ni_netdev_get_gre(cfg_ifp); if ((err = ni_gre_validate(gre))) { dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "%s", err); goto out; } if (ni_string_empty(ifname)) { if (ni_string_empty(cfg_ifp->name) && (ifname = ni_netdev_make_name(nc, "gre", 1))) { ni_string_dup(&cfg_ifp->name, ifname); } else { dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "Unable to create gre tunnel: " "name argument missed"); goto out; } ifname = NULL; } else if(!ni_string_eq(cfg_ifp->name, ifname)) { ni_string_dup(&cfg_ifp->name, ifname); } if (!ni_string_empty(cfg_ifp->link.lowerdev.name) && !ni_objectmodel_bind_netdev_ref_index(cfg_ifp->name, "gre tunnel", &cfg_ifp->link.lowerdev, nc, error)) goto out; if (cfg_ifp->link.hwaddr.len) { if (cfg_ifp->link.hwaddr.type == ARPHRD_VOID) cfg_ifp->link.hwaddr.type = ARPHRD_IPGRE; if (cfg_ifp->link.hwaddr.type != ARPHRD_IPGRE || cfg_ifp->link.hwaddr.len != ni_link_address_length(ARPHRD_IPGRE)) { dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "Cannot create gre tunnel interface: " "invalid local address '%s'", ni_link_address_print(&cfg_ifp->link.hwaddr)); return NULL; } } if (cfg_ifp->link.hwpeer.len) { if (cfg_ifp->link.hwpeer.type == ARPHRD_VOID) cfg_ifp->link.hwpeer.type = ARPHRD_IPGRE; if (cfg_ifp->link.hwpeer.type != ARPHRD_IPGRE || cfg_ifp->link.hwpeer.len != ni_link_address_length(ARPHRD_IPGRE)) { dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "Cannot create gre tunnel interface: " "invalid remote address '%s'", ni_link_address_print(&cfg_ifp->link.hwpeer)); return NULL; } } if ((rv = ni_system_tunnel_create(nc, cfg_ifp, &dev, NI_IFTYPE_GRE) < 0)) { if (rv != -NI_ERROR_DEVICE_EXISTS || dev == NULL || (ifname && dev && !ni_string_eq(dev->name, ifname))) { dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create gre tunnel: %s", cfg_ifp->name); dev = NULL; goto out; } ni_debug_dbus("gre tunnel exists (and name matches)"); } if (dev->link.type != NI_IFTYPE_GRE) { dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create gre tunnel: " "new interface is of type %s", ni_linktype_type_to_name(dev->link.type)); dev = NULL; } out: if (cfg_ifp) ni_netdev_put(cfg_ifp); return dev; }
/* * Create a new TUN/TAP interface */ static ni_netdev_t * __ni_objectmodel_tuntap_create(ni_netdev_t *cfg, DBusError *error) { ni_netconfig_t *nc = ni_global_state_handle(0); ni_netdev_t *dev = NULL; const char *iftype; const ni_tuntap_t *tuntap; const char *err; int rv; iftype = ni_linktype_type_to_name(cfg->link.type); if (cfg->link.type != NI_IFTYPE_TUN && cfg->link.type != NI_IFTYPE_TAP) { dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "BUG: Cannot handle %s type in tun/tap factory", iftype); return NULL; } ni_debug_dbus("%s.newDevice(name=%s)", iftype, cfg->name); tuntap = ni_netdev_get_tuntap(cfg); if ((err = ni_tuntap_validate(tuntap))) { dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "%s", err); return NULL; } if (ni_string_empty(cfg->name)) { if (ni_string_empty(cfg->name) && (cfg->name = (char *) ni_netdev_make_name(nc, iftype, 0))) { ni_string_dup(&cfg->name, cfg->name); } else { dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "Unable to create %s interface: " "name argument missed", iftype); return NULL; } cfg->name = NULL; } else if(!ni_string_eq(cfg->name, cfg->name)) { ni_string_dup(&cfg->name, cfg->name); } if (cfg->link.type == NI_IFTYPE_TAP && cfg->link.hwaddr.len) { if (cfg->link.hwaddr.type == ARPHRD_VOID) cfg->link.hwaddr.type = ARPHRD_ETHER; if (cfg->link.hwaddr.type != ARPHRD_ETHER || cfg->link.hwaddr.len != ni_link_address_length(ARPHRD_ETHER)) { dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "Cannot create %s interface: " "invalid ethernet address '%s'", iftype, ni_link_address_print(&cfg->link.hwaddr)); return NULL; } } if ((rv = ni_system_tuntap_create(nc, cfg, &dev)) < 0) { if (rv != -NI_ERROR_DEVICE_EXISTS || dev == NULL || (cfg->name && dev && !ni_string_eq(dev->name, cfg->name))) { ni_dbus_set_error_from_code(error, rv, "Unable to create %s interface %s", iftype, cfg->name); return NULL; } ni_debug_dbus("%s interface exists (and name matches)", iftype); } if (dev->link.type != cfg->link.type) { dbus_set_error(error, DBUS_ERROR_FAILED, "Unable to create %s: existing interface %s is of type %s", iftype, dev->name, ni_linktype_type_to_name(dev->link.type)); return NULL; } return dev; }