Error while attaching to Vitual Packet Interface (TCPV5.0)

Hello All,

I have read through the Documentation of the VPI and have written a small program which would get the packet and give it back to the TCP/IP stack.

Here is my concern:

First: I am able to attach the proxy to the my process using qnx_proxy_attach(0, 0, 0, -1)

Secondly: If I am doing a vp_attach(sockfd, VP_FILTER, inProxy)

Sockfd: Socket FD
inProxy: this is the return value from the proxy attach function.

The vp_attach gives me a error stating “Resource Temporarily Unavailable

Here is the sample code (Modified IP Filter Code by Darren Reed) for your perusal:

[b]Compiled with the following command:

“cc ipf_main.c -I…/ -lvpack -lsocket -M”[/b]


vpid_t vpid = NULL;
struct flt_pktinfo pinfo;
static pid_t  inProxy = -1;
static pid_t tmrpxy = -1;
static timer_t tmrid = -1;

extern int ipfr_slowtimer __P((void));
extern int (*fr_checkp) __P((ip_t *, int , void *, int, mb_t **));

static int init_vp()
{
        struct ifreq ifr;
        int sockfd;

        if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
                printf("Socket Failed INIT\n");
                syslog(LOG_ERR, "socket(): %m");
                return -1;
        }

        if ((inProxy = qnx_proxy_attach(0, 0, 0, -1)) == -1) {
                printf("Proxy Attach Failed INIT\n");
                syslog(LOG_ERR, "qnx_proxy_attach(): %m");
                return -1;
        }
                printf("Proxy Attach NIT: %d\n", inProxy);

        if ((vpid = vp_attach(sockfd, VP_FILTER, inProxy)) == (vpid_t) -1) {
                printf("VP Attach Failed INIT\n");
                perror("VP ATTACH:");
                syslog(LOG_ERR, "vp_attach(): %m");
                vpid = NULL;
                return -1;
        }

        if (!vp_ifrname(vpid, ifr.ifr_name)) {
                printf("IRNAME Failed INIT\n");
                syslog(LOG_ERR, "vp_ifrname(): %m");
                hangup();
   }

        if (ioctl(sockfd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) {
                printf("IOCTL Failed INIT\n");
                syslog(LOG_ERR, "ioctl(SIOCGIFFLAGS): %m");
                hangup();
        }

        ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
        if (ioctl(sockfd, SIOCSIFFLAGS, (caddr_t) &ifr) < 0) {
                printf("IOCTL2 Failed INIT\n");
                syslog(LOG_ERR, "ioctl(SIOCSIFFLAGS): %m");
                hangup();
        }

        return 0;
}

static void hangup()
{
        if (vpid)
          vp_detach(vpid);

        if (inProxy != -1)
          qnx_proxy_detach(inProxy);

        if (tmrpxy != -1)
          qnx_proxy_detach(tmrpxy);

        if (tmrid != -1)
          timer_delete(tmrid);

        exit(0);
}

int main()
{
        sigset_t sigs;
        pid_t pid;
        int devnull;
        struct mbuf *m;
        struct sigevent event;
        struct itimerspec tm;

        /* first of all, detach from terminal */
        if (1) {
/*              setpgid(0, 0);
                chdir("/");
                if ((devnull = open("/dev/null", O_RDWR, 0)) != -1) {
                        dup2(devnull, 0);
                        dup2(devnull, 1);
                        dup2(devnull, 2);
                        if (devnull > 2)
                          close(devnull);
                }*/
        }

        /* we need a 500ms timer to hit ipfr_slowtimer */
        if ((tmrpxy = qnx_proxy_attach(0, 0, 0, -1)) == -1) {
                printf("Proxy Failed \n");
                syslog(LOG_ERR, "qnx_proxy_attach: %m");
                return;
        }

        event.sigev_signo = -tmrpxy;
/*      if ((tmrid = timer_create(CLOCK_REALTIME, &event)) == -1) {
                syslog(LOG_ERR, "timer_create(): %m");
                return;
        }

        tm.it_value.tv_sec = 0;
        tm.it_value.tv_nsec = 1;
        tm.it_interval.tv_sec = 0;
        tm.it_interval.tv_nsec = 500 * 1000000L;
        timer_settime(tmrid, 0, &tm, NULL);
        if (ipf_res_init() == -1)
          return;
*/
        if (init_vp() == -1) {
                printf("Attach Failed \n");
                return;
        }

        sigfillset(&sigs);
        sigdelset(&sigs, SIGINT);
        sigdelset(&sigs, SIGTERM);
        sigprocmask(SIG_SETMASK, &sigs, 0);
        signal(SIGINT, hangup);
        signal(SIGTERM, hangup);


        for (;;) {
/*
                pid = Receive(0, &iomsg, sizeof(iomsg));
                if (pid == -1 && errno != EINTR) {
                        syslog(LOG_ERR, "Receive: %m");
                        continue;
                }*/

                if (pid == inProxy) {
                        m = vp_getpkt(vpid, &pinfo);

                        if (m) {
                                printf("Got the packet ********\n"); /*
/*                                      struct mbuf *m1 = m;
                                        struct ip *ip = mtod(m1, struct ip *);
                                        int out = pinfo.flag & PACKET_OUTPUT ? 1 : 0;

                                        if ((*fr_checkp)(ip, ip->ip_hl << 2, pinfo.ifname, out, &m1)
                                          continue;
                                        if (!m1)
                                          continue;
                                        m = m1;*/
        signal(SIGTERM, hangup);


        for (;;) {
/*
                pid = Receive(0, &iomsg, sizeof(iomsg));
                if (pid == -1 && errno != EINTR) {
                        syslog(LOG_ERR, "Receive: %m");
                        continue;
                }*/

                if (pid == inProxy) {
                        m = vp_getpkt(vpid, &pinfo);

                        if (m) {
                                printf("Got the packet ********\n"); /*
/*                                      struct mbuf *m1 = m;
                                        struct ip *ip = mtod(m1, struct ip *);
                                        int out = pinfo.flag & PACKET_OUTPUT ? 1 : 0;

                                        if ((*fr_checkp)(ip, ip->ip_hl << 2, pinfo.ifname, out, &m1)
                                          continue;
                                        if (!m1)
                                          continue;
                                        m = m1;*/
                        }
                        vp_putpkt(vpid, m, &pinfo);
                        continue;
                }

                if (pid == tmrpxy) {
                        //ipfr_slowtimer();
                        continue;
                }

        //      ipf_res_intr(pid);
        }
}

If you want to use VPI, you will have to run the Tcpip socket manager with the -v option.