sock.c revision 363769
1/* $FreeBSD: stable/11/contrib/ipfilter/ipsend/sock.c 363769 2020-08-02 04:25:36Z cy $ */ 2/* 3 * sock.c (C) 1995-1998 Darren Reed 4 * 5 * See the IPFILTER.LICENCE file for details on licencing. 6 * 7 */ 8#if !defined(lint) 9static const char sccsid[] = "@(#)sock.c 1.2 1/11/96 (C)1995 Darren Reed"; 10static const char rcsid[] = "@(#)$Id$"; 11#endif 12#include <sys/param.h> 13#include <sys/types.h> 14#include <sys/time.h> 15#include <sys/stat.h> 16#if defined(__NetBSD__) && defined(__vax__) 17/* 18 * XXX need to declare boolean_t for _KERNEL <sys/files.h> 19 * which ends up including <sys/device.h> for vax. See PR#32907 20 * for further details. 21 */ 22typedef int boolean_t; 23#endif 24#include <fcntl.h> 25# include <sys/dirent.h> 26# ifdef __NetBSD__ 27# include <machine/lock.h> 28# endif 29# ifdef __FreeBSD__ 30# define _WANT_FILE 31# else 32# define _KERNEL 33# define KERNEL 34# endif 35# include <sys/file.h> 36# ifdef __FreeBSD__ 37# undef _WANT_FILE 38# else 39# undef _KERNEL 40# undef KERNEL 41# endif 42#include <nlist.h> 43#include <sys/user.h> 44#include <sys/socket.h> 45#include <sys/socketvar.h> 46#include <sys/proc.h> 47# include <kvm.h> 48#ifdef sun 49#include <sys/systm.h> 50#include <sys/session.h> 51#endif 52#include <sys/sysctl.h> 53#include <sys/filedesc.h> 54#include <paths.h> 55#include <math.h> 56#include <netinet/in.h> 57#include <netinet/in_systm.h> 58#include <netinet/ip.h> 59#include <netinet/tcp.h> 60#include <net/if.h> 61# include <net/route.h> 62#include <netinet/ip_var.h> 63#include <netinet/in_pcb.h> 64#include <netinet/tcp_timer.h> 65#include <netinet/tcp_var.h> 66#include <stdio.h> 67#include <unistd.h> 68#include <string.h> 69#include <stdlib.h> 70#include <stddef.h> 71#include <pwd.h> 72#include "ipsend.h" 73 74 75int nproc; 76struct proc *proc; 77 78#ifndef KMEM 79# ifdef _PATH_KMEM 80# define KMEM _PATH_KMEM 81# endif 82#endif 83#ifndef KERNEL 84# ifdef _PATH_UNIX 85# define KERNEL _PATH_UNIX 86# endif 87#endif 88#ifndef KMEM 89# define KMEM "/dev/kmem" 90#endif 91#ifndef KERNEL 92# define KERNEL "/vmunix" 93#endif 94 95 96#if BSD < 199103 97static struct proc *getproc __P((void)); 98#else 99static struct kinfo_proc *getproc __P((void)); 100#endif 101 102 103int kmemcpy(buf, pos, n) 104 char *buf; 105 void *pos; 106 int n; 107{ 108 static int kfd = -1; 109 off_t offset = (u_long)pos; 110 111 if (kfd == -1) 112 kfd = open(KMEM, O_RDONLY); 113 114 if (lseek(kfd, offset, SEEK_SET) == -1) 115 { 116 perror("lseek"); 117 return -1; 118 } 119 if (read(kfd, buf, n) == -1) 120 { 121 perror("read"); 122 return -1; 123 } 124 return n; 125} 126 127struct nlist names[4] = { 128 { "_proc" }, 129 { "_nproc" }, 130 { NULL }, 131 { NULL } 132 }; 133 134static struct kinfo_proc *getproc() 135{ 136 static struct kinfo_proc kp; 137 pid_t pid = getpid(); 138 int mib[4]; 139 size_t n; 140 141 mib[0] = CTL_KERN; 142 mib[1] = KERN_PROC; 143 mib[2] = KERN_PROC_PID; 144 mib[3] = pid; 145 146 n = sizeof(kp); 147 if (sysctl(mib, 4, &kp, &n, NULL, 0) == -1) 148 { 149 perror("sysctl"); 150 return NULL; 151 } 152 return &kp; 153} 154 155 156struct tcpcb *find_tcp(tfd, ti) 157 int tfd; 158 struct tcpiphdr *ti; 159{ 160 struct tcpcb *t; 161 struct inpcb *i; 162 struct socket *s; 163 struct filedesc *fd; 164 struct kinfo_proc *p; 165 struct file *f, **o; 166 167 if (!(p = getproc())) 168 return NULL; 169 170 fd = (struct filedesc *)malloc(sizeof(*fd)); 171 if (fd == NULL) 172 return NULL; 173#if defined( __FreeBSD_version) 174 if (KMCPY(fd, p->ki_fd, sizeof(*fd)) == -1) 175 { 176 fprintf(stderr, "read(%#lx,%#lx) failed\n", 177 (u_long)p, (u_long)p->ki_fd); 178 free(fd); 179 return NULL; 180 } 181#else 182 if (KMCPY(fd, p->kp_proc.p_fd, sizeof(*fd)) == -1) 183 { 184 fprintf(stderr, "read(%#lx,%#lx) failed\n", 185 (u_long)p, (u_long)p->kp_proc.p_fd); 186 free(fd); 187 return NULL; 188 } 189#endif 190 191 o = NULL; 192 f = NULL; 193 s = NULL; 194 i = NULL; 195 t = NULL; 196 197 o = (struct file **)calloc(fd->fd_lastfile + 1, sizeof(*o)); 198 if (KMCPY(o, fd->fd_ofiles, (fd->fd_lastfile + 1) * sizeof(*o)) == -1) 199 { 200 fprintf(stderr, "read(%#lx,%#lx,%lu) - u_ofile - failed\n", 201 (u_long)fd->fd_ofiles, (u_long)o, (u_long)sizeof(*o)); 202 goto finderror; 203 } 204 f = (struct file *)calloc(1, sizeof(*f)); 205 if (KMCPY(f, o[tfd], sizeof(*f)) == -1) 206 { 207 fprintf(stderr, "read(%#lx,%#lx,%lu) - o[tfd] - failed\n", 208 (u_long)o[tfd], (u_long)f, (u_long)sizeof(*f)); 209 goto finderror; 210 } 211 212 s = (struct socket *)calloc(1, sizeof(*s)); 213 if (KMCPY(s, f->f_data, sizeof(*s)) == -1) 214 { 215 fprintf(stderr, "read(%#lx,%#lx,%lu) - f_data - failed\n", 216 (u_long)f->f_data, (u_long)s, (u_long)sizeof(*s)); 217 goto finderror; 218 } 219 220 i = (struct inpcb *)calloc(1, sizeof(*i)); 221 if (KMCPY(i, s->so_pcb, sizeof(*i)) == -1) 222 { 223 fprintf(stderr, "kvm_read(%#lx,%#lx,%lu) - so_pcb - failed\n", 224 (u_long)s->so_pcb, (u_long)i, (u_long)sizeof(*i)); 225 goto finderror; 226 } 227 228 t = (struct tcpcb *)calloc(1, sizeof(*t)); 229 if (KMCPY(t, i->inp_ppcb, sizeof(*t)) == -1) 230 { 231 fprintf(stderr, "read(%#lx,%#lx,%lu) - inp_ppcb - failed\n", 232 (u_long)i->inp_ppcb, (u_long)t, (u_long)sizeof(*t)); 233 goto finderror; 234 } 235 return (struct tcpcb *)i->inp_ppcb; 236 237finderror: 238 if (o != NULL) 239 free(o); 240 if (f != NULL) 241 free(f); 242 if (s != NULL) 243 free(s); 244 if (i != NULL) 245 free(i); 246 if (t != NULL) 247 free(t); 248 return NULL; 249} 250 251int do_socket(dev, mtu, ti, gwip) 252 char *dev; 253 int mtu; 254 struct tcpiphdr *ti; 255 struct in_addr gwip; 256{ 257 struct sockaddr_in rsin, lsin; 258 struct tcpcb *t, tcb; 259 int fd, nfd; 260 socklen_t len; 261 262 printf("Dest. Port: %d\n", ti->ti_dport); 263 264 fd = socket(AF_INET, SOCK_STREAM, 0); 265 if (fd == -1) 266 { 267 perror("socket"); 268 return -1; 269 } 270 271 if (fcntl(fd, F_SETFL, FNDELAY) == -1) 272 { 273 perror("fcntl"); 274 return -1; 275 } 276 277 bzero((char *)&lsin, sizeof(lsin)); 278 lsin.sin_family = AF_INET; 279 bcopy((char *)&ti->ti_src, (char *)&lsin.sin_addr, 280 sizeof(struct in_addr)); 281 if (bind(fd, (struct sockaddr *)&lsin, sizeof(lsin)) == -1) 282 { 283 perror("bind"); 284 return -1; 285 } 286 len = sizeof(lsin); 287 (void) getsockname(fd, (struct sockaddr *)&lsin, &len); 288 ti->ti_sport = lsin.sin_port; 289 printf("sport %d\n", ntohs(lsin.sin_port)); 290 291 nfd = initdevice(dev, 1); 292 if (nfd == -1) 293 return -1; 294 295 if (!(t = find_tcp(fd, ti))) 296 return -1; 297 298 bzero((char *)&rsin, sizeof(rsin)); 299 rsin.sin_family = AF_INET; 300 bcopy((char *)&ti->ti_dst, (char *)&rsin.sin_addr, 301 sizeof(struct in_addr)); 302 rsin.sin_port = ti->ti_dport; 303 if (connect(fd, (struct sockaddr *)&rsin, sizeof(rsin)) == -1 && 304 errno != EINPROGRESS) 305 { 306 perror("connect"); 307 return -1; 308 } 309 KMCPY(&tcb, t, sizeof(tcb)); 310 ti->ti_win = tcb.rcv_adv; 311 ti->ti_seq = tcb.snd_nxt - 1; 312 ti->ti_ack = tcb.rcv_nxt; 313 314 if (send_tcp(nfd, mtu, (ip_t *)ti, gwip) == -1) 315 return -1; 316 (void)write(fd, "Hello World\n", 12); 317 sleep(2); 318 close(fd); 319 return 0; 320} 321