1997-02-09 22:50:16 +00:00
|
|
|
/*
|
2000-02-10 03:17:51 +00:00
|
|
|
* sock.c (C) 1995-1998 Darren Reed
|
1997-02-09 22:50:16 +00:00
|
|
|
*
|
2001-07-28 12:08:15 +00:00
|
|
|
* See the IPFILTER.LICENCE file for details on licencing.
|
2005-04-25 18:20:15 +00:00
|
|
|
*
|
1997-02-09 22:50:16 +00:00
|
|
|
*/
|
2005-04-25 18:20:15 +00:00
|
|
|
#if !defined(lint)
|
|
|
|
static const char sccsid[] = "@(#)sock.c 1.2 1/11/96 (C)1995 Darren Reed";
|
2013-08-11 14:28:45 +00:00
|
|
|
static const char rcsid[] = "@(#)$Id$";
|
2002-03-19 11:48:16 +00:00
|
|
|
#endif
|
2005-04-25 18:20:15 +00:00
|
|
|
#include <sys/param.h>
|
1997-02-09 22:50:16 +00:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <sys/stat.h>
|
2006-08-16 12:23:02 +00:00
|
|
|
#if defined(__NetBSD__) && defined(__vax__)
|
|
|
|
/*
|
|
|
|
* XXX need to declare boolean_t for _KERNEL <sys/files.h>
|
|
|
|
* which ends up including <sys/device.h> for vax. See PR#32907
|
|
|
|
* for further details.
|
|
|
|
*/
|
|
|
|
typedef int boolean_t;
|
|
|
|
#endif
|
1997-02-09 22:50:16 +00:00
|
|
|
#include <fcntl.h>
|
2000-02-10 03:17:51 +00:00
|
|
|
# include <sys/dirent.h>
|
2013-08-11 14:28:45 +00:00
|
|
|
# ifdef __NetBSD__
|
2007-10-18 21:52:14 +00:00
|
|
|
# include <machine/lock.h>
|
|
|
|
# endif
|
2008-07-23 16:34:53 +00:00
|
|
|
# ifdef __FreeBSD__
|
|
|
|
# define _WANT_FILE
|
|
|
|
# else
|
|
|
|
# define _KERNEL
|
|
|
|
# define KERNEL
|
|
|
|
# endif
|
2005-04-25 18:20:15 +00:00
|
|
|
# include <sys/file.h>
|
2008-07-23 16:34:53 +00:00
|
|
|
# ifdef __FreeBSD__
|
|
|
|
# undef _WANT_FILE
|
|
|
|
# else
|
|
|
|
# undef _KERNEL
|
|
|
|
# undef KERNEL
|
|
|
|
# endif
|
1997-02-09 22:50:16 +00:00
|
|
|
#include <nlist.h>
|
|
|
|
#include <sys/user.h>
|
|
|
|
#include <sys/socket.h>
|
2021-11-22 17:58:08 +00:00
|
|
|
#define _WANT_SOCKET
|
1997-02-09 22:50:16 +00:00
|
|
|
#include <sys/socketvar.h>
|
|
|
|
#include <sys/proc.h>
|
1997-11-16 04:52:19 +00:00
|
|
|
# include <kvm.h>
|
1997-02-09 22:50:16 +00:00
|
|
|
#ifdef sun
|
|
|
|
#include <sys/systm.h>
|
|
|
|
#include <sys/session.h>
|
|
|
|
#endif
|
|
|
|
#include <sys/sysctl.h>
|
|
|
|
#include <sys/filedesc.h>
|
|
|
|
#include <paths.h>
|
|
|
|
#include <math.h>
|
|
|
|
#include <netinet/in.h>
|
|
|
|
#include <netinet/in_systm.h>
|
|
|
|
#include <netinet/ip.h>
|
|
|
|
#include <netinet/tcp.h>
|
|
|
|
#include <net/if.h>
|
2007-06-04 02:54:36 +00:00
|
|
|
# include <net/route.h>
|
1997-02-09 22:50:16 +00:00
|
|
|
#include <netinet/ip_var.h>
|
Hide struct inpcb, struct tcpcb from the userland.
This is a painful change, but it is needed. On the one hand, we avoid
modifying them, and this slows down some ideas, on the other hand we still
eventually modify them and tools like netstat(1) never work on next version of
FreeBSD. We maintain a ton of spares in them, and we already got some ifdef
hell at the end of tcpcb.
Details:
- Hide struct inpcb, struct tcpcb under _KERNEL || _WANT_FOO.
- Make struct xinpcb, struct xtcpcb pure API structures, not including
kernel structures inpcb and tcpcb inside. Export into these structures
the fields from inpcb and tcpcb that are known to be used, and put there
a ton of spare space.
- Make kernel and userland utilities compilable after these changes.
- Bump __FreeBSD_version.
Reviewed by: rrs, gnn
Differential Revision: D10018
2017-03-21 06:39:49 +00:00
|
|
|
#define _WANT_INPCB
|
1997-02-09 22:50:16 +00:00
|
|
|
#include <netinet/in_pcb.h>
|
|
|
|
#include <netinet/tcp_timer.h>
|
Hide struct inpcb, struct tcpcb from the userland.
This is a painful change, but it is needed. On the one hand, we avoid
modifying them, and this slows down some ideas, on the other hand we still
eventually modify them and tools like netstat(1) never work on next version of
FreeBSD. We maintain a ton of spares in them, and we already got some ifdef
hell at the end of tcpcb.
Details:
- Hide struct inpcb, struct tcpcb under _KERNEL || _WANT_FOO.
- Make struct xinpcb, struct xtcpcb pure API structures, not including
kernel structures inpcb and tcpcb inside. Export into these structures
the fields from inpcb and tcpcb that are known to be used, and put there
a ton of spare space.
- Make kernel and userland utilities compilable after these changes.
- Bump __FreeBSD_version.
Reviewed by: rrs, gnn
Differential Revision: D10018
2017-03-21 06:39:49 +00:00
|
|
|
#define _WANT_TCPCB
|
1997-02-09 22:50:16 +00:00
|
|
|
#include <netinet/tcp_var.h>
|
2005-04-25 18:20:15 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stddef.h>
|
|
|
|
#include <pwd.h>
|
1997-04-03 10:22:02 +00:00
|
|
|
#include "ipsend.h"
|
1997-02-09 22:50:16 +00:00
|
|
|
|
2001-07-28 12:08:15 +00:00
|
|
|
|
1997-02-09 22:50:16 +00:00
|
|
|
int nproc;
|
|
|
|
struct proc *proc;
|
|
|
|
|
|
|
|
#ifndef KMEM
|
|
|
|
# ifdef _PATH_KMEM
|
|
|
|
# define KMEM _PATH_KMEM
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
#ifndef KERNEL
|
|
|
|
# ifdef _PATH_UNIX
|
|
|
|
# define KERNEL _PATH_UNIX
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
#ifndef KMEM
|
|
|
|
# define KMEM "/dev/kmem"
|
|
|
|
#endif
|
|
|
|
#ifndef KERNEL
|
|
|
|
# define KERNEL "/vmunix"
|
|
|
|
#endif
|
|
|
|
|
1997-04-03 10:22:02 +00:00
|
|
|
|
2021-01-26 06:24:28 +00:00
|
|
|
static struct kinfo_proc *getproc(void);
|
1997-04-03 10:22:02 +00:00
|
|
|
|
|
|
|
|
2021-12-20 17:07:20 +00:00
|
|
|
int
|
|
|
|
kmemcpy(char *buf, void *pos, int n)
|
1997-02-09 22:50:16 +00:00
|
|
|
{
|
|
|
|
static int kfd = -1;
|
1997-11-16 04:52:19 +00:00
|
|
|
off_t offset = (u_long)pos;
|
1997-02-09 22:50:16 +00:00
|
|
|
|
|
|
|
if (kfd == -1)
|
|
|
|
kfd = open(KMEM, O_RDONLY);
|
|
|
|
|
1997-11-16 04:52:19 +00:00
|
|
|
if (lseek(kfd, offset, SEEK_SET) == -1)
|
1997-02-09 22:50:16 +00:00
|
|
|
{
|
|
|
|
perror("lseek");
|
2022-01-04 02:49:18 +00:00
|
|
|
return (-1);
|
1997-02-09 22:50:16 +00:00
|
|
|
}
|
|
|
|
if (read(kfd, buf, n) == -1)
|
|
|
|
{
|
|
|
|
perror("read");
|
2022-01-04 02:49:18 +00:00
|
|
|
return (-1);
|
1997-02-09 22:50:16 +00:00
|
|
|
}
|
2022-01-04 02:49:18 +00:00
|
|
|
return (n);
|
1997-02-09 22:50:16 +00:00
|
|
|
}
|
|
|
|
|
1997-11-16 04:52:19 +00:00
|
|
|
struct nlist names[4] = {
|
1997-02-09 22:50:16 +00:00
|
|
|
{ "_proc" },
|
|
|
|
{ "_nproc" },
|
1997-11-16 04:52:19 +00:00
|
|
|
{ NULL },
|
1997-02-09 22:50:16 +00:00
|
|
|
{ NULL }
|
|
|
|
};
|
|
|
|
|
2021-12-20 17:07:20 +00:00
|
|
|
static struct
|
|
|
|
kinfo_proc *getproc(void)
|
1997-02-09 22:50:16 +00:00
|
|
|
{
|
|
|
|
static struct kinfo_proc kp;
|
|
|
|
pid_t pid = getpid();
|
1997-11-16 04:52:19 +00:00
|
|
|
int mib[4];
|
|
|
|
size_t n;
|
1997-02-09 22:50:16 +00:00
|
|
|
|
|
|
|
mib[0] = CTL_KERN;
|
|
|
|
mib[1] = KERN_PROC;
|
|
|
|
mib[2] = KERN_PROC_PID;
|
|
|
|
mib[3] = pid;
|
|
|
|
|
1998-03-21 10:04:55 +00:00
|
|
|
n = sizeof(kp);
|
1997-02-09 22:50:16 +00:00
|
|
|
if (sysctl(mib, 4, &kp, &n, NULL, 0) == -1)
|
|
|
|
{
|
|
|
|
perror("sysctl");
|
2022-01-04 02:49:18 +00:00
|
|
|
return (NULL);
|
1997-02-09 22:50:16 +00:00
|
|
|
}
|
2022-01-04 02:49:18 +00:00
|
|
|
return (&kp);
|
1997-02-09 22:50:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-12-20 17:07:20 +00:00
|
|
|
struct tcpcb *
|
|
|
|
find_tcp(int tfd, struct tcpiphdr *ti)
|
1997-02-09 22:50:16 +00:00
|
|
|
{
|
|
|
|
struct tcpcb *t;
|
|
|
|
struct inpcb *i;
|
|
|
|
struct socket *s;
|
|
|
|
struct filedesc *fd;
|
|
|
|
struct kinfo_proc *p;
|
|
|
|
struct file *f, **o;
|
|
|
|
|
|
|
|
if (!(p = getproc()))
|
2022-01-04 02:49:18 +00:00
|
|
|
return (NULL);
|
1997-02-09 22:50:16 +00:00
|
|
|
|
|
|
|
fd = (struct filedesc *)malloc(sizeof(*fd));
|
2007-06-04 02:54:36 +00:00
|
|
|
if (fd == NULL)
|
2022-01-04 02:49:18 +00:00
|
|
|
return (NULL);
|
2021-02-07 03:22:52 +00:00
|
|
|
#if defined( __FreeBSD__)
|
2000-12-14 23:35:57 +00:00
|
|
|
if (KMCPY(fd, p->ki_fd, sizeof(*fd)) == -1)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "read(%#lx,%#lx) failed\n",
|
|
|
|
(u_long)p, (u_long)p->ki_fd);
|
2007-06-04 02:54:36 +00:00
|
|
|
free(fd);
|
2022-01-04 02:49:18 +00:00
|
|
|
return (NULL);
|
2000-12-14 23:35:57 +00:00
|
|
|
}
|
|
|
|
#else
|
1997-04-03 10:22:02 +00:00
|
|
|
if (KMCPY(fd, p->kp_proc.p_fd, sizeof(*fd)) == -1)
|
1997-02-09 22:50:16 +00:00
|
|
|
{
|
|
|
|
fprintf(stderr, "read(%#lx,%#lx) failed\n",
|
|
|
|
(u_long)p, (u_long)p->kp_proc.p_fd);
|
2007-06-04 02:54:36 +00:00
|
|
|
free(fd);
|
2022-01-04 02:49:18 +00:00
|
|
|
return (NULL);
|
1997-02-09 22:50:16 +00:00
|
|
|
}
|
2000-12-14 23:35:57 +00:00
|
|
|
#endif
|
1997-02-09 22:50:16 +00:00
|
|
|
|
2006-08-16 12:23:02 +00:00
|
|
|
o = NULL;
|
|
|
|
f = NULL;
|
|
|
|
s = NULL;
|
|
|
|
i = NULL;
|
|
|
|
t = NULL;
|
|
|
|
|
2017-03-16 04:40:07 +00:00
|
|
|
o = (struct file **)calloc(fd->fd_lastfile + 1, sizeof(*o));
|
1997-04-03 10:22:02 +00:00
|
|
|
if (KMCPY(o, fd->fd_ofiles, (fd->fd_lastfile + 1) * sizeof(*o)) == -1)
|
1997-02-09 22:50:16 +00:00
|
|
|
{
|
1997-11-16 04:52:19 +00:00
|
|
|
fprintf(stderr, "read(%#lx,%#lx,%lu) - u_ofile - failed\n",
|
|
|
|
(u_long)fd->fd_ofiles, (u_long)o, (u_long)sizeof(*o));
|
2006-08-16 12:23:02 +00:00
|
|
|
goto finderror;
|
1997-02-09 22:50:16 +00:00
|
|
|
}
|
|
|
|
f = (struct file *)calloc(1, sizeof(*f));
|
1997-04-03 10:22:02 +00:00
|
|
|
if (KMCPY(f, o[tfd], sizeof(*f)) == -1)
|
1997-02-09 22:50:16 +00:00
|
|
|
{
|
1997-11-16 04:52:19 +00:00
|
|
|
fprintf(stderr, "read(%#lx,%#lx,%lu) - o[tfd] - failed\n",
|
|
|
|
(u_long)o[tfd], (u_long)f, (u_long)sizeof(*f));
|
2006-08-16 12:23:02 +00:00
|
|
|
goto finderror;
|
1997-02-09 22:50:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
s = (struct socket *)calloc(1, sizeof(*s));
|
2003-01-13 00:33:17 +00:00
|
|
|
if (KMCPY(s, f->f_data, sizeof(*s)) == -1)
|
1997-02-09 22:50:16 +00:00
|
|
|
{
|
1997-11-16 04:52:19 +00:00
|
|
|
fprintf(stderr, "read(%#lx,%#lx,%lu) - f_data - failed\n",
|
2006-08-16 12:23:02 +00:00
|
|
|
(u_long)f->f_data, (u_long)s, (u_long)sizeof(*s));
|
|
|
|
goto finderror;
|
1997-02-09 22:50:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
i = (struct inpcb *)calloc(1, sizeof(*i));
|
1997-04-03 10:22:02 +00:00
|
|
|
if (KMCPY(i, s->so_pcb, sizeof(*i)) == -1)
|
1997-02-09 22:50:16 +00:00
|
|
|
{
|
1997-11-16 04:52:19 +00:00
|
|
|
fprintf(stderr, "kvm_read(%#lx,%#lx,%lu) - so_pcb - failed\n",
|
|
|
|
(u_long)s->so_pcb, (u_long)i, (u_long)sizeof(*i));
|
2006-08-16 12:23:02 +00:00
|
|
|
goto finderror;
|
1997-02-09 22:50:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
t = (struct tcpcb *)calloc(1, sizeof(*t));
|
1997-04-03 10:22:02 +00:00
|
|
|
if (KMCPY(t, i->inp_ppcb, sizeof(*t)) == -1)
|
1997-02-09 22:50:16 +00:00
|
|
|
{
|
1997-11-16 04:52:19 +00:00
|
|
|
fprintf(stderr, "read(%#lx,%#lx,%lu) - inp_ppcb - failed\n",
|
|
|
|
(u_long)i->inp_ppcb, (u_long)t, (u_long)sizeof(*t));
|
2006-08-16 12:23:02 +00:00
|
|
|
goto finderror;
|
1997-02-09 22:50:16 +00:00
|
|
|
}
|
2022-01-04 02:49:18 +00:00
|
|
|
return (struct tcpcb *)i->inp_ppcb;
|
2006-08-16 12:23:02 +00:00
|
|
|
|
|
|
|
finderror:
|
|
|
|
if (o != NULL)
|
|
|
|
free(o);
|
|
|
|
if (f != NULL)
|
|
|
|
free(f);
|
|
|
|
if (s != NULL)
|
|
|
|
free(s);
|
|
|
|
if (i != NULL)
|
|
|
|
free(i);
|
|
|
|
if (t != NULL)
|
|
|
|
free(t);
|
2022-01-04 02:49:18 +00:00
|
|
|
return (NULL);
|
1997-02-09 22:50:16 +00:00
|
|
|
}
|
|
|
|
|
2021-12-20 17:07:20 +00:00
|
|
|
int
|
|
|
|
do_socket(char *dev, int mtu, struct tcpiphdr *ti, struct in_addr gwip)
|
1997-02-09 22:50:16 +00:00
|
|
|
{
|
|
|
|
struct sockaddr_in rsin, lsin;
|
|
|
|
struct tcpcb *t, tcb;
|
2007-10-18 21:52:14 +00:00
|
|
|
int fd, nfd;
|
|
|
|
socklen_t len;
|
1997-02-09 22:50:16 +00:00
|
|
|
|
|
|
|
printf("Dest. Port: %d\n", ti->ti_dport);
|
|
|
|
|
|
|
|
fd = socket(AF_INET, SOCK_STREAM, 0);
|
|
|
|
if (fd == -1)
|
|
|
|
{
|
|
|
|
perror("socket");
|
2022-01-04 02:49:18 +00:00
|
|
|
return (-1);
|
1997-02-09 22:50:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (fcntl(fd, F_SETFL, FNDELAY) == -1)
|
|
|
|
{
|
|
|
|
perror("fcntl");
|
2022-01-04 02:49:18 +00:00
|
|
|
return (-1);
|
1997-02-09 22:50:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bzero((char *)&lsin, sizeof(lsin));
|
|
|
|
lsin.sin_family = AF_INET;
|
|
|
|
bcopy((char *)&ti->ti_src, (char *)&lsin.sin_addr,
|
|
|
|
sizeof(struct in_addr));
|
|
|
|
if (bind(fd, (struct sockaddr *)&lsin, sizeof(lsin)) == -1)
|
|
|
|
{
|
|
|
|
perror("bind");
|
2022-01-04 02:49:18 +00:00
|
|
|
return (-1);
|
1997-02-09 22:50:16 +00:00
|
|
|
}
|
|
|
|
len = sizeof(lsin);
|
|
|
|
(void) getsockname(fd, (struct sockaddr *)&lsin, &len);
|
|
|
|
ti->ti_sport = lsin.sin_port;
|
|
|
|
printf("sport %d\n", ntohs(lsin.sin_port));
|
2006-08-16 12:23:02 +00:00
|
|
|
|
2005-04-25 18:20:15 +00:00
|
|
|
nfd = initdevice(dev, 1);
|
2006-08-16 12:23:02 +00:00
|
|
|
if (nfd == -1)
|
2022-01-04 02:49:18 +00:00
|
|
|
return (-1);
|
1997-02-09 22:50:16 +00:00
|
|
|
|
|
|
|
if (!(t = find_tcp(fd, ti)))
|
2022-01-04 02:49:18 +00:00
|
|
|
return (-1);
|
1997-02-09 22:50:16 +00:00
|
|
|
|
|
|
|
bzero((char *)&rsin, sizeof(rsin));
|
|
|
|
rsin.sin_family = AF_INET;
|
|
|
|
bcopy((char *)&ti->ti_dst, (char *)&rsin.sin_addr,
|
|
|
|
sizeof(struct in_addr));
|
|
|
|
rsin.sin_port = ti->ti_dport;
|
|
|
|
if (connect(fd, (struct sockaddr *)&rsin, sizeof(rsin)) == -1 &&
|
|
|
|
errno != EINPROGRESS)
|
|
|
|
{
|
|
|
|
perror("connect");
|
2022-01-04 02:49:18 +00:00
|
|
|
return (-1);
|
1997-02-09 22:50:16 +00:00
|
|
|
}
|
1997-04-03 10:22:02 +00:00
|
|
|
KMCPY(&tcb, t, sizeof(tcb));
|
1997-02-09 22:50:16 +00:00
|
|
|
ti->ti_win = tcb.rcv_adv;
|
|
|
|
ti->ti_seq = tcb.snd_nxt - 1;
|
|
|
|
ti->ti_ack = tcb.rcv_nxt;
|
|
|
|
|
1997-04-03 10:22:02 +00:00
|
|
|
if (send_tcp(nfd, mtu, (ip_t *)ti, gwip) == -1)
|
2022-01-04 02:49:18 +00:00
|
|
|
return (-1);
|
1997-02-09 22:50:16 +00:00
|
|
|
(void)write(fd, "Hello World\n", 12);
|
|
|
|
sleep(2);
|
|
|
|
close(fd);
|
2022-01-04 02:49:18 +00:00
|
|
|
return (0);
|
1997-02-09 22:50:16 +00:00
|
|
|
}
|