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