Beispiel #1
0
int CreateNgKsocket() {
    char path[NG_PATHSIZ];
    struct ngm_mkpeer arg;
    
    sprintf(arg.type, "ksocket");
    sprintf(arg.peerhook, "inet/stream/tcp");
    sprintf(arg.ourhook, "delusion");
    
    memset(path, 0, sizeof(path));
    sprintf(path, ".:");
    if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE, NGM_MKPEER, &arg, sizeof(arg)) < 0 ) {
        printf("%s(): Error sending message: %s", __func__, strerror(errno));
        return -1;
    }
    sprintf(path, ".:%s", arg.ourhook);
    memset( ksock_name, 0, sizeof(ksock_name) );
    sprintf(ksock_name, "http-ksocket-%d", getpid());
    if ( NgNameNode(csock, path, ksock_name, getpid()) < 0 ) {
        printf("%s: error naming node : %s", __func__, strerror(errno));
        return -1;
    }

    /* make kscoket bind and listen state */
    struct sockaddr_in source;
    source.sin_family = AF_INET;
    inet_aton(SRC_IP, &source.sin_addr);
    source.sin_port = htons(atoi(SRC_PORT));
    source.sin_len = sizeof(struct sockaddr_in);
    sprintf(path, "%s:", ksock_name);
    NgSetDebug(3);
    if ( NgSendMsg(csock, path, NGM_KSOCKET_COOKIE, NGM_KSOCKET_BIND,  &source, sizeof(source)) < 0 ) {
        printf("%s(): Error sending ksocket bind: %s\n", __func__, strerror(errno));
        return -1;
    }
    /* Listening ksocket */
    int lst = 1024;
    if ( NgSendMsg(csock, path, NGM_KSOCKET_COOKIE, NGM_KSOCKET_LISTEN,  &lst, sizeof(lst)) < 0 ) {
        printf("%s(): Error sending ksocket bind: %s\n", __func__, strerror(errno));
        return -1;
    }
    int token;
    token = NgSendMsg(csock, path, NGM_KSOCKET_COOKIE, NGM_KSOCKET_ACCEPT, NULL, 0);
    if ( token < 0 && errno != EINPROGRESS && errno != EALREADY ) {
        printf("%s(): Accept Failed %s\n", __func__, strerror(errno));
        return -1;
    }
    SetKsocketKeepAlive(ksock_name);
    return token;
}
Beispiel #2
0
struct device *
ng_Create(struct physical *p)
{
    struct sockaddr_ng ngsock;
    u_char rbuf[2048];
    struct sockaddr *sock = (struct sockaddr *)&ngsock;
    const struct hooklist *hlist;
    const struct nodeinfo *ninfo;
    const struct linkinfo *nlink;
    struct ngdevice *dev;
    struct ng_mesg *resp;
    struct ngm_mkpeer mkp;
    struct ngm_connect ngc;
    const char *devp, *endp;
    char lasthook[NG_HOOKSIZ];
    char hook[NG_HOOKSIZ];
    char nodetype[NG_TYPESIZ + NG_NODESIZ];
    char modname[NG_TYPESIZ + 3];
    char path[NG_PATHSIZ];
    char *nodename;
    int len, sz, done;
    unsigned f;

    dev = NULL;
    if (p->fd < 0 && !strncasecmp(p->name.full, NETGRAPH_PREFIX,
                                  sizeof NETGRAPH_PREFIX - 1)) {
        p->fd--;				/* We own the device - change fd */

        if ((dev = malloc(sizeof *dev)) == NULL)
            return NULL;

        loadmodules(LOAD_VERBOSLY, "netgraph", "ng_socket", NULL);

        /* Create a socket node */
        if (ID0NgMkSockNode(NULL, &dev->cs, &p->fd) == -1) {
            log_Printf(LogWARN, "Cannot create netgraph socket node: %s\n",
                       strerror(errno));
            free(dev);
            p->fd = -2;
            return NULL;
        }

        devp = p->name.full + sizeof NETGRAPH_PREFIX - 1;
        *lasthook = *path = '\0';
        log_Printf(LogDEBUG, "%s: Opening netgraph device \"%s\"\n",
                   p->link.name, devp);
        done = 0;

        while (*devp != '\0' && !done) {
            if (*devp != '[') {
                if (*lasthook == '\0') {
                    log_Printf(LogWARN, "%s: Netgraph devices must start with"
                               " [nodetype:nodename]\n", p->link.name);
                    return ng_Abandon(dev, p);
                }

                /* Get the hook name of the new node */
                if (!GETSEGMENT(hook, devp, ".[", &endp))
                    return ng_Abandon(dev, p);
                log_Printf(LogDEBUG, "%s: Got hook \"%s\"\n", p->link.name, hook);
                devp = endp;
                if (*devp == '\0') {
                    log_Printf(LogWARN, "%s: Netgraph device must not end with a second"
                               " hook\n", p->link.name);
                    return ng_Abandon(dev, p);
                }
                if (devp[-1] != '[') {
                    log_Printf(LogWARN, "%s: Expected a [nodetype:nodename] at device"
                               " pos %d\n", p->link.name, devp - p->link.name - 1);
                    return ng_Abandon(dev, p);
                }
            } else {
                /* Use lasthook as the hook name */
                strcpy(hook, lasthook);
                devp++;
            }

            /* We've got ``lasthook'' and ``hook'', get the node type */
            if (!GETSEGMENT(nodetype, devp, "]", &endp))
                return ng_Abandon(dev, p);
            log_Printf(LogDEBUG, "%s: Got node \"%s\"\n", p->link.name, nodetype);

            if ((nodename = strchr(nodetype, ':')) != NULL) {
                *nodename++ = '\0';
                if (*nodename == '\0' && *nodetype == '\0') {
                    log_Printf(LogWARN, "%s: Empty [nodetype:nodename] at device"
                               " pos %d\n", p->link.name, devp - p->link.name - 1);
                    return ng_Abandon(dev, p);
                }
            }

            /* Ignore optional colons after nodes */
            devp = *endp == ':' ? endp + 1 : endp;
            if (*devp == '.')
                devp++;

            if (*lasthook == '\0') {
                /* This is the first node in the chain */
                if (nodename == NULL || *nodename == '\0') {
                    log_Printf(LogWARN, "%s: %s: No initial device nodename\n",
                               p->link.name, devp);
                    return ng_Abandon(dev, p);
                }

                if (*nodetype != '\0') {
                    /* Attempt to load the module */
                    snprintf(modname, sizeof modname, "ng_%s", nodetype);
                    log_Printf(LogDEBUG, "%s: Attempting to load %s.ko\n",
                               p->link.name, modname);
                    loadmodules(LOAD_QUIETLY, modname, NULL);
                }

                snprintf(path, sizeof path, "%s:", nodename);
                /* XXX: If we have a node type, ensure it's correct */
            } else {
                /*
                 * Ask for a list of hooks attached to the previous node.  If we
                 * find the one we're interested in, and if it's connected to a
                 * node of the right type using the correct hook, use that.
                 * If we find the hook connected to something else, fail.
                 * If we find no match, mkpeer the new node.
                 */
                if (*nodetype == '\0') {
                    log_Printf(LogWARN, "%s: Nodetype missing at device offset %d\n",
                               p->link.name,
                               devp - p->name.full + sizeof NETGRAPH_PREFIX - 1);
                    return ng_Abandon(dev, p);
                }

                /* Get a list of node hooks */
                if (NgSendMsg(dev->cs, path, NGM_GENERIC_COOKIE, NGM_LISTHOOKS,
                              NULL, 0) < 0) {
                    log_Printf(LogWARN, "%s: %s Cannot send a LISTHOOOKS message: %s\n",
                               p->link.name, path, strerror(errno));
                    return ng_Abandon(dev, p);
                }

                /* Get our list back */
                resp = (struct ng_mesg *)rbuf;
                if (NgRecvMsg(dev->cs, resp, sizeof rbuf, NULL) <= 0) {
                    log_Printf(LogWARN, "%s: Cannot get netgraph response: %s\n",
                               p->link.name, strerror(errno));
                    return ng_Abandon(dev, p);
                }

                hlist = (const struct hooklist *)resp->data;
                ninfo = &hlist->nodeinfo;

                log_Printf(LogDEBUG, "List of netgraph node ``%s'' (id %x) hooks:\n",
                           path, ninfo->id);

                /* look for a hook already attached.  */
                for (f = 0; f < ninfo->hooks; f++) {
                    nlink = &hlist->link[f];

                    log_Printf(LogDEBUG, "  Found %s -> %s (type %s)\n", nlink->ourhook,
                               nlink->peerhook, nlink->nodeinfo.type);

                    if (!strcmp(nlink->ourhook, lasthook)) {
                        if (strcmp(nlink->peerhook, hook) ||
                                strcmp(nlink->nodeinfo.type, nodetype)) {
                            log_Printf(LogWARN, "%s: hook %s:%s is already in use\n",
                                       p->link.name, nlink->ourhook, path);
                            return ng_Abandon(dev, p);
                        }
                        /* The node is already hooked up nicely.... reuse it */
                        break;
                    }
                }

                if (f == ninfo->hooks) {
                    /* Attempt to load the module */
                    snprintf(modname, sizeof modname, "ng_%s", nodetype);
                    log_Printf(LogDEBUG, "%s: Attempting to load %s.ko\n",
                               p->link.name, modname);
                    loadmodules(LOAD_QUIETLY, modname, NULL);

                    /* Create (mkpeer) the new node */

                    snprintf(mkp.type, sizeof mkp.type, "%s", nodetype);
                    snprintf(mkp.ourhook, sizeof mkp.ourhook, "%s", lasthook);
                    snprintf(mkp.peerhook, sizeof mkp.peerhook, "%s", hook);

                    log_Printf(LogDEBUG, "%s: Doing MKPEER %s%s -> %s (type %s)\n",
                               p->link.name, path, mkp.ourhook, mkp.peerhook, nodetype);

                    if (NgSendMsg(dev->cs, path, NGM_GENERIC_COOKIE,
                                  NGM_MKPEER, &mkp, sizeof mkp) < 0) {
                        log_Printf(LogWARN, "%s Cannot create %s netgraph node: %s\n",
                                   path, nodetype, strerror(errno));
                        return ng_Abandon(dev, p);
                    }
                }
                len = strlen(path);
                snprintf(path + len, sizeof path - len, "%s%s",
                         path[len - 1] == ':' ? "" : ".", lasthook);
            }

            /* Get a list of node hooks */
            if (NgSendMsg(dev->cs, path, NGM_GENERIC_COOKIE, NGM_LISTHOOKS,
                          NULL, 0) < 0) {
                log_Printf(LogWARN, "%s: %s Cannot send a LISTHOOOKS message: %s\n",
                           p->link.name, path, strerror(errno));
                return ng_Abandon(dev, p);
            }

            /* Get our list back */
            resp = (struct ng_mesg *)rbuf;
            if (NgRecvMsg(dev->cs, resp, sizeof rbuf, NULL) <= 0) {
                log_Printf(LogWARN, "%s: Cannot get netgraph response: %s\n",
                           p->link.name, strerror(errno));
                return ng_Abandon(dev, p);
            }

            hlist = (const struct hooklist *)resp->data;
            ninfo = &hlist->nodeinfo;

            if (*lasthook != '\0' && nodename != NULL && *nodename != '\0' &&
                    strcmp(ninfo->name, nodename) &&
                    NgNameNode(dev->cs, path, "%s", nodename) < 0) {
                log_Printf(LogWARN, "%s: %s: Cannot name netgraph node: %s\n",
                           p->link.name, path, strerror(errno));
                return ng_Abandon(dev, p);
            }

            if (!GETSEGMENT(lasthook, devp, " \t.[", &endp))
                return ng_Abandon(dev, p);
            log_Printf(LogDEBUG, "%s: Got hook \"%s\"\n", p->link.name, lasthook);

            len = strlen(lasthook);
            done = strchr(" \t", devp[len]) ? 1 : 0;
            devp = endp;

            if (*devp != '\0') {
                if (devp[-1] == '[')
                    devp--;
            } /* else should moan about devp[-1] being '[' ? */
        }

        snprintf(dev->hook, sizeof dev->hook, "%s", lasthook);

        /* Connect the node to our socket node */
        snprintf(ngc.path, sizeof ngc.path, "%s", path);
        snprintf(ngc.ourhook, sizeof ngc.ourhook, "%s", dev->hook);
        memcpy(ngc.peerhook, ngc.ourhook, sizeof ngc.peerhook);

        log_Printf(LogDEBUG, "Connecting netgraph socket .:%s -> %s.%s\n",
                   ngc.ourhook, ngc.path, ngc.peerhook);
        if (NgSendMsg(dev->cs, ".:", NGM_GENERIC_COOKIE,
                      NGM_CONNECT, &ngc, sizeof ngc) < 0) {
            log_Printf(LogWARN, "Cannot connect %s and socket netgraph "
                       "nodes: %s\n", path, strerror(errno));
            return ng_Abandon(dev, p);
        }

        /* Hook things up so that we monitor dev->cs */
        p->desc.UpdateSet = ng_UpdateSet;
        p->desc.IsSet = ng_IsSet;
        p->desc.Read = ng_DescriptorRead;

        memcpy(&dev->dev, &basengdevice, sizeof dev->dev);

    } else {
        /* See if we're a netgraph socket */

        sz = sizeof ngsock;
        if (getsockname(p->fd, sock, &sz) != -1 && sock->sa_family == AF_NETGRAPH) {
            /*
             * It's a netgraph node... We can't determine hook names etc, so we
             * stay pretty impartial....
             */
            log_Printf(LogPHASE, "%s: Link is a netgraph node\n", p->link.name);

            if ((dev = malloc(sizeof *dev)) == NULL) {
                log_Printf(LogWARN, "%s: Cannot allocate an ether device: %s\n",
                           p->link.name, strerror(errno));
                return NULL;
            }

            memcpy(&dev->dev, &basengdevice, sizeof dev->dev);
            dev->cs = -1;
            *dev->hook = '\0';
        }
    }

    if (dev) {
        physical_SetupStack(p, dev->dev.name, PHYSICAL_FORCE_SYNCNOACF);
        return &dev->dev;
    }

    return NULL;
}